From d37982f0af44714d95caf24d7f944e4e659b3e69 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Thu, 6 Jan 2022 14:28:32 -0400 Subject: Fixes for the pure-Lux JVM compiler machinery. [Part 2] --- stdlib/source/test/lux.lux | 20 +- stdlib/source/test/lux/extension.lux | 9 +- stdlib/source/test/lux/target/js.lux | 2 +- stdlib/source/test/lux/target/lua.lux | 709 +++++++++++++++++++++++++++++++ stdlib/source/test/lux/target/python.lux | 17 +- stdlib/source/test/lux/target/ruby.lux | 2 +- 6 files changed, 731 insertions(+), 28 deletions(-) create mode 100644 stdlib/source/test/lux/target/lua.lux (limited to 'stdlib/source/test') diff --git a/stdlib/source/test/lux.lux b/stdlib/source/test/lux.lux index 255d15c71..631f754e4 100644 --- a/stdlib/source/test/lux.lux +++ b/stdlib/source/test/lux.lux @@ -65,8 +65,9 @@ (~~ (.for ["{old}" (~~ (.as_is ["[1]/[0]" jvm])) "JVM" (~~ (.as_is ["[1]/[0]" jvm])) "JavaScript" (~~ (.as_is ["[1]/[0]" js])) - "Ruby" (~~ (.as_is ["[1]/[0]" ruby])) - "Python" (~~ (.as_is ["[1]/[0]" python]))] + "Lua" (~~ (.as_is ["[1]/[0]" lua])) + "Python" (~~ (.as_is ["[1]/[0]" python])) + "Ruby" (~~ (.as_is ["[1]/[0]" ruby]))] (~~ (.as_is))))] ]))) @@ -101,8 +102,9 @@ (~~ (for [@.jvm (~~ (as_is /target/jvm.test)) @.old (~~ (as_is /target/jvm.test)) @.js (~~ (as_is /target/js.test)) - @.ruby (~~ (as_is /target/ruby.test)) - @.python (~~ (as_is /target/python.test))] + @.lua (~~ (as_is /target/lua.test)) + @.python (~~ (as_is /target/python.test)) + @.ruby (~~ (as_is /target/ruby.test))] (~~ (as_is)))) (~~ (for [@.old (~~ (as_is))] (~~ (as_is /extension.test)))) @@ -181,21 +183,21 @@ (case (/.try expected) {.#Left _} false - + {.#Right actual} (n.= expected actual))) (_.cover [/.undefined] (case (/.try (/.undefined)) {.#Left _} true - + {.#Right _} false)) (_.cover [/.panic!] (case (/.try (/.panic! expected_error)) {.#Left actual_error} (text.contains? expected_error actual_error) - + {.#Right _} false)) ))) @@ -1116,7 +1118,7 @@ (value@ .#mappings) (list#each product.left) (set.of_list text.hash)) - + correct_locals! (and (n.= 4 (value@ .#counter locals/2)) (set#= expected_locals/2 @@ -1149,7 +1151,7 @@ (binding? captured? let/0))] (and correct_locals! correct_closure!)) - + _ false))))) diff --git a/stdlib/source/test/lux/extension.lux b/stdlib/source/test/lux/extension.lux index 92b314dc7..a754e9bd2 100644 --- a/stdlib/source/test/lux/extension.lux +++ b/stdlib/source/test/lux/extension.lux @@ -150,6 +150,9 @@ @.js (generation.save! artifact_id {.#None} (js.comment commentary (js.statement (js.string commentary)))) + @.python (generation.save! artifact_id {.#None} + (python.comment commentary + (python.statement (python.string commentary)))) @.lua (generation.save! artifact_id {.#None} (lua.comment commentary (lua.statement (lua.string commentary)))) @@ -159,8 +162,10 @@ (generation.log! commentary))))] (in directive.no_requirements))) - ... TODO: No longer skip testing Lua after Rembulan isn't being used anymore. - (for [@.lua (as_is)] + (for [... TODO: No longer skip testing Lua after Rembulan isn't being used anymore. + @.lua (as_is) + ... TODO: No longer skip testing Python. + @.python (as_is)] (`` ((~~ (static ..directive)) (n.* 2 3)))) )) diff --git a/stdlib/source/test/lux/target/js.lux b/stdlib/source/test/lux/target/js.lux index cc60dd896..ae190fade 100644 --- a/stdlib/source/test/lux/target/js.lux +++ b/stdlib/source/test/lux/target/js.lux @@ -80,7 +80,7 @@ (try#each (function (_ it) (case it {.#None} true - {.#Some _} true))) + {.#Some _} false))) (try.else false))) (_.cover [/.boolean] (expression (|>> (:as Bit) (bit#= boolean)) diff --git a/stdlib/source/test/lux/target/lua.lux b/stdlib/source/test/lux/target/lua.lux new file mode 100644 index 000000000..2558f41c8 --- /dev/null +++ b/stdlib/source/test/lux/target/lua.lux @@ -0,0 +1,709 @@ +(.using + [library + [lux "*" + ["_" test {"+" Test}] + ["[0]" ffi] + ["[0]" static] + [abstract + [monad {"+" do}] + [\\specification + ["$[0]" equivalence] + ["$[0]" hash]]] + [control + [pipe {"+" case>}] + ["[0]" function] + ["[0]" maybe ("[1]#[0]" functor)] + ["[0]" try {"+" Try} ("[1]#[0]" functor)]] + [data + ["[0]" bit ("[1]#[0]" equivalence)] + ["[0]" text {"+" \n} ("[1]#[0]" equivalence) + ["%" format {"+" format}]] + [collection + ["[0]" list ("[1]#[0]" functor)]]] + [macro + ["[0]" template]] + ["[0]" math + ["[0]" random {"+" Random} ("[1]#[0]" monad)] + [number + ["n" nat] + ["i" int] + ["f" frac] + ["[0]" i64]]]]] + [\\library + ["[0]" /]]) + +... http://www.lua.org/manual/5.3/manual.html#pdf-load +(ffi.import: (load [Text] "?" (-> Any Any))) + +(def: (expression ??? it) + (-> (-> Any Bit) /.Expression Bit) + (|> it + /.code + (format "return ") + ..load + (maybe#each (|>> (function.on []) ???)) + (maybe.else false))) + +(def: test|literal + Test + (do [! random.monad] + [boolean random.bit + int random.int + float random.frac + string (random.ascii/upper 5)] + ($_ _.and + (_.cover [/.nil] + (|> /.nil + /.code + ..load + (case> {.#None} true + {.#Some _} false))) + (_.cover [/.boolean] + (expression (|>> (:as Bit) (bit#= boolean)) + (/.boolean boolean))) + (_.cover [/.int] + (expression (|>> (:as Int) (i.= int)) + (/.int int))) + (_.cover [/.float] + (expression (|>> (:as Frac) (f.= float)) + (/.float float))) + (_.cover [/.string] + (expression (|>> (:as Text) (text#= string)) + (/.string string))) + ))) + +(def: test|boolean + Test + (do [! random.monad] + [left random.bit + right random.bit] + (`` ($_ _.and + (~~ (template [ ] + [(_.cover [] + (let [expected ( left right)] + (expression (|>> (:as Bit) (bit#= expected)) + ( (/.boolean left) (/.boolean right)))))] + + [/.or .or] + [/.and .and] + )) + (_.cover [/.not] + (expression (|>> (:as Bit) (bit#= (not left))) + (/.not (/.boolean left)))) + )))) + +(template [] + [(`` (def: (~~ (template.symbol [int/ ])) + (Random Int) + (let [mask (|> 1 (i64.left_shifted (-- )) --)] + (random#each (|>> (i64.and mask) .int) random.nat))))] + + [16] + [32] + ) + +(def: test|int + Test + (do [! random.monad] + [left random.int + right random.int + shift (# ! each (n.% 65) random.nat) + + parameter (random.only (|>> (i.= +0) not) + random.int) + subject random.int] + (`` ($_ _.and + (~~ (template [ ] + [(_.cover [] + (let [expected ( left right)] + (expression (|>> (:as Int) (i.= expected)) + ( (/.int left) (/.int right)))))] + + [/.bit_or i64.or] + [/.bit_xor i64.xor] + [/.bit_and i64.and] + )) + (_.cover [/.opposite] + (expression (|>> (:as Int) (i.= (i.- left +0))) + (/.opposite (/.int left)))) + (_.cover [/.bit_shl] + (let [expected (i64.left_shifted shift left)] + (expression (|>> (:as Int) (i.= expected)) + (/.bit_shl (/.int (.int shift)) + (/.int left))))) + (_.cover [/.bit_shr] + (let [expected (i64.right_shifted shift left)] + (expression (|>> (:as Int) (i.= expected)) + (/.bit_shr (/.int (.int shift)) + (/.int left))))) + (_.cover [/.//] + (let [expected (if (or (i.= (i.signum parameter) (i.signum subject)) + (i.= +0 (i.% parameter subject))) + (i./ parameter subject) + (-- (i./ parameter subject)))] + (expression (|>> (:as Int) (i.= expected)) + (/.// (/.int parameter) (/.int subject))))) + )))) + +(def: test|float + Test + (do [! random.monad] + [parameter (random.only (|>> (f.= +0.0) not) + random.safe_frac) + subject random.safe_frac] + (`` ($_ _.and + (~~ (template [
]
+                  [(_.cover []
+                            (let [expected ( (
 parameter) (
 subject))]
+                              (expression (|>> (:as Frac) (f.= expected))
+                                          ( (/.float (
 parameter)) (/.float (
 subject))))))]
+
+                  [/.+ f.+ |>]
+                  [/.- f.- |>]
+                  [/.* f.* |>]
+                  [/./ f./ |>]
+                  [/.% f.mod |>]
+                  [/.^ math.pow f.abs]
+                  ))
+            (~~ (template [ ]
+                  [(_.cover []
+                            (let [expected ( parameter subject)]
+                              (expression (|>> (:as Bit) (bit#= expected))
+                                          ( (/.float parameter) (/.float subject)))))]
+
+                  [/.<  f.<]
+                  [/.<= f.<=]
+                  [/.>  f.>]
+                  [/.>= f.>=]
+                  [/.=  f.=]
+                  ))
+            ))))
+
+(def: test|string
+  Test
+  (do random.monad
+    [left (random.ascii/lower 8)
+     right (random.ascii/lower 8)
+     .let [expected (format left right)]]
+    ($_ _.and
+        (_.cover [/.concat]
+                 (expression (|>> (:as Text) (text#= expected))
+                             (|> (/.string left)
+                                 (/.concat (/.string right)))))
+        )))
+
+(def: test|array
+  Test
+  (do [! random.monad]
+    [size (# ! each (|>> (n.% 10) ++) random.nat)
+     index (# ! each (n.% size) random.nat)
+     items (random.list size random.safe_frac)
+     .let [expected (|> items
+                        (list.item index)
+                        maybe.trusted)]]
+    ($_ _.and
+        (_.cover [/.array /.item]
+                 (and (expression (|>> (:as Frac) (f.= expected))
+                                  (/.item (/.int (.int (++ index)))
+                                          (/.array (list#each /.float items))))
+                      (expression (|>> (:as Bit))
+                                  (|> (/.array (list#each /.float items))
+                                      (/.item (/.int (.int (++ size))))
+                                      (/.= /.nil)))))
+        (_.cover [/.length]
+                 (expression (|>> (:as Int) (i.= (.int size)))
+                             (/.length (/.array (list#each /.float items)))))
+        )))
+
+(def: test|table
+  Test
+  (do [! random.monad]
+    [expected random.safe_frac
+     dummy (random.only (|>> (f.= expected) not)
+                        random.safe_frac)
+
+     size (# ! each (|>> (n.% 10) ++) random.nat)
+     index (# ! each (n.% size) random.nat)
+     items (random.list size random.safe_frac)
+
+     $self (# ! each /.var (random.ascii/lower 10))
+     $table (# ! each /.var (random.ascii/lower 11))
+     $arg (# ! each /.var (random.ascii/lower 12))
+     field (random.ascii/upper 5)
+     non_field (random.only (|>> (text#= field) not)
+                            (random.ascii/upper 5))
+     method (random.ascii/upper 6)]
+    ($_ _.and
+        (_.cover [/.table /.the]
+                 (and (expression (|>> (:as Frac) (f.= expected))
+                                  (/.the field (/.table (list [field (/.float expected)]))))
+                      (expression (|>> (:as Bit))
+                                  (|> (/.table (list [field (/.float expected)]))
+                                      (/.the non_field)
+                                      (/.= /.nil)))))
+        (_.cover [/.do /.function]
+                 (expression (|>> (:as Frac) (f.= expected))
+                             (|> ($_ /.then
+                                     (/.local/1 $table (/.table (list [field (/.float expected)])))
+                                     (/.function (/.the method $table) (list $self $arg)
+                                       (/.if (/.= (/.float dummy) $arg)
+                                         (/.return (/.the field $self))
+                                         (/.return $arg)))
+                                     (/.return (/.do method (list (/.float dummy)) $table)))
+                                 (/.closure (list))
+                                 (/.apply (list)))))
+        )))
+
+(def: test|computation
+  Test
+  (do [! random.monad]
+    [test random.bit
+     then random.safe_frac
+     else random.safe_frac
+
+     boolean random.bit
+     int random.int
+     float random.frac
+     string (random.ascii/upper 5)
+
+     comment (random.ascii/upper 10)]
+    ($_ _.and
+        ..test|boolean
+        ..test|int
+        ..test|float
+        ..test|string
+        ..test|array
+        ..test|table
+        (_.cover [/.type/1]
+                 (and (expression (|>> (:as Text) (text#= "boolean"))
+                                  (/.type/1 (/.boolean boolean)))
+                      (expression (|>> (:as Text) (text#= "number"))
+                                  (/.type/1 (/.int int)))
+                      (expression (|>> (:as Text) (text#= "number"))
+                                  (/.type/1 (/.float float)))
+                      (expression (|>> (:as Text) (text#= "string"))
+                                  (/.type/1 (/.string string)))
+                      (expression (|>> (:as Text) (text#= "nil"))
+                                  (/.type/1 /.nil))
+                      (expression (|>> (:as Text) (text#= "table"))
+                                  (/.type/1 (/.table (list [string (/.float float)]))))
+                      (expression (|>> (:as Text) (text#= "table"))
+                                  (/.type/1 (/.array (list (/.boolean boolean)
+                                                           (/.float float)
+                                                           (/.string string)))))
+                      ))
+        (_.cover [/.require/1]
+                 (expression (|>> (:as Int) (i.= (i.abs int)))
+                             (|> (/.require/1 (/.string "math"))
+                                 (/.the "abs")
+                                 (/.apply (list (/.int int))))))
+        (_.cover [/.comment]
+                 (expression (|>> (:as Frac) (f.= then))
+                             (/.comment comment
+                               (/.float then))))
+        )))
+
+(def: test|expression
+  Test
+  (`` ($_ _.and
+          (_.for [/.Literal]
+                 ..test|literal)
+          (_.for [/.Computation]
+                 ..test|computation)
+          )))
+
+(def: test/var
+  Test
+  (do [! random.monad]
+    [float/0 random.safe_frac
+     float/1 random.safe_frac
+     float/2 random.safe_frac
+     foreign (random.ascii/lower 10)
+     local (random.only (|>> (text#= foreign) not)
+                        (random.ascii/lower 10))
+     .let [$foreign (/.var foreign)
+           $local (/.var local)]]
+    ($_ _.and
+        (_.cover [/.var]
+                 (expression (|>> (:as Frac) (f.= float/0))
+                             (|> (/.return $foreign)
+                                 (/.closure (list $foreign))
+                                 (/.apply (list (/.float float/0))))))
+        (_.cover [/.let]
+                 (expression (|>> (:as Frac) (f.= float/1))
+                             (|> ($_ /.then
+                                     (/.let (list $local) (/.float float/1))
+                                     (/.return $local))
+                                 (/.closure (list $foreign))
+                                 (/.apply (list (/.float float/0))))))
+        (_.cover [/.local/1]
+                 (expression (|>> (:as Frac) (f.= float/1))
+                             (|> ($_ /.then
+                                     (/.local/1 $local (/.float float/1))
+                                     (/.return $local))
+                                 (/.closure (list $foreign))
+                                 (/.apply (list (/.float float/0))))))
+        (_.cover [/.local]
+                 (expression (|>> (:as Frac) (f.= float/1))
+                             (|> ($_ /.then
+                                     (/.local (list $local))
+                                     (/.set (list $local) (/.float float/1))
+                                     (/.return $local))
+                                 (/.closure (list $foreign))
+                                 (/.apply (list (/.float float/0))))))
+        )))
+
+(def: test/location
+  Test
+  (do [! random.monad]
+    [float/0 random.safe_frac
+     float/1 random.safe_frac
+     int/0 ..int/16
+     $foreign (# ! each /.var (random.ascii/lower 10))
+     $arg/0 (# ! each /.var (random.ascii/lower 11))
+     $arg/1 (# ! each /.var (random.ascii/lower 12))
+     field (random.ascii/upper 10)]
+    ($_ _.and
+        (_.cover [/.set]
+                 (expression (|>> (:as Frac) (f.= (f.+ float/0 float/0)))
+                             (|> ($_ /.then
+                                     (/.set (list $foreign) (/.+ $foreign $foreign))
+                                     (/.return $foreign))
+                                 (/.closure (list $foreign))
+                                 (/.apply (list (/.float float/0))))))
+        (_.cover [/.multi]
+                 (and (expression (|>> (:as Frac) (f.= float/0))
+                                  (|> ($_ /.then
+                                          (/.set (list $arg/0 $arg/1) (/.multi (list (/.float float/0) (/.float float/1))))
+                                          (/.return $arg/0))
+                                      (/.closure (list))
+                                      (/.apply (list))))
+                      (expression (|>> (:as Frac) (f.= float/1))
+                                  (|> ($_ /.then
+                                          (/.set (list $arg/0 $arg/1) (/.multi (list (/.float float/0) (/.float float/1))))
+                                          (/.return $arg/1))
+                                      (/.closure (list))
+                                      (/.apply (list))))))
+        (_.cover [/.Access]
+                 (and (expression (|>> (:as Frac) (f.= (f.+ float/0 float/0)))
+                                  (let [@ (/.item (/.int +1) $foreign)]
+                                    (|> ($_ /.then
+                                            (/.set (list $foreign) (/.array (list $foreign)))
+                                            (/.set (list @) (/.+ @ @))
+                                            (/.return @))
+                                        (/.closure (list $foreign))
+                                        (/.apply (list (/.float float/0))))))
+                      (expression (|>> (:as Frac) (f.= (f.+ float/0 float/0)))
+                                  (let [@ (/.the field $foreign)]
+                                    (|> ($_ /.then
+                                            (/.set (list $foreign) (/.table (list [field $foreign])))
+                                            (/.set (list @) (/.+ @ @))
+                                            (/.return @))
+                                        (/.closure (list $foreign))
+                                        (/.apply (list (/.float float/0))))))))
+        (_.for [/.Var]
+               ..test/var)
+        )))
+
+(def: test|label
+  Test
+  (do [! random.monad]
+    [input ..int/16
+
+     full_iterations (# ! each (|>> (n.% 20) ++) random.nat)
+     expected_iterations (# ! each (|>> (n.% full_iterations) .int) random.nat)
+
+     $input (# ! each /.var (random.ascii/lower 10))
+     $output (# ! each /.var (random.ascii/lower 11))
+     $index (# ! each /.var (random.ascii/lower 12))
+
+     @loop (# ! each /.label (random.ascii/lower 13))
+     
+     .let [expected (i.* expected_iterations input)
+           expected_iterations (/.int expected_iterations)]]
+    ($_ _.and
+        (_.cover [/.break]
+                 (let [=for_in (expression (|>> (:as Int) (i.= expected))
+                                           (|> ($_ /.then
+                                                   (/.local/1 $output (/.int +0))
+                                                   (/.for_in (list $index $input) (/.ipairs/1 (/.array (list.repeated full_iterations $input)))
+                                                             ($_ /.then
+                                                                 (/.when (/.> expected_iterations $index)
+                                                                         /.break)
+                                                                 (/.set (list $output) (/.+ $input $output))))
+                                                   (/.return $output))
+                                               (/.closure (list $input))
+                                               (/.apply (list (/.int input)))))
+                       
+                       full_iterations (/.int (.int full_iterations))
+                       =while (expression (|>> (:as Int) (i.= expected))
+                                          (|> ($_ /.then
+                                                  (/.local/1 $index (/.int +0))
+                                                  (/.local/1 $output (/.int +0))
+                                                  (/.while (/.< full_iterations $index)
+                                                           ($_ /.then
+                                                               (/.when (/.= expected_iterations $index)
+                                                                       /.break)
+                                                               (/.set (list $output) (/.+ $input $output))
+                                                               (/.set (list $index) (/.+ (/.int +1) $index))
+                                                               ))
+                                                  (/.return $output))
+                                              (/.closure (list $input))
+                                              (/.apply (list (/.int input)))))
+                       =repeat (expression (|>> (:as Int) (i.= expected))
+                                           (|> ($_ /.then
+                                                   (/.local/1 $index (/.int +0))
+                                                   (/.local/1 $output (/.int +0))
+                                                   (/.repeat (/.= full_iterations $index)
+                                                             ($_ /.then
+                                                                 (/.when (/.= expected_iterations $index)
+                                                                         /.break)
+                                                                 (/.set (list $output) (/.+ $input $output))
+                                                                 (/.set (list $index) (/.+ (/.int +1) $index))
+                                                                 ))
+                                                   (/.return $output))
+                                               (/.closure (list $input))
+                                               (/.apply (list (/.int input)))))
+                       =for_step (expression (|>> (:as Int) (i.= expected))
+                                             (|> ($_ /.then
+                                                     (/.local/1 $output (/.int +0))
+                                                     (/.for_step $index (/.int +0) full_iterations (/.int +1)
+                                                                 ($_ /.then
+                                                                     (/.when (/.= expected_iterations $index)
+                                                                             /.break)
+                                                                     (/.set (list $output) (/.+ $input $output))))
+                                                     (/.return $output))
+                                                 (/.closure (list $input))
+                                                 (/.apply (list (/.int input)))))]
+                   (and =while
+                        =repeat
+                        =for_step
+                        =for_in)))
+        (_.cover [/.label /.set_label /.go_to]
+                 (expression (|>> (:as Int) (i.= expected))
+                             (|> ($_ /.then
+                                     (/.local/1 $index (/.int +0))
+                                     (/.local/1 $output (/.int +0))
+                                     (/.set_label @loop)
+                                     (/.if (/.< expected_iterations $index)
+                                       ($_ /.then
+                                           (/.set (list $output) (/.+ $input $output))
+                                           (/.set (list $index) (/.+ (/.int +1) $index))
+                                           (/.go_to @loop))
+                                       (/.return $output)))
+                                 (/.closure (list $input))
+                                 (/.apply (list (/.int input))))))
+        )))
+
+(def: test|loop
+  Test
+  (do [! random.monad]
+    [input ..int/16
+     iterations (# ! each (n.% 10) random.nat)
+     .let [$input (/.var "input")
+           $output (/.var "output")
+           $index (/.var "index")
+           expected (i.* (.int iterations) input)]]
+    ($_ _.and
+        (_.cover [/.while]
+                 (expression (|>> (:as Int) (i.= expected))
+                             (|> ($_ /.then
+                                     (/.local/1 $index (/.int +0))
+                                     (/.local/1 $output (/.int +0))
+                                     (/.while (/.< (/.int (.int iterations)) $index)
+                                              ($_ /.then
+                                                  (/.set (list $output) (/.+ $input $output))
+                                                  (/.set (list $index) (/.+ (/.int +1) $index))
+                                                  ))
+                                     (/.return $output))
+                                 (/.closure (list $input))
+                                 (/.apply (list (/.int input))))))
+        (_.cover [/.repeat]
+                 (expression (|>> (:as Int) (i.= expected))
+                             (|> ($_ /.then
+                                     (/.local/1 $index (/.int +0))
+                                     (/.local/1 $output (/.int +0))
+                                     (/.repeat (/.= (/.int (.int iterations)) $index)
+                                               ($_ /.then
+                                                   (/.set (list $output) (/.+ $input $output))
+                                                   (/.set (list $index) (/.+ (/.int +1) $index))
+                                                   ))
+                                     (/.return $output))
+                                 (/.closure (list $input))
+                                 (/.apply (list (/.int input))))))
+        (_.cover [/.for_step]
+                 (expression (|>> (:as Int) (i.= expected))
+                             (|> ($_ /.then
+                                     (/.local/1 $output (/.int +0))
+                                     (/.for_step $index (/.int +0) (/.int (.int (-- iterations))) (/.int +1)
+                                                 (/.set (list $output) (/.+ $input $output)))
+                                     (/.return $output))
+                                 (/.closure (list $input))
+                                 (/.apply (list (/.int input))))))
+        (_.cover [/.for_in /.ipairs/1]
+                 (expression (|>> (:as Int) (i.= expected))
+                             (|> ($_ /.then
+                                     (/.local/1 $output (/.int +0))
+                                     (/.for_in (list $index $input) (/.ipairs/1 (/.array (list.repeated iterations $input)))
+                                               (/.set (list $output) (/.+ $input $output)))
+                                     (/.return $output))
+                                 (/.closure (list $input))
+                                 (/.apply (list (/.int input))))))
+        (_.for [/.Label]
+               ..test|label)
+        )))
+
+(def: test|exception
+  Test
+  (do [! random.monad]
+    [expected random.safe_frac
+     dummy (random.only (|>> (f.= expected) not)
+                        random.safe_frac)
+     $verdict (# ! each /.var (random.ascii/lower 10))
+     $outcome (# ! each /.var (random.ascii/lower 11))]
+    ($_ _.and
+        (_.cover [/.pcall/1]
+                 (expression (|>> (:as Frac) (f.= expected))
+                             (|> ($_ /.then
+                                     (/.let (list $verdict $outcome) (/.pcall/1 (/.closure (list)
+                                                                                           (/.return (/.float expected)))))
+                                     (/.if $verdict
+                                       (/.return $outcome)
+                                       (/.return (/.float dummy))))
+                                 (/.closure (list))
+                                 (/.apply (list)))))
+        (_.cover [/.error/1]
+                 (expression (|>> (:as Frac) (f.= expected))
+                             (|> ($_ /.then
+                                     (/.let (list $verdict $outcome) (/.pcall/1 (/.closure (list)
+                                                                                           ($_ /.then
+                                                                                               (/.statement (/.error/1 (/.float expected)))
+                                                                                               (/.return (/.float dummy))))))
+                                     (/.if $verdict
+                                       (/.return (/.float dummy))
+                                       (/.return $outcome)))
+                                 (/.closure (list))
+                                 (/.apply (list)))))
+        )))
+
+(def: test|function
+  Test
+  (do [! random.monad]
+    [float/0 random.safe_frac
+     iterations (# ! each (n.% 10) random.nat)
+     $self (# ! each /.var (random.ascii/lower 1))
+     $arg/0 (# ! each /.var (random.ascii/lower 2))
+     field (random.ascii/lower 3)
+     $class (# ! each /.var (random.ascii/upper 4))]
+    ($_ _.and
+        (_.cover [/.closure /.return]
+                 (expression (|>> (:as Frac) (f.= float/0))
+                             (/.apply (list)
+                                      (/.closure (list) (/.return (/.float float/0))))))
+        (_.cover [/.local_function]
+                 (expression (|>> (:as Int) .nat (n.= iterations))
+                             (|> ($_ /.then
+                                     (/.local_function $self (list $arg/0)
+                                                       (/.if (/.< (/.int (.int iterations)) $arg/0)
+                                                         (/.return (/.apply (list (/.+ (/.int +1) $arg/0)) $self))
+                                                         (/.return $arg/0)))
+                                     (/.return (/.apply (list (/.int +0)) $self)))
+                                 (/.closure (list))
+                                 (/.apply (list)))))
+        (do [! random.monad]
+          [float/0 random.safe_frac
+           float/1 random.safe_frac
+           float/2 random.safe_frac
+           $arg/0 (# ! each /.var (random.ascii/lower 10))
+           $arg/1 (# ! each /.var (random.ascii/lower 11))
+           $arg/2 (# ! each /.var (random.ascii/lower 12))]
+          (`` ($_ _.and
+                  (_.cover [/.apply]
+                           (expression (|>> (:as Frac) (f.= ($_ f.+ float/0 float/1 float/2)))
+                                       (/.apply (list (/.float float/0)
+                                                      (/.float float/1)
+                                                      (/.float float/2))
+                                                (/.closure (list $arg/0 $arg/1 $arg/2) (/.return ($_ /.+ $arg/0 $arg/1 $arg/2))))))
+                  )))
+        )))
+
+(def: test|branching
+  Test
+  (do [! random.monad]
+    [float/0 random.safe_frac
+     float/1 random.safe_frac
+     ??? random.bit]
+    ($_ _.and
+        (_.cover [/.if]
+                 (expression (|>> (:as Frac) (f.= (if ??? float/0 float/1)))
+                             (|> (/.if (/.boolean ???)
+                                   (/.return (/.float float/0))
+                                   (/.return (/.float float/1)))
+                                 (/.closure (list))
+                                 (/.apply (list)))))
+        (_.cover [/.when]
+                 (expression (|>> (:as Frac) (f.= (if ??? float/0 float/1)))
+                             (|> ($_ /.then
+                                     (/.when (/.boolean ???)
+                                             (/.return (/.float float/0)))
+                                     (/.return (/.float float/1)))
+                                 (/.closure (list))
+                                 (/.apply (list)))))
+        )))
+
+(def: test|binding
+  Test
+  ($_ _.and
+      ..test|function
+      (_.for [/.Location]
+             ..test/location)
+      ))
+
+(def: test|control
+  Test
+  ($_ _.and
+      ..test|branching
+      ..test|loop
+      ..test|exception
+      ))
+
+(def: test|statement
+  Test
+  (do [! random.monad]
+    [float/0 random.safe_frac
+     float/1 random.safe_frac
+     $arg/0 (# ! each /.var (random.ascii/lower 10))
+     $arg/1 (# ! each /.var (random.ascii/lower 11))]
+    (`` ($_ _.and
+            (_.cover [/.statement /.then /.print/1]
+                     (expression (|>> (:as Frac) (f.= float/0))
+                                 (|> ($_ /.then
+                                         (/.statement (/.print/1 $arg/0))
+                                         (/.return $arg/0))
+                                     (/.closure (list $arg/0))
+                                     (/.apply (list (/.float float/0))))))
+            ..test|binding
+            ..test|control
+            ))))
+
+(def: .public test
+  Test
+  (do [! random.monad]
+    [.let [random (# ! each /.int random.int)]
+     expected random.int]
+    (<| (_.covering /._)
+        (_.for [/.Code /.code])
+        (`` ($_ _.and
+                (_.for [/.equivalence]
+                       ($equivalence.spec /.equivalence random))
+                (_.for [/.hash]
+                       ($hash.spec /.hash random))
+                
+                (_.cover [/.manual]
+                         (expression (|>> (:as Int) (i.= expected))
+                                     (/.manual (/.code (/.int expected)))))
+                (_.for [/.Expression]
+                       ..test|expression)
+                (_.for [/.Statement]
+                       ..test|statement)
+                )))))
diff --git a/stdlib/source/test/lux/target/python.lux b/stdlib/source/test/lux/target/python.lux
index 49d74c1b3..e936ba850 100644
--- a/stdlib/source/test/lux/target/python.lux
+++ b/stdlib/source/test/lux/target/python.lux
@@ -29,25 +29,12 @@
 
 (def: (expression ??? it)
   (-> (-> Any Bit) (/.Expression Any) Bit)
-  ... (case (|> it /.code ..eval)
-  ...   {try.#Success it}
-  ...   (|> it
-  ...       (maybe#each ???)
-  ...       (maybe.else false))
-  
-  ...   {try.#Failure error}
-  ...   (exec
-  ...     ("lux io log" "try.#Failure")
-  ...     ("lux io log" error)
-  ...     ("lux io log" (|> it /.code))
-  ...     false))
   (|> it
       /.code
       ..eval
       (try#each (|>> (maybe#each ???)
                      (maybe.else false)))
-      (try.else false))
-  )
+      (try.else false)))
 
 (def: test|literal
   Test
@@ -64,7 +51,7 @@
                      (try#each (function (_ it)
                                  (case it
                                    {.#None} true
-                                   {.#Some _} true)))
+                                   {.#Some _} false)))
                      (try.else false)))
         (_.cover [/.bool]
                  (expression (|>> (:as Bit) (bit#= bool))
diff --git a/stdlib/source/test/lux/target/ruby.lux b/stdlib/source/test/lux/target/ruby.lux
index 80d4a161f..87e781ebc 100644
--- a/stdlib/source/test/lux/target/ruby.lux
+++ b/stdlib/source/test/lux/target/ruby.lux
@@ -50,7 +50,7 @@
                      (try#each (function (_ it)
                                  (case it
                                    {.#None} true
-                                   {.#Some _} true)))
+                                   {.#Some _} false)))
                      (try.else false)))
         (_.cover [/.bool]
                  (expression (|>> (:as Bit) (bit#= bool))
-- 
cgit v1.2.3