Files
organicCafe/test/tests.lisp
hpcdisrespecter bc14c93a3c Initial commit, ACM PEARC25 and PEARC26 chosen restaurants work.
Committer: hpcdisrespecter <noreply@git.asperger.pro>

	modified:   .gitignore
	modified:   README.md
	new file:   menus/peoples-organic.sexp
	new file:   menus/townhall-shortnorth.sexp
	new file:   organic-cafe.asd
	new file:   run.lisp
	new file:   src/package.lisp
	new file:   src/planner.lisp
	new file:   test/tests.lisp
2026-07-23 02:58:10 -05:00

151 lines
5.0 KiB
Common Lisp

(defpackage #:organic-cafe/tests
(:use #:cl)
(:export #:run-tests))
(in-package #:organic-cafe/tests)
(defun menu-path (filename)
(asdf:system-relative-pathname
"organic-cafe"
(format nil "menus/~A" filename)))
(defmacro check (form)
`(unless ,form
(error "Check failed: ~S" ',form)))
(defun selections (candidate meal label)
(remove-if-not
(lambda (selection)
(and (eql meal (organic-cafe::selection-meal selection))
(eql label (organic-cafe::selection-label selection))))
(organic-cafe::candidate-selections candidate)))
(defun check-within-budget (plans budget-cents)
(check
(every (lambda (candidate)
(<= (organic-cafe::candidate-total candidate) budget-cents))
plans)))
(defun test-peoples-organic ()
(let* ((menu
(organic-cafe:load-menu
(menu-path "peoples-organic.sexp")))
(candidates
;; test a smaller budget to check filter
(organic-cafe:feasible-candidates menu :full-day 85))
(plans
(organic-cafe:generate-plans
menu :full-day 85 3
:state (sb-ext:seed-random-state 1337))))
(check (= 107168 (length candidates)))
(check-within-budget candidates 8500)
(check (= 3 (length plans)))
(check-within-budget plans 8500)
(length candidates)))
(defun test-townhall ()
(let* ((menu
(organic-cafe:load-menu
(menu-path "townhall-shortnorth.sexp")))
(plans
(organic-cafe:generate-plans
menu :full-day 70 3
:state (sb-ext:seed-random-state 67)))
(lazy-plan
(first
(organic-cafe:generate-plans
menu :lazy-day 30 1
:state (sb-ext:seed-random-state 69))))
(branch-samples
(organic-cafe:generate-plans
menu :full-day 100 20
:state (sb-ext:seed-random-state 69)
:diversity-pool-size 1)))
(check (= 3 (length plans)))
(check-within-budget plans 7000)
(dolist (candidate plans)
(check (= 2 (length (selections candidate :lunch :side))))
(check (= 2 (length (selections candidate :lunch :garnish))))
(check
(= 2
(length
(remove-duplicates
(mapcar (lambda (selection)
(organic-cafe::item-name
(organic-cafe::selection-item selection)))
(selections candidate :lunch :side))
:test #'string=))))
(let ((shared (selections candidate :dinner :shared-plate))
(bowl (selections candidate :dinner :protein)))
(check (not (and shared bowl)))
(check (or shared bowl))
(check shared)))
(check (<= (organic-cafe::candidate-total lazy-plan) 3000))
(check (= 4 (length
(organic-cafe::candidate-selections lazy-plan))))
(dolist (candidate branch-samples)
(let ((shared (selections candidate :dinner :shared-plate))
(bowl (selections candidate :dinner :protein)))
(check (not (and shared bowl)))
(check (or shared bowl))
(when bowl
(check (= 2 (length (selections candidate :dinner :side))))
(check (= 2 (length
(selections candidate :dinner :garnish)))))))
;; At a roomy budget, both weighted dinner branches are reachable.
(check
(some (lambda (candidate)
(selections candidate :dinner :shared-plate))
branch-samples))
(check
(some (lambda (candidate)
(selections candidate :dinner :protein))
branch-samples))
t))
(defun test-cli-lazy-day-budget ()
(let* ((peoples-menu (menu-path "peoples-organic.sexp"))
(output
(with-output-to-string (stream)
(let ((*standard-output* stream))
(organic-cafe:run-cli
(list "--days" "1"
"--add-lazy-day" "30"
"--seed" "1337")
:default-menu peoples-menu)))))
(check (search "Day 1" output))
(check (search "Lazy Day (outbound)" output))
(check (not (search "Lazy Day 2" output)))
(check
(handler-case
(let ((*standard-output* (make-broadcast-stream)))
(organic-cafe:run-cli
(list "--days" "1"
"--add-lazy-day" "1"
"--seed" "1337")
:default-menu peoples-menu)
nil)
(error (condition)
(search "LAZY-DAY" (string-upcase
(princ-to-string condition))))))
(check
(handler-case
(progn
(organic-cafe:run-cli
(list "--plan" "lazy-day")
:default-menu peoples-menu)
nil)
(error (condition)
(search "--add-lazy-day"
(princ-to-string condition)))))
t))
(defun run-tests ()
(let ((peoples-count (test-peoples-organic)))
(test-townhall)
(test-cli-lazy-day-budget)
(format t
"~&All organic-cafe tests passed (~:D enumerated People's days; TownHall DP sampling covered).~%"
peoples-count)
t))