diff options
author | Eduardo Julian | 2022-09-03 14:31:47 -0400 |
---|---|---|
committer | Eduardo Julian | 2022-09-03 14:31:47 -0400 |
commit | 1f4557bf0d904231b3b8d2b2bf73c35e9caead48 (patch) | |
tree | 30e49d4ed6cc75b3185ed9a771d2dbb004fca00f /stdlib/source/test | |
parent | 950836e72a1b775ccab19a722566c431f56208f6 (diff) |
Added support for context-oriented programming.
Diffstat (limited to '')
-rw-r--r-- | stdlib/source/test/lux.lux | 6 | ||||
-rw-r--r-- | stdlib/source/test/lux/control/function.lux | 4 | ||||
-rw-r--r-- | stdlib/source/test/lux/control/function/polymorphism/context.lux | 117 | ||||
-rw-r--r-- | stdlib/source/test/lux/program.lux | 2 | ||||
-rw-r--r-- | stdlib/source/test/lux/test.lux | 2 | ||||
-rw-r--r-- | stdlib/source/test/lux/test/property.lux | 58 | ||||
-rw-r--r-- | stdlib/source/test/lux/test/unit.lux | 126 | ||||
-rw-r--r-- | stdlib/source/test/lux/world/time/day.lux | 91 | ||||
-rw-r--r-- | stdlib/source/test/lux/world/time/month.lux | 136 |
9 files changed, 392 insertions, 150 deletions
diff --git a/stdlib/source/test/lux.lux b/stdlib/source/test/lux.lux index e4dbc056b..67a23e73b 100644 --- a/stdlib/source/test/lux.lux +++ b/stdlib/source/test/lux.lux @@ -77,12 +77,14 @@ expected dummy))) (_.coverage [/.or] - (and (not (/.or /.false /.false)) + (and (not (/.or)) + (not (/.or /.false /.false)) (/.or /.false /.true) (/.or /.true /.false) (/.or /.true /.true))) (_.coverage [/.and] - (and (not (/.and /.false /.false)) + (and (/.and) + (not (/.and /.false /.false)) (not (/.and /.false /.true)) (not (/.and /.true /.false)) (/.and /.true /.true))) diff --git a/stdlib/source/test/lux/control/function.lux b/stdlib/source/test/lux/control/function.lux index f4333d520..fe8c69b07 100644 --- a/stdlib/source/test/lux/control/function.lux +++ b/stdlib/source/test/lux/control/function.lux @@ -26,7 +26,8 @@ ["[1][0]" trampoline] ["[1][0]" polymorphism ["[1]/[0]" type] - ["[1]/[0]" predicate]]]) + ["[1]/[0]" predicate] + ["[1]/[0]" context]]]) (def .public test Test @@ -78,4 +79,5 @@ /trampoline.test /polymorphism/type.test /polymorphism/predicate.test + /polymorphism/context.test )))) diff --git a/stdlib/source/test/lux/control/function/polymorphism/context.lux b/stdlib/source/test/lux/control/function/polymorphism/context.lux new file mode 100644 index 000000000..6b12a0360 --- /dev/null +++ b/stdlib/source/test/lux/control/function/polymorphism/context.lux @@ -0,0 +1,117 @@ +(.require + [library + [lux (.except) + [abstract + [monad (.only do)]] + [control + ["context" reader (.use "[1]#[0]" monad)]] + [data + [collection + ["[0]" set]]] + [math + ["[0]" random (.only Random)] + [number + ["i" int]]] + [test + ["_" property (.only Test)]]]] + [\\library + ["[0]" /]]) + +(/.def .public (arbitrary _ negative zero positive) + [(All (_ value))] + Int + [value value value] + value + + (context#in zero) + + (/.method (arbitrary next negative zero positive) + (i.> +0) + (context#in positive)) + + (/.method (arbitrary next negative zero positive) + (i.< +0) + (context#in negative)) + ) + +(/.layer positive) +(/.layer negative) + +(/.def .public (layered _ negative zero positive) + [(All (_ value))] + /.Context + [value value value] + value + + (context#in zero) + + (/.method (layered next negative zero positive) + (/.active? ..positive) + (context#in positive)) + + (/.method (layered next negative zero positive) + (/.active? ..negative) + (context#in negative)) + ) + +(def .public test + Test + (<| (_.covering /._) + (do [! random.monad] + [negative random.nat + zero random.nat + positive random.nat + choice random.int]) + (all _.and + (_.coverage [/.def /.method] + (|> (arbitrary negative zero positive) + (context.result choice) + (same? (cond (i.> +0 choice) positive + (i.< +0 choice) negative + ... else + zero)))) + (_.coverage [/.altered] + (|> (arbitrary negative zero positive) + (/.altered (i.* -1)) + (context.result choice) + (same? (cond (i.> +0 choice) negative + (i.< +0 choice) positive + ... else + zero)))) + (_.for [/.Context] + (all _.and + (_.coverage [/.empty] + (|> (layered negative zero positive) + (context.result /.empty) + (same? zero))) + (_.coverage [/.with] + (and (|> (layered negative zero positive) + (/.with ..positive) + (context.result /.empty) + (same? positive)) + (|> (layered negative zero positive) + (/.with ..negative) + (context.result /.empty) + (same? negative)))) + (_.coverage [/.without] + (|> (layered negative zero positive) + (/.without ..positive) + (/.with ..positive) + (context.result /.empty) + (same? zero))))) + (_.for [/.Layer /.layer] + (all _.and + (_.coverage [/.active?] + (|> (do context.monad + [it context.read] + (in (/.active? ..positive it))) + (/.with ..positive) + (context.result /.empty))) + (_.coverage [/.inactive?] + (|> (do context.monad + [it context.read] + (in (/.inactive? ..negative it))) + (/.with ..positive) + (context.result /.empty))) + )) + ))) diff --git a/stdlib/source/test/lux/program.lux b/stdlib/source/test/lux/program.lux index a4382595d..dbe034606 100644 --- a/stdlib/source/test/lux/program.lux +++ b/stdlib/source/test/lux/program.lux @@ -98,7 +98,7 @@ (do random.monad [inputs (random.list 5 (random.upper_case 5))] (all _.and - (_.coverage [/.program] + (_.coverage [/.Program /.program] (let [(open "list#[0]") (list.equivalence text.equivalence)] (and (let [outcome ((is /.Program (/.program all_arguments diff --git a/stdlib/source/test/lux/test.lux b/stdlib/source/test/lux/test.lux index 6400db17f..8d9be9f39 100644 --- a/stdlib/source/test/lux/test.lux +++ b/stdlib/source/test/lux/test.lux @@ -6,6 +6,7 @@ ["[0]" / ["[1][0]" coverage] ["[1][0]" tally] + ["[1][0]" unit] ["[1][0]" property]]) (def .public test @@ -13,5 +14,6 @@ (all _.and /coverage.test /tally.test + /unit.test /property.test )) diff --git a/stdlib/source/test/lux/test/property.lux b/stdlib/source/test/lux/test/property.lux index 8a1fa2f0d..e1bc232dd 100644 --- a/stdlib/source/test/lux/test/property.lux +++ b/stdlib/source/test/lux/test/property.lux @@ -32,39 +32,6 @@ (n.= successes (the tally.#successes tally)) (n.= failures (the tally.#failures tally)))) -(def unit_test - /.Test - (do [! random.monad] - [expected_message/0 (random.lower_case 5) - expected_message/1 (random.only (|>> (text#= expected_message/0) not) - (random.lower_case 5))] - (all /.and - (in (do async.monad - [[success_tally success_message] (unit.test expected_message/0 true) - [failure_tally failure_message] (unit.test expected_message/0 false)] - (unit.coverage [unit.test] - (and (text.ends_with? (%.text expected_message/0) success_message) - (text.ends_with? (%.text expected_message/0) failure_message) - (and (n.= 1 (the tally.#successes success_tally)) - (n.= 0 (the tally.#successes failure_tally))) - (and (n.= 0 (the tally.#failures success_tally)) - (n.= 1 (the tally.#failures failure_tally))))))) - (in (do async.monad - [tt (unit.and (unit.test expected_message/0 true) - (unit.test expected_message/1 true)) - ff (unit.and (unit.test expected_message/0 false) - (unit.test expected_message/1 false)) - tf (unit.and (unit.test expected_message/0 true) - (unit.test expected_message/1 false)) - ft (unit.and (unit.test expected_message/0 false) - (unit.test expected_message/1 true))] - (unit.coverage [unit.and] - (and (..verify expected_message/0 expected_message/1 2 0 tt) - (..verify expected_message/0 expected_message/1 0 2 ff) - (..verify expected_message/0 expected_message/1 1 1 tf) - (..verify expected_message/0 expected_message/1 1 1 ft))))) - ))) - (def seed /.Test (do [! random.monad] @@ -197,17 +164,6 @@ (set.member? (the tally.#actual covering) (symbol ..dummy_target)))))))) (do random.monad [not_covering (/.covering .._ (/.test "" true)) - covering (/.covering .._ (in (unit.coverage [..dummy_target] true)))] - (in (do async.monad - [[not_covering _] not_covering - [covering _] covering] - (unit.coverage [unit.coverage] - (and (and (not (set.empty? (the tally.#expected not_covering))) - (not (set.member? (the tally.#actual not_covering) (symbol ..dummy_target)))) - (and (not (set.empty? (the tally.#expected covering))) - (set.member? (the tally.#actual covering) (symbol ..dummy_target)))))))) - (do random.monad - [not_covering (/.covering .._ (/.test "" true)) covering (/.covering .._ (/.for [..dummy_target] (/.test "" true)))] (in (do async.monad [[not_covering _] not_covering @@ -230,8 +186,6 @@ expected_message/1 (random.only (|>> (text#= expected_message/0) not) (random.lower_case 5))] (all /.and - (/.for [unit.Test] - ..unit_test) (/.for [/.Seed] seed) (do ! @@ -282,13 +236,21 @@ (and (n.= 0 (the tally.#successes failure_tally)) (n.= 1 (the tally.#failures failure_tally)))))))) (do ! + [success_unit_test (/.success expected_message/0)] + (in (do async.monad + [[success_tally success_message] success_unit_test] + (unit.coverage [/.success] + (and (text.contains? expected_message/0 success_message) + (n.= 1 (the tally.#successes success_tally)) + (n.= 0 (the tally.#failures success_tally))))))) + (do ! [failure_unit_test (/.failure expected_message/0)] (in (do async.monad [[failure_tally failure_message] failure_unit_test] (unit.coverage [/.failure] (and (text.contains? expected_message/0 failure_message) - (and (n.= 0 (the tally.#successes failure_tally)) - (n.= 1 (the tally.#failures failure_tally)))))))) + (n.= 0 (the tally.#successes failure_tally)) + (n.= 1 (the tally.#failures failure_tally))))))) (do ! [success_unit_test (/.lifted expected_message/0 (in true)) failure_unit_test (/.lifted expected_message/0 (in false))] diff --git a/stdlib/source/test/lux/test/unit.lux b/stdlib/source/test/lux/test/unit.lux new file mode 100644 index 000000000..edfc8224a --- /dev/null +++ b/stdlib/source/test/lux/test/unit.lux @@ -0,0 +1,126 @@ +(.require + [library + [lux (.except) + [abstract + [monad (.only do)]] + [control + [concurrency + ["[0]" async]]] + [data + ["[0]" text (.only) + ["%" \\format]] + [collection + ["[0]" set (.use "[1]#[0]" equivalence)]]] + [math + ["[0]" random (.only Random) (.use "[1]#[0]" monad)] + [number + ["n" nat]]] + [meta + ["[0]" static] + ["[0]" code]] + [test + ["_" property (.only Test)]]]] + [\\library + ["[0]" / (.only) + [// + ["[0]" tally (.only Tally)]]]]) + +(def (verify expected_message/0 expected_message/1 successes failures [tally message]) + (-> Text Text Nat Nat [Tally Text] Bit) + (and (text.contains? expected_message/0 message) + (text.contains? expected_message/1 message) + (n.= successes (the tally.#successes tally)) + (n.= failures (the tally.#failures tally)))) + +(with_expansions [expected_message/0 (static.random (|>> %.nat code.text) random.nat) + expected_message/1 (static.random (|>> %.int code.text) random.int) + <context> (static.random (|>> %.rev code.text) random.rev) + <success?> (static.random code.bit random.bit)] + (these (def .public dummy_target + (static.random_nat)) + + (def .public test + Test + (<| random#in + (/.covering /._) + (/.for [/.Test]) + (all /.and + (do async.monad + [[success_tally success_message] (/.success expected_message/0)] + (/.coverage [/.success] + (and (text.contains? (%.text expected_message/0) success_message) + (n.= 1 (the tally.#successes success_tally)) + (n.= 0 (the tally.#failures success_tally))))) + (do async.monad + [[failure_tally failure_message] (/.failure expected_message/0)] + (/.coverage [/.failure] + (and (text.contains? expected_message/0 failure_message) + (n.= 0 (the tally.#successes failure_tally)) + (n.= 1 (the tally.#failures failure_tally))))) + (do async.monad + [[success_tally success_message] (/.test expected_message/0 true) + [failure_tally failure_message] (/.test expected_message/0 false)] + (/.coverage [/.test] + (and (text.ends_with? (%.text expected_message/0) success_message) + (text.ends_with? (%.text expected_message/0) failure_message) + (and (n.= 1 (the tally.#successes success_tally)) + (n.= 0 (the tally.#successes failure_tally))) + (and (n.= 0 (the tally.#failures success_tally)) + (n.= 1 (the tally.#failures failure_tally)))))) + (do async.monad + [tt (/.and (/.test expected_message/0 true) + (/.test expected_message/1 true)) + ff (/.and (/.test expected_message/0 false) + (/.test expected_message/1 false)) + tf (/.and (/.test expected_message/0 true) + (/.test expected_message/1 false)) + ft (/.and (/.test expected_message/0 false) + (/.test expected_message/1 true))] + (/.coverage [/.and] + (and (..verify expected_message/0 expected_message/1 2 0 tt) + (..verify expected_message/0 expected_message/1 0 2 ff) + (..verify expected_message/0 expected_message/1 1 1 tf) + (..verify expected_message/0 expected_message/1 1 1 ft)))) + (do async.monad + [[tally _] (/.covering .._ (/.test "" true))] + (/.coverage [/.covering] + (set.member? (the tally.#expected tally) (symbol ..dummy_target)))) + (do async.monad + [[not_covering _] (/.covering .._ (/.test "" true)) + [covering _] (/.covering .._ (/.coverage [..dummy_target] true))] + (/.coverage [/.coverage] + (and (and (set.member? (the tally.#expected not_covering) (symbol ..dummy_target)) + (not (set.member? (the tally.#actual not_covering) (symbol ..dummy_target)))) + (and (set.member? (the tally.#expected covering) (symbol ..dummy_target)) + (set.member? (the tally.#actual covering) (symbol ..dummy_target)))))) + (do async.monad + [[reference_tally reference_message] (/.test expected_message/0 <success?>) + [context_tally context_message] (/.context <context> + (/.test expected_message/0 <success?>))] + (/.coverage [/.context] + (and (set#= (the tally.#expected context_tally) + (the tally.#expected reference_tally)) + (set#= (the tally.#actual context_tally) + (the tally.#actual reference_tally)) + (n.= (the tally.#successes context_tally) + (the tally.#successes reference_tally)) + (n.= (the tally.#failures context_tally) + (the tally.#failures reference_tally)) + (text.contains? (%.text <context>) context_message) + (not (text.contains? (%.text <context>) reference_message))))) + (do async.monad + [[reference_tally reference_message] (/.test expected_message/0 <success?>) + [context_tally context_message] (<| (/.for [..dummy_target]) + (/.test expected_message/0 <success?>))] + (/.coverage [/.for] + (and (set#= (the tally.#expected reference_tally) + (the tally.#expected context_tally)) + (not (set#= (the tally.#actual reference_tally) + (the tally.#actual context_tally))) + (n.= (the tally.#successes reference_tally) + (the tally.#successes context_tally)) + (n.= (the tally.#failures reference_tally) + (the tally.#failures context_tally)) + (not (text.contains? (%.symbol (symbol ..dummy_target)) reference_message)) + (text.contains? (%.symbol (symbol ..dummy_target)) context_message)))) + ))))) diff --git a/stdlib/source/test/lux/world/time/day.lux b/stdlib/source/test/lux/world/time/day.lux index c6471ffae..a893a1405 100644 --- a/stdlib/source/test/lux/world/time/day.lux +++ b/stdlib/source/test/lux/world/time/day.lux @@ -45,46 +45,59 @@ [expected ..random invalid (random.only (predicate.or (n.< (/.number {/.#Sunday})) (n.> (/.number {/.#Saturday}))) - random.nat)] - (all _.and - (_.for [/.equivalence] - ($equivalence.spec /.equivalence ..random)) - (_.for [/.hash] - ($hash.spec /.hash ..random)) - (_.for [/.order] - ($order.spec /.order ..random)) - (_.for [/.enum] - ($enum.spec /.enum ..random)) - (_.for [/.codec] - ($codec.spec /.equivalence /.codec ..random)) + random.nat)]) + (`` (all _.and + (_.for [/.equivalence] + ($equivalence.spec /.equivalence ..random)) + (_.for [/.hash] + ($hash.spec /.hash ..random)) + (_.for [/.order] + ($order.spec /.order ..random)) + (_.for [/.enum] + ($enum.spec /.enum ..random)) + (_.for [/.codec] + ($codec.spec /.equivalence /.codec ..random)) - (do random.monad - [not_a_day (random.upper_case 1)] - (_.coverage [/.not_a_day_of_the_week] - (when (at /.codec decoded not_a_day) + (,, (with_template [<before> <current> <after>] + [(_.coverage [<current>] + (and (at /.equivalence = {<before>} (at /.enum pred {<current>})) + (at /.equivalence = {<after>} (at /.enum succ {<current>}))))] + + [/.#Saturday /.#Sunday /.#Monday] + [/.#Sunday /.#Monday /.#Tuesday] + [/.#Monday /.#Tuesday /.#Wednesday] + [/.#Tuesday /.#Wednesday /.#Thursday] + [/.#Wednesday /.#Thursday /.#Friday] + [/.#Thursday /.#Friday /.#Saturday] + [/.#Friday /.#Saturday /.#Sunday] + )) + (do random.monad + [not_a_day (random.upper_case 1)] + (_.coverage [/.not_a_day_of_the_week] + (when (at /.codec decoded not_a_day) + {try.#Failure error} + (exception.match? /.not_a_day_of_the_week error) + + {try.#Success _} + false))) + (_.coverage [/.number /.by_number] + (|> expected + /.number + /.by_number + (try#each (at /.equivalence = expected)) + (try.else false))) + (_.coverage [/.invalid_day] + (when (/.by_number invalid) {try.#Failure error} - (exception.match? /.not_a_day_of_the_week error) + (exception.match? /.invalid_day error) {try.#Success _} - false))) - (_.coverage [/.number /.by_number] - (|> expected - /.number - /.by_number - (try#each (at /.equivalence = expected)) - (try.else false))) - (_.coverage [/.invalid_day] - (when (/.by_number invalid) - {try.#Failure error} - (exception.match? /.invalid_day error) - - {try.#Success _} - false)) - (_.coverage [/.week] - (let [all (list.size /.week) - uniques (set.size (set.of_list /.hash /.week))] - (and (n.= (/.number {/.#Saturday}) - all) - (n.= all - uniques)))) - )))) + false)) + (_.coverage [/.week] + (let [all (list.size /.week) + uniques (set.size (set.of_list /.hash /.week))] + (and (n.= (/.number {/.#Saturday}) + all) + (n.= all + uniques)))) + )))) diff --git a/stdlib/source/test/lux/world/time/month.lux b/stdlib/source/test/lux/world/time/month.lux index 29117b8d3..d259985c6 100644 --- a/stdlib/source/test/lux/world/time/month.lux +++ b/stdlib/source/test/lux/world/time/month.lux @@ -40,63 +40,81 @@ Test (<| (_.covering /._) (_.for [/.Month]) - (all _.and - (_.for [/.equivalence] - ($equivalence.spec /.equivalence ..random)) - (_.for [/.hash] - ($hash.spec /.hash ..random)) - (_.for [/.order] - ($order.spec /.order ..random)) - (_.for [/.enum] - ($enum.spec /.enum ..random)) - (_.for [/.codec] - ($codec.spec /.equivalence /.codec ..random)) + (`` (all _.and + (_.for [/.equivalence] + ($equivalence.spec /.equivalence ..random)) + (_.for [/.hash] + ($hash.spec /.hash ..random)) + (_.for [/.order] + ($order.spec /.order ..random)) + (_.for [/.enum] + ($enum.spec /.enum ..random)) + (_.for [/.codec] + ($codec.spec /.equivalence /.codec ..random)) - (do random.monad - [expected ..random - invalid (random.only (predicate.or (n.< (/.number {/.#January})) - (n.> (/.number {/.#December}))) - random.nat)] - (all _.and - (_.coverage [/.number /.by_number] - (|> expected - /.number - /.by_number - (try#each (at /.equivalence = expected)) - (try.else false))) - (_.coverage [/.invalid_month] - (when (/.by_number invalid) - {try.#Failure error} - (exception.match? /.invalid_month error) - - {try.#Success _} - false)) - (_.coverage [/.year] - (let [all (list.size /.year) - uniques (set.size (set.of_list /.hash /.year))] - (and (n.= (/.number {/.#December}) - all) - (n.= all - uniques)))) - (_.coverage [/.days] - (let [expected (.nat (duration.ticks duration.day duration.normal_year))] - (|> /.year - (list#each /.days) - (list#mix n.+ 0) - (n.= expected)))) - (_.coverage [/.leap_year_days] - (let [expected (.nat (duration.ticks duration.day duration.leap_year))] - (|> /.year - (list#each /.leap_year_days) - (list#mix n.+ 0) - (n.= expected)))) - (do random.monad - [not_a_month (random.upper_case 1)] - (_.coverage [/.not_a_month_of_the_year] - (when (at /.codec decoded not_a_month) - {try.#Failure error} - (exception.match? /.not_a_month_of_the_year error) - - {try.#Success _} - false))) - ))))) + (,, (with_template [<before> <current> <after>] + [(_.coverage [<current>] + (and (at /.equivalence = {<before>} (at /.enum pred {<current>})) + (at /.equivalence = {<after>} (at /.enum succ {<current>}))))] + + [/.#December /.#January /.#February] + [/.#January /.#February /.#March] + [/.#February /.#March /.#April] + [/.#March /.#April /.#May] + [/.#April /.#May /.#June] + [/.#May /.#June /.#July] + [/.#June /.#July /.#August] + [/.#July /.#August /.#September] + [/.#August /.#September /.#October] + [/.#September /.#October /.#November] + [/.#October /.#November /.#December] + [/.#November /.#December /.#January] + )) + (do random.monad + [expected ..random + invalid (random.only (predicate.or (n.< (/.number {/.#January})) + (n.> (/.number {/.#December}))) + random.nat)] + (all _.and + (_.coverage [/.number /.by_number] + (|> expected + /.number + /.by_number + (try#each (at /.equivalence = expected)) + (try.else false))) + (_.coverage [/.invalid_month] + (when (/.by_number invalid) + {try.#Failure error} + (exception.match? /.invalid_month error) + + {try.#Success _} + false)) + (_.coverage [/.year] + (let [all (list.size /.year) + uniques (set.size (set.of_list /.hash /.year))] + (and (n.= (/.number {/.#December}) + all) + (n.= all + uniques)))) + (_.coverage [/.days] + (let [expected (.nat (duration.ticks duration.day duration.normal_year))] + (|> /.year + (list#each /.days) + (list#mix n.+ 0) + (n.= expected)))) + (_.coverage [/.leap_year_days] + (let [expected (.nat (duration.ticks duration.day duration.leap_year))] + (|> /.year + (list#each /.leap_year_days) + (list#mix n.+ 0) + (n.= expected)))) + (do random.monad + [not_a_month (random.upper_case 1)] + (_.coverage [/.not_a_month_of_the_year] + (when (at /.codec decoded not_a_month) + {try.#Failure error} + (exception.match? /.not_a_month_of_the_year error) + + {try.#Success _} + false))) + )))))) |