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
151 lines
5.0 KiB
Common Lisp
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))
|