Version casi lista
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
}
|
||||
@@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user