125 lines
5.8 KiB
Clojure
125 lines
5.8 KiB
Clojure
(ns mw-parser.generate-test
|
|
(:require [clojure.pprint :as pprint]
|
|
[clojure.test :refer [deftest is testing]]
|
|
[mw-engine.core :refer [apply-rule]]
|
|
[mw-engine.utils :refer [get-cell]]
|
|
[mw-parser.declarative :refer [compile parse]]
|
|
[mw-parser.generate :refer [generate]]
|
|
[mw-parser.simplify :refer [simplify]]))
|
|
|
|
(deftest expressions-tests
|
|
(testing "Generating primitive expressions."
|
|
(let [actual (generate '(:NUMERIC-EXPRESSION (:NUMBER "50")))
|
|
expected 50]
|
|
(is (= actual expected)))
|
|
(let [actual (generate '(:NUMERIC-EXPRESSION (:SYMBOL "sealevel")))
|
|
expected '(:sealevel cell)]
|
|
(is (= actual expected)))))
|
|
|
|
(deftest lhs-generators-tests
|
|
(testing "Generating left-hand-side fragments of rule functions from appropriate fragments of parse trees"
|
|
(let [expected '(= (:state cell) (or (:forest cell) :forest))
|
|
actual (generate
|
|
'(:PROPERTY-CONDITION
|
|
(:SYMBOL "state")
|
|
[:EQUIVALENCE [:IS "is"]]
|
|
(:SYMBOL "forest")))]
|
|
(is (= actual expected)))
|
|
(is (= (generate
|
|
'(:PROPERTY-CONDITION (:SYMBOL "fertility") [:EQUIVALENCE [:IS "is"]] (:NUMBER "10")))
|
|
'(= (:fertility cell) 10)))
|
|
(is (= (generate '(:PROPERTY-CONDITION (:SYMBOL "fertility") [:COMPARATIVE [:LESS "less"]] (:NUMBER "10")))
|
|
'(< (:fertility cell) 10)))
|
|
(is (= (generate '(:PROPERTY-CONDITION (:SYMBOL "fertility") [:COMPARATIVE [:MORE "more"]] (:NUMBER "10")))
|
|
'(> (:fertility cell) 10)))
|
|
(is (= (generate '(:CONJUNCT-CONDITION
|
|
(:PROPERTY-CONDITION
|
|
(:SYMBOL "state")
|
|
(:QUALIFIER (:EQUIVALENCE (:IS "is")))
|
|
(:SYMBOL "forest"))
|
|
(:PROPERTY-CONDITION
|
|
(:SYMBOL "fertility")
|
|
(:QUALIFIER (:EQUIVALENCE (:IS "is")))
|
|
(:NUMBER "10"))))
|
|
'(and (= (:state cell) (or (:forest cell) :forest)) (= (:fertility cell) 10))))
|
|
(is (= (generate '(:DISJUNCT-CONDITION (:PROPERTY-CONDITION (:SYMBOL "state") (:EQUIVALENCE (:IS "is")) (:SYMBOL "forest")) (:PROPERTY-CONDITION (:SYMBOL "fertility") (:EQUIVALENCE (:IS "is")) (:NUMBER "10"))))
|
|
'(or (= (:state cell) (or (:forest cell) :forest)) (= (:fertility cell) 10))))
|
|
(is (= (generate '(:PROPERTY-CONDITION
|
|
(:SYMBOL "state")
|
|
(:QUALIFIER (:EQUIVALENCE (:IS "is")))
|
|
(:DISJUNCT-EXPRESSION
|
|
(:SYMBOL "heath")
|
|
(:SYMBOL "scrub")
|
|
(:SYMBOL "forest"))))
|
|
'(#{:scrub :forest :heath} (:state cell))))
|
|
(is (= (generate '(:PROPERTY-CONDITION (:SYMBOL "altitude") [:EQUIVALENCE [:IS "is"]] (:RANGE-EXPRESSION (:BETWEEN "between") (:NUMERIC-EXPRESSION (:NUMBER "50")) (:AND "and") (:NUMERIC-EXPRESSION (:NUMBER "100")))))
|
|
'(let [lower (min 50 100) upper (max 50 100)] (and (>= (:altitude cell) lower) (<= (:altitude cell) upper)))))))
|
|
|
|
(deftest rhs-generators-tests
|
|
(testing "Generating right-hand-side fragments of rule functions from appropriate fragments of parse trees"
|
|
(is (= (generate
|
|
'(:SIMPLE-ACTION (:SYMBOL "state") (:BECOMES "should be") (:SYMBOL "climax")))
|
|
'(merge cell {:state :climax})))
|
|
(is (= (generate
|
|
'(:SIMPLE-ACTION (:SYMBOL "fertility") (:BECOMES "should be") (:NUMBER "10")))
|
|
'(merge cell {:fertility 10})))))
|
|
|
|
(deftest full-generation-tests
|
|
(testing "Full rule generation from pre-parsed tree"
|
|
(let [rule '(:RULE
|
|
(:IF "if")
|
|
(:PROPERTY-CONDITION
|
|
(:SYMBOL "state")
|
|
(:QUALIFIER (:EQUIVALENCE (:IS "is")))
|
|
(:SYMBOL "forest"))
|
|
(:ACTIONS
|
|
(:SIMPLE-ACTION
|
|
(:SYMBOL "state")
|
|
(:BECOMES "should be")
|
|
(:SYMBOL "climax"))))
|
|
expected '(fn [cell world]
|
|
(when
|
|
(= (:state cell) (or (:forest cell) :forest))
|
|
(merge cell {:state :climax})))
|
|
actual (generate rule)
|
|
expected-meta {:rule-type :production}
|
|
actual-meta (meta actual)]
|
|
(is (= actual expected))
|
|
(is (= actual-meta expected-meta)))))
|
|
|
|
(deftest metadata-tests
|
|
(testing "Rules have correct metadata"
|
|
(let [expected :production
|
|
actual (:rule-type
|
|
(meta
|
|
(generate
|
|
(simplify
|
|
(parse "if state is house then state should be waste")))))]
|
|
(is (= actual expected)))
|
|
(let [expected :flow
|
|
actual (:rule-type
|
|
(meta
|
|
(generate
|
|
(simplify
|
|
(parse "flow 10% food from house to house within 2 with least food")))))]
|
|
(is (= actual expected)))))
|
|
|
|
(deftest chance-bug-test
|
|
(testing "exception thrown when evaluating``"
|
|
(let [cell {:y 1, :generation 10,
|
|
:state :scrub, :gradient 85,
|
|
:x 1, :altitude 92}
|
|
world [[{:y 0, :state :new, :x 0} {:y 0, :state :new, :x 1} {:y 0, :state :new, :x 2}]
|
|
[{:y 1, :state :new, :x 0} cell {:y 1, :state :new, :x 2}]
|
|
[{:y 2, :state :new, :x 0} {:y 2, :state :new, :x 1} {:y 2, :state :new, :x 2}]]
|
|
rule (compile "if state is scrub then 1 chance in 5 state should be forest")
|
|
expected #{:scrub :forest}
|
|
cell' (reduce
|
|
(fn [c i] (merge (or (apply-rule world c rule) c) {:i i}))
|
|
cell
|
|
(range 20))
|
|
actual (:state cell')]
|
|
(pprint/pprint cell')
|
|
(is (expected actual)))))
|
|
|