Version casi lista

This commit is contained in:
alexandrev-tibco
2026-02-17 13:34:02 +01:00
commit e593453abd
99 changed files with 10867 additions and 0 deletions
@@ -0,0 +1,63 @@
import XCTest
@testable import MealMood
final class AutocompleteEngineTests: XCTestCase {
func testValidateDropRejectsConsecutiveTag() {
let tag = Tag(
name: "Carne",
nameEN: "Meat",
color: "#E74C3C",
maxPerWeek: nil,
noConsecutive: true,
noDuplicateInDay: false
)
let dishA = Dish(name: "Pollo", tagIds: [tag.id])
let dishB = Dish(name: "Ternera", tagIds: [tag.id])
let plan = WeekPlan(weekStartDate: Date().startOfWeek())
let mondayDinner = MealSlot(dayOfWeek: 0, mealType: MealType.dinner.rawValue, dishId: dishA.id)
let tuesdayDinner = MealSlot(dayOfWeek: 1, mealType: MealType.dinner.rawValue, dishId: nil)
plan.slots = [mondayDinner, tuesdayDinner]
let isValid = AutocompleteEngine.validateDrop(
dish: dishB,
slot: tuesdayDinner,
plan: plan,
allTags: [tag],
allDishes: [dishA, dishB]
)
XCTAssertFalse(isValid)
}
func testAutocompleteLeavesSlotEmptyWhenMaxPerWeekReached() {
let tag = Tag(
name: "Pescado",
nameEN: "Fish",
color: "#3498DB",
maxPerWeek: 1,
noConsecutive: false,
noDuplicateInDay: false
)
let fishDish = Dish(name: "Salmon", tagIds: [tag.id])
let plan = WeekPlan(weekStartDate: Date().startOfWeek())
let mondayDinner = MealSlot(dayOfWeek: 0, mealType: MealType.dinner.rawValue, dishId: fishDish.id)
let tuesdayDinner = MealSlot(dayOfWeek: 1, mealType: MealType.dinner.rawValue, dishId: nil)
plan.slots = [mondayDinner, tuesdayDinner]
let result = AutocompleteEngine.autocomplete(
emptySlots: [tuesdayDinner],
currentPlan: plan,
allDishes: [fishDish],
allTags: [tag]
)
XCTAssertEqual(result.unfilledCount, 1)
XCTAssertNil(tuesdayDinner.dishId)
}
}
+36
View File
@@ -0,0 +1,36 @@
import XCTest
@testable import MealMood
final class DateHelpersTests: XCTestCase {
func testStartOfWeekReturnsMonday() {
var components = DateComponents()
components.year = 2026
components.month = 2
components.day = 18 // Wednesday
let calendar = Calendar(identifier: .gregorian)
let input = calendar.date(from: components)!
let start = input.startOfWeek()
let weekday = calendar.component(.weekday, from: start)
XCTAssertEqual(weekday, 2) // Monday in Gregorian calendar
}
func testCombineDateAndTime() {
let calendar = Calendar(identifier: .gregorian)
let date = calendar.date(from: DateComponents(year: 2026, month: 2, day: 20))!
let time = calendar.date(from: DateComponents(hour: 21, minute: 30))!
let combined = combineDateAndTime(date: date, time: time)
let parts = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: combined)
XCTAssertEqual(parts.year, 2026)
XCTAssertEqual(parts.month, 2)
XCTAssertEqual(parts.day, 20)
XCTAssertEqual(parts.hour, 21)
XCTAssertEqual(parts.minute, 30)
}
}
@@ -0,0 +1,44 @@
import XCTest
@testable import MealMood
@MainActor
final class OnboardingViewModelTests: XCTestCase {
func testAddDishAllowsNameOnlyAndUsesDefaultTag() {
let vm = OnboardingViewModel()
vm.newDishName = "Test dish"
let fallbackId = UUID()
vm.addDish(defaultTagId: fallbackId)
XCTAssertEqual(vm.addedDishes.count, 1)
XCTAssertEqual(vm.addedDishes.first?.name, "Test dish")
XCTAssertEqual(vm.addedDishes.first?.tagIds, [fallbackId])
}
func testAddDishPreventsDuplicateNames() {
let vm = OnboardingViewModel()
vm.newDishName = "Lentils"
vm.addDish(defaultTagId: UUID())
vm.newDishName = " lentils "
vm.addDish(defaultTagId: UUID())
XCTAssertEqual(vm.addedDishes.count, 1)
}
func testSuggestedDishFallsBackToFirstTagWhenNoNameMatch() {
let vm = OnboardingViewModel()
let fallback = Tag(name: "Carne", nameEN: "Meat", color: "#E74C3C", sortOrder: 0)
let other = Tag(name: "Pescado", nameEN: "Fish", color: "#3498DB", sortOrder: 1)
vm.addSuggestedDish(
name: "Roast chicken",
preferredTagNames: ["Unknown tag"],
availableTags: [other, fallback]
)
XCTAssertEqual(vm.addedDishes.count, 1)
XCTAssertEqual(vm.addedDishes.first?.tagIds, [fallback.id])
}
}
+37
View File
@@ -0,0 +1,37 @@
import XCTest
@testable import MealMood
final class TagLocalizationTests: XCTestCase {
func testLocalizedNameUsesEnglishWhenAvailable() {
let tag = Tag(
name: "Carne",
nameEN: "Meat",
color: "#E74C3C"
)
XCTAssertEqual(tag.localizedName(language: .spanish), "Carne")
XCTAssertEqual(tag.localizedName(language: .english), "Meat")
}
func testLocalizedRulesDescriptionChangesByLanguage() {
let tag = Tag(
name: "Carne",
nameEN: "Meat",
color: "#E74C3C",
maxPerWeek: 3,
noConsecutive: true,
noDuplicateInDay: true,
mealTypeRestriction: "dinner"
)
let es = tag.localizedRulesDescription(language: .spanish)
let en = tag.localizedRulesDescription(language: .english)
XCTAssertTrue(es.contains("Max 3/semana"))
XCTAssertTrue(es.contains("solo cena"))
XCTAssertTrue(en.contains("Max 3/week"))
XCTAssertTrue(en.contains("dinner only"))
}
}