diff options
30 files changed, 566 insertions, 61 deletions
diff --git a/documentation/bookmark/analysis/static/separation_logic.md b/documentation/bookmark/analysis/static/separation_logic.md new file mode 100644 index 000000000..9541dc47a --- /dev/null +++ b/documentation/bookmark/analysis/static/separation_logic.md @@ -0,0 +1,4 @@ +# Reference + +0. [A Primer on Separation Logic (and Automatic Program Verification and Analysis)](http://www0.cs.ucl.ac.uk/staff/p.ohearn/papers/Marktoberdorf11LectureNotes.pdf) + diff --git a/documentation/bookmark/bookmarklet.md b/documentation/bookmark/bookmarklet.md new file mode 100644 index 000000000..8fd9b7204 --- /dev/null +++ b/documentation/bookmark/bookmarklet.md @@ -0,0 +1,4 @@ +# Reference + +0. [Bookmarkleter](https://chriszarate.github.io/bookmarkleter/) + diff --git a/documentation/bookmark/css.md b/documentation/bookmark/css.md index 6a9301265..48f61e3e9 100644 --- a/documentation/bookmark/css.md +++ b/documentation/bookmark/css.md @@ -1,10 +1,10 @@ # Methodology -0. []() 0. [CUBE CSS](https://cube.fyi/) # Reference +0. [CSS-Only Type Grinding: Casting Tokens (sm|md|etc) into Useful Values](https://www.bitovi.com/blog/css-only-type-grinding-casting-tokens-into-useful-values) 0. [CSS Classes considered harmful](https://www.keithcirkel.co.uk/css-classes-considered-harmful/) 0. [Meet the top layer: a solution to z-index:10000](https://developer.chrome.com/blog/what-is-the-top-layer/) 0. [Not All Zeros are Equal: And every ‘best practice’ comes with caveats](https://www.oddbird.net/2022/08/04/zero-units/) diff --git a/documentation/bookmark/data/structure/probabilistic/cuckoo_filter.md b/documentation/bookmark/data/structure/probabilistic/cuckoo_filter.md new file mode 100644 index 000000000..0162b2a4b --- /dev/null +++ b/documentation/bookmark/data/structure/probabilistic/cuckoo_filter.md @@ -0,0 +1,5 @@ +# Reference + +0. [Cuckoo Filter: Practically Better Than Bloom](https://www.eecs.harvard.edu/~michaelm/postscripts/cuckoo-conext2014.pdf) +0. [Cuckoo Hashing and Cuckoo Filters](https://www.cs.toronto.edu/~noahfleming/CuckooHashing.pdf) + diff --git a/documentation/bookmark/database/local.md b/documentation/bookmark/database/local.md new file mode 100644 index 000000000..358a1b200 --- /dev/null +++ b/documentation/bookmark/database/local.md @@ -0,0 +1,4 @@ +# Reference + +0. [In Search of a Local-First Database](https://jaredforsyth.com/posts/in-search-of-a-local-first-database/) + diff --git a/documentation/bookmark/design/input.md b/documentation/bookmark/design/input.md index 23eefcbe9..e5a4aeaf9 100644 --- a/documentation/bookmark/design/input.md +++ b/documentation/bookmark/design/input.md @@ -1,5 +1,6 @@ # Reference -0. []() +0. [Pitfalls of debounced functions](https://www.shukantpal.com/blog/software/pitfalls-of-debounced-functions/) +0. [Should required fields be marked?](https://user-interface.io/should-required-fields-be-marked/) 0. [A WEB COMPONENT FOR MATH INPUT](https://cortexjs.io/mathlive/) diff --git a/documentation/bookmark/error/message.md b/documentation/bookmark/error/message.md index 62c93e8dd..b9c2af76b 100644 --- a/documentation/bookmark/error/message.md +++ b/documentation/bookmark/error/message.md @@ -1,5 +1,6 @@ # Reference +0. [When life gives you lemons, write better error messages: When it comes to error handling, it truly is a team sport](https://wix-ux.com/when-life-gives-you-lemons-write-better-error-messages-46c5223e1a2f) 0. [Rethinking errors, warnings, and lints](http://neugierig.org/software/blog/2022/01/rethinking-errors.html) 0. [Error Message Style Guides of Various Languages](https://www.pypy.org/posts/2021/12/error-message-style-guides.html) 0. [Error Messages in Haskell, and how to Improve them](https://anthony.noided.media/blog/haskell/programming/2020/05/14/haskell-errors.html) diff --git a/documentation/bookmark/game/platform/ps2__playstation_2.md b/documentation/bookmark/game/platform/ps2__playstation_2.md new file mode 100644 index 000000000..01eb7cb37 --- /dev/null +++ b/documentation/bookmark/game/platform/ps2__playstation_2.md @@ -0,0 +1,4 @@ +# Reference + +0. [Tyra: Open source game engine for PlayStation 2™](https://github.com/h4570/tyra) + diff --git a/documentation/bookmark/observability.md b/documentation/bookmark/observability.md new file mode 100644 index 000000000..29e9ab3a9 --- /dev/null +++ b/documentation/bookmark/observability.md @@ -0,0 +1,4 @@ +# Reference + +0. [jHiccup: a non-intrusive instrumentation tool that logs and records platform "hiccups"](https://github.com/giltene/jHiccup) + diff --git a/documentation/bookmark/optimization/condensation.md b/documentation/bookmark/optimization/condensation.md new file mode 100644 index 000000000..180120120 --- /dev/null +++ b/documentation/bookmark/optimization/condensation.md @@ -0,0 +1,4 @@ +# Reference + +0. [Selectively Shifting and Constraining Computation](https://openjdk.org/projects/leyden/notes/02-shift-and-constrain) + diff --git a/documentation/bookmark/optimization/low_level/x86.md b/documentation/bookmark/optimization/low_level/x86.md new file mode 100644 index 000000000..583649e28 --- /dev/null +++ b/documentation/bookmark/optimization/low_level/x86.md @@ -0,0 +1,4 @@ +# Reference + +0. [Optimizing subroutines in assembly language: An optimization guide for x86 platforms](https://www.agner.org/optimize/optimizing_assembly.pdf) + diff --git a/documentation/bookmark/paradigm/probabilistic_programming.md b/documentation/bookmark/paradigm/probabilistic_programming.md index f1a46d27b..5a03479e7 100644 --- a/documentation/bookmark/paradigm/probabilistic_programming.md +++ b/documentation/bookmark/paradigm/probabilistic_programming.md @@ -15,6 +15,7 @@ # Reference +0. [Lightweight Implementations of Probabilistic Programming Languages Via Transformational Compilation](https://proceedings.mlr.press/v15/wingate11a.html) 0. [Probabilistic programming with continuations](https://julesh.com/2020/08/15/probabilistic-programming-with-continuations/) 0. [Foundations of Probabilistic Programming](https://www.cambridge.org/core/books/foundations-of-probabilistic-programming/819623B1B5B33836476618AC0621F0EE) 0. [An unorthodox path for implementing a probabilistic programming language](http://hyperparameter.space/blog/an-unorthodox-path-for-implementing-a-probabilistic-programming-language/) diff --git a/documentation/bookmark/research/data.md b/documentation/bookmark/research/data.md new file mode 100644 index 000000000..cbc35f8c1 --- /dev/null +++ b/documentation/bookmark/research/data.md @@ -0,0 +1,4 @@ +# Reference + +0. [Academic Torrents](https://academictorrents.com/) + diff --git a/documentation/bookmark/security/ifc__information_flow_control.md b/documentation/bookmark/security/ifc__information_flow_control.md new file mode 100644 index 000000000..582021e80 --- /dev/null +++ b/documentation/bookmark/security/ifc__information_flow_control.md @@ -0,0 +1,5 @@ +# Reference + +0. [Language-Based Information-Flow Security](https://ifc-challenge.appspot.com/static/pdfs/jsac.pdf) +0. [Information Flow Control Challenge](https://ifc-challenge.appspot.com/) + diff --git a/documentation/bookmark/software/modifiability.md b/documentation/bookmark/software/modifiability.md new file mode 100644 index 000000000..48e707241 --- /dev/null +++ b/documentation/bookmark/software/modifiability.md @@ -0,0 +1,4 @@ +# Reference + +0. [An argument for self-modifying applications](https://macoy.me/blog/programming/SelfModifyingApplications) + diff --git a/documentation/bookmark/state_machine/behavior_tree.md b/documentation/bookmark/state_machine/behavior_tree.md new file mode 100644 index 000000000..a650c436c --- /dev/null +++ b/documentation/bookmark/state_machine/behavior_tree.md @@ -0,0 +1,4 @@ +# Reference + +0. [BehaviorTree.CPP](https://www.behaviortree.dev/) + diff --git a/stdlib/source/library/lux/data/color.lux b/stdlib/source/library/lux/data/color.lux index a0971891a..e2bd180f3 100644 --- a/stdlib/source/library/lux/data/color.lux +++ b/stdlib/source/library/lux/data/color.lux @@ -23,7 +23,8 @@ [/ ["[0]" rgb (.only RGB)]]) -(def top (-- rgb.limit)) +(def top + (-- rgb.limit)) (def rgb_factor (|> top .int int.frac)) diff --git a/stdlib/source/library/lux/data/color/terminal.lux b/stdlib/source/library/lux/data/color/terminal.lux new file mode 100644 index 000000000..1f368de0b --- /dev/null +++ b/stdlib/source/library/lux/data/color/terminal.lux @@ -0,0 +1,103 @@ +... https://en.wikipedia.org/wiki/ANSI_escape_code#Colors +(.require + [library + [lux (.except with) + [abstract + [equivalence (.only Equivalence)]] + [data + ["[0]" text (.use "[1]#[0]" equivalence) + ["[0]" char] + ["%" \\format]]] + [math + [number + ["n" nat]]] + [meta + [macro + ["[0]" template]] + [type + ["[0]" primitive]]]]] + ["[0]" // (.only Color) + ["[0]" rgb]]) + +(primitive.def .public Command + [Text Text] + + (def .public equivalence + (Equivalence Command) + (implementation + (def (= reference it) + (let [[beforeR afterR] (primitive.representation Command reference) + [beforeI afterI] (primitive.representation Command it)] + (and (text#= beforeR beforeI) + (text#= afterR afterI)))))) + + (def command + Text + (%.format (text.of_char char.escape) "[")) + + (def .public (with command text) + (-> Command Text + Text) + (let [[before after] (primitive.representation Command command)] + (%.format before + text + after))) + + (with_template [<code> <name>] + [(def <name> + Text + (%.format ..command (%.nat <code>) "m"))] + + [39 default_foreground_color] + [49 default_background_color] + ) + + (with_template [<fg> <bg> <color>] + [(`` (def .public (,, (template.symbol [<color> "_foreground"])) + Command + (|> [(%.format ..command (%.nat <fg>) "m") + ..default_foreground_color] + (primitive.abstraction Command)))) + + (`` (def .public (,, (template.symbol [<color> "_background"])) + Command + (|> [(%.format ..command (%.nat <bg>) "m") + ..default_background_color] + (primitive.abstraction Command))))] + + [030 040 black] + [031 041 red] + [032 042 green] + [033 043 yellow] + [034 044 blue] + [035 045 magenta] + [036 046 cyan] + [037 047 white] + + [090 100 bright_black] + [091 101 bright_red] + [092 102 bright_green] + [093 103 bright_yellow] + [094 104 bright_blue] + [095 105 bright_magenta] + [096 106 bright_cyan] + [097 107 bright_white] + ) + + (with_template [<command> <name> <reset>] + [(def .public (<name> it) + (-> Color Command) + (let [it (//.rgb it)] + (|> [(%.format ..command + <command> + ";" (%.nat (rgb.number (the rgb.#red it))) + ";" (%.nat (rgb.number (the rgb.#green it))) + ";" (%.nat (rgb.number (the rgb.#blue it))) + "m") + <reset>] + (primitive.abstraction Command))))] + + ["38;2" foreground ..default_foreground_color] + ["48;2" background ..default_background_color] + ) + ) diff --git a/stdlib/source/library/lux/meta/type/unit.lux b/stdlib/source/library/lux/meta/type/unit.lux index 4aa27fbfd..e4bf7a1e9 100644 --- a/stdlib/source/library/lux/meta/type/unit.lux +++ b/stdlib/source/library/lux/meta/type/unit.lux @@ -6,6 +6,9 @@ [equivalence (.only Equivalence)] [order (.only Order)] [enum (.only Enum)]] + [data + ["[0]" text (.only) + ["%" \\format]]] [math [number ["i" int]]] @@ -21,21 +24,27 @@ Int (def .public measure - (All (_ scale unit) (-> Int (Measure scale unit))) + (All (_ scale unit) + (-> Int + (Measure scale unit))) (|>> abstraction)) (def .public number - (All (_ scale unit) (-> (Measure scale unit) Int)) + (All (_ scale unit) + (-> (Measure scale unit) + Int)) (|>> representation)) (def .public equivalence - (All (_ scale unit) (Equivalence (Measure scale unit))) + (All (_ scale unit) + (Equivalence (Measure scale unit))) (implementation (def (= reference sample) (i.= (representation reference) (representation sample))))) (def .public order - (All (_ scale unit) (Order (Measure scale unit))) + (All (_ scale unit) + (Order (Measure scale unit))) (implementation (def equivalence ..equivalence) @@ -43,7 +52,8 @@ (i.< (representation reference) (representation sample))))) (def .public enum - (All (_ scale unit) (Enum (Measure scale unit))) + (All (_ scale unit) + (Enum (Measure scale unit))) (implementation (def order ..order) (def succ (|>> representation ++ abstraction)) @@ -51,7 +61,9 @@ (with_template [<name> <op>] [(def .public (<name> param subject) - (All (_ scale unit) (-> (Measure scale unit) (Measure scale unit) (Measure scale unit))) + (All (_ scale unit) + (-> (Measure scale unit) (Measure scale unit) + (Measure scale unit))) (abstraction (<op> (representation param) (representation subject))))] @@ -61,7 +73,9 @@ (with_template [<name> <op> <p> <s> <p*s>] [(def .public (<name> param subject) - (All (_ scale p s) (-> (Measure scale <p>) (Measure scale <s>) (Measure scale <p*s>))) + (All (_ scale p s) + (-> (Measure scale <p>) (Measure scale <s>) + (Measure scale <p*s>))) (abstraction (<op> (representation param) (representation subject))))] @@ -69,16 +83,24 @@ [/ i./ p [p s] s] ) - (.type .public (Unit a) + (.type .public (Unit of) (Interface - (is (-> Int (Measure Any a)) + (is (-> (Measure Any of) + Text) + format) + (is (-> Int + (Measure Any of)) in) - (is (-> (Measure Any a) Int) + (is (-> (Measure Any of) + Int) out))) - (def .public (unit _) - (Ex (_ a) (-> Any (Unit a))) + (def .public (unit descriptor) + (Ex (_ of) + (-> Text + (Unit of))) (implementation + (def format (|>> ..number %.int (text.suffix descriptor))) (def in ..measure) (def out ..number))) ) @@ -91,9 +113,9 @@ (, it)) (, g!a)))))))) -(with_template [<unit> <type>] +(with_template [<descriptor> <unit> <type>] [(def .public <unit> - (..unit [])) + (..unit <descriptor>)) (.def .public <type> (let [[module _] (symbol .._) @@ -101,8 +123,8 @@ {.#Named [module short] (..type <unit>)}))] - [gram Gram] - [meter Meter] - [litre Litre] - [second Second] + ["g" gram Gram] + ["m" meter Meter] + ["l" litre Litre] + ["s" second Second] ) diff --git a/stdlib/source/library/lux/test/unit.lux b/stdlib/source/library/lux/test/unit.lux index 86df9efd0..e8eeb0a04 100644 --- a/stdlib/source/library/lux/test/unit.lux +++ b/stdlib/source/library/lux/test/unit.lux @@ -10,6 +10,8 @@ [concurrency ["[0]" async (.only Async) (.use "[1]#[0]" monad)]]] [data + [color + ["[0]" terminal]] ["[0]" text (.only) ["%" \\format (.only format)]] [collection @@ -60,10 +62,13 @@ (-> Text Test Test) (|>> %.text context')) -(with_template [<prefix> <tally> <raw> <quoted>] +(with_template [<prefix> <tally> <raw> <quoted> <foreground>] [(def <raw> (-> Text Test) - (|>> (format <prefix>) + (|>> (format "[" + (terminal.with <foreground> + <prefix>) + "] ") [<tally>] async#in)) @@ -71,8 +76,8 @@ (-> Text Test) (|>> %.text <raw>))] - ["[Failure] " tally.failure failure' failure] - ["[Success] " tally.success success' success] + ["Failure" tally.failure failure' failure terminal.red_foreground] + ["Success" tally.success success' success terminal.green_foreground] ) (def (test' message condition) diff --git a/stdlib/source/library/lux/world/console.lux b/stdlib/source/library/lux/world/console.lux index 37d8b3b07..4d3ba46d8 100644 --- a/stdlib/source/library/lux/world/console.lux +++ b/stdlib/source/library/lux/world/console.lux @@ -40,7 +40,8 @@ [read] [read_line] [write] - [close]))))) + [close] + ))))) (exception.def .public cannot_close) diff --git a/stdlib/source/library/lux/world/logging.lux b/stdlib/source/library/lux/world/logging.lux new file mode 100644 index 000000000..6f58fd134 --- /dev/null +++ b/stdlib/source/library/lux/world/logging.lux @@ -0,0 +1,66 @@ +(.require + [library + [lux (.except with) + [abstract + [monad (.only Monad do)]] + [control + ["[0]" try (.only Try)]] + [data + [color + ["[0]" terminal]] + [text + ["%" \\format]]] + [world + ["[0]" console (.only Console)] + [time + [instant (.only Instant)]]]]]) + +(type .public (Logger !) + (Interface + (is (-> Text + (! (Try Any))) + log))) + +(with_template [<prefix> <name> <foreground>] + [(def .public (<name> message it) + (All (_ !) + (-> Text (Logger !) + (! (Try Any)))) + (at it log (terminal.with <foreground> + (%.format <prefix> message))))] + + ["[ERROR] " error terminal.red_foreground] + ["[WARNING] " warn terminal.yellow_foreground] + ["[INFO] " info terminal.white_foreground] + ["[DEBUG] " debug terminal.cyan_foreground] + ) + +(def .public (with scope it) + (All (_ !) + (-> (-> Text Text) + (-> (Logger !) (Logger !)))) + (implementation + (def log + (|>> scope + (at it log))))) + +(def .public (timed ! now it) + (All (_ !) + (-> (Monad !) (-> Any (! Instant)) + (-> (Logger !) (Logger !)))) + (implementation + (def (log message) + (do ! + [now (now [])] + (at it log (%.format (terminal.with terminal.green_foreground + (%.format "[" (%.instant now) "]")) + " " + message)))))) + +(def .public (console it) + (All (_ !) + (-> (Console !) + (Logger !))) + (implementation + (def (log message) + (console.write_line message it)))) diff --git a/stdlib/source/test/lux/control/try.lux b/stdlib/source/test/lux/control/try.lux index ff8fe9455..7b2ec5918 100644 --- a/stdlib/source/test/lux/control/try.lux +++ b/stdlib/source/test/lux/control/try.lux @@ -40,7 +40,8 @@ (def .public test Test (<| (_.covering /._) - (_.for [/.Try]) + (_.for [/.Try + /.#Failure /.#Success]) (do random.monad [expected random.nat alternative (|> random.nat (random.only (|>> (n.= expected) not))) diff --git a/stdlib/source/test/lux/data/color.lux b/stdlib/source/test/lux/data/color.lux index c56352d3d..e53d5d0b7 100644 --- a/stdlib/source/test/lux/data/color.lux +++ b/stdlib/source/test/lux/data/color.lux @@ -24,7 +24,8 @@ ["[0]" rgb]]] ["[0]" / ["[1][0]" rgb] - ["[1][0]" named]]) + ["[1][0]" named] + ["[1][0]" terminal]]) (def .public random (Random /.Color) @@ -217,4 +218,5 @@ /rgb.test /named.test + /terminal.test )))) diff --git a/stdlib/source/test/lux/data/color/rgb.lux b/stdlib/source/test/lux/data/color/rgb.lux index 5781c9efa..c0d329631 100644 --- a/stdlib/source/test/lux/data/color/rgb.lux +++ b/stdlib/source/test/lux/data/color/rgb.lux @@ -75,7 +75,8 @@ {try.#Failure it} (exception.match? /.invalid it) {try.#Success _} false))) )) - (_.for [/.RGB] + (_.for [/.RGB + /.#red /.#green /.#blue] (all _.and (_.for [/.equivalence] (equivalenceS.spec /.equivalence ..random)) diff --git a/stdlib/source/test/lux/data/color/terminal.lux b/stdlib/source/test/lux/data/color/terminal.lux new file mode 100644 index 000000000..a22173fbf --- /dev/null +++ b/stdlib/source/test/lux/data/color/terminal.lux @@ -0,0 +1,102 @@ +(.require + [library + [lux (.except) + [abstract + [monad (.only do)] + [\\specification + ["[0]S" equivalence]]] + [data + ["[0]" text (.use "[1]#[0]" equivalence)] + [collection + ["[0]" list]]] + [math + ["[0]" random (.only Random) (.use "[1]#[0]" monad)]] + [test + ["_" property (.only Test)]]]] + [\\library + ["[0]" / (.only) + ["/[1]" //]]] + [// + ["[0]T" rgb]]) + +(with_expansions [<commands> (these [/.black_foreground] + [/.red_foreground] + [/.green_foreground] + [/.yellow_foreground] + [/.blue_foreground] + [/.magenta_foreground] + [/.cyan_foreground] + [/.white_foreground] + [/.bright_black_foreground] + [/.bright_red_foreground] + [/.bright_green_foreground] + [/.bright_yellow_foreground] + [/.bright_blue_foreground] + [/.bright_magenta_foreground] + [/.bright_cyan_foreground] + [/.bright_white_foreground] + + [/.black_background] + [/.red_background] + [/.green_background] + [/.yellow_background] + [/.blue_background] + [/.magenta_background] + [/.cyan_background] + [/.white_background] + [/.bright_black_background] + [/.bright_red_background] + [/.bright_green_background] + [/.bright_yellow_background] + [/.bright_blue_background] + [/.bright_magenta_background] + [/.bright_cyan_background] + [/.bright_white_background] + )] + (def .public random + (Random /.Command) + (`` (all random.either + (random#each (|>> //.of_rgb /.foreground) rgbT.random) + (random#each (|>> //.of_rgb /.background) rgbT.random) + (,, (with_template [<command>] + [(random#in <command>)] + + <commands> + )) + ))) + + (def .public test + Test + (<| (_.covering /._) + (do [! random.monad] + [color (random#each //.of_rgb rgbT.random) + command ..random + expected_text (random.upper_cased 3)]) + (_.for [/.Command]) + (all _.and + (_.for [/.equivalence] + (equivalenceS.spec /.equivalence ..random)) + + (_.coverage [/.with] + (let [it (/.with command + expected_text)] + (and (text.contains? expected_text it) + (not (text#= expected_text it))))) + (_.coverage [/.foreground /.background] + (not (at /.equivalence = + (/.foreground color) + (/.background color)))) + (`` (_.coverage [(,, (with_template [<command>] + [<command>] + + <commands>))] + (loop (again [commands (list <commands>)]) + (when commands + {.#End} + true + + {.#Item head tail} + (and (list.every? (|>> (at /.equivalence = head) not) tail) + (again tail)))))) + ))) + ) diff --git a/stdlib/source/test/lux/meta/type/unit.lux b/stdlib/source/test/lux/meta/type/unit.lux index c31abd6b0..734400ade 100644 --- a/stdlib/source/test/lux/meta/type/unit.lux +++ b/stdlib/source/test/lux/meta/type/unit.lux @@ -8,10 +8,16 @@ ["$[0]" equivalence] ["$[0]" order] ["$[0]" enum]]] + [data + ["[0]" text (.use "[1]#[0]" equivalence) + ["%" \\format]]] [math ["[0]" random (.only Random)] [number ["i" int]]] + [meta + ["[0]" static] + ["[0]" code]] [test ["_" property (.only Test)]]]] [\\library @@ -42,39 +48,51 @@ ($enum.spec /.enum (..meter 1,000))) )) -(def what (/.unit [])) -(def What (/.type what)) +(with_expansions [<descriptor> (static.random code.text + (random.upper_cased 1))] + (def what (/.unit <descriptor>)) + (def What (/.type what)) -(def unit - Test - (do random.monad - [expected random.int] - (_.for [/.Unit] - (`` (all _.and - (,, (with_template [<type> <unit>] - [(_.coverage [<type> <unit>] - (|> expected - (at <unit> in) - (at <unit> out) - (i.= expected)))] + (def unit + Test + (do random.monad + [expected random.int] + (_.for [/.Unit] + (`` (all _.and + (,, (with_template [<type> <unit>] + [(_.coverage [<type> <unit>] + (and (|> expected + (at <unit> in) + (at <unit> out) + (i.= expected)) + (let [it (|> expected + (at <unit> in) + (at <unit> format))] + (and (not (text#= (%.int expected) it)) + (text.starts_with? (%.int expected) it)))))] - [/.Gram /.gram] - [/.Meter /.meter] - [/.Litre /.litre] - [/.Second /.second] - )) - (_.coverage [/.measure /.number] - (|> expected - /.measure - /.number - (i.= expected))) - (_.coverage [/.unit /.type] - (|> expected - (at ..what in) - (is (/.Measure Any What)) - (at ..what out) - (i.= expected))) - ))))) + [/.Gram /.gram] + [/.Meter /.meter] + [/.Litre /.litre] + [/.Second /.second] + )) + (_.coverage [/.measure /.number] + (|> expected + /.measure + /.number + (i.= expected))) + (_.coverage [/.unit /.type] + (and (|> expected + (at ..what in) + (is (/.Measure Any What)) + (at ..what out) + (i.= expected)) + (let [it (|> expected + (at ..what in) + (at ..what format))] + (and (text.contains? (%.int expected) it) + (text.contains? <descriptor> it))))) + )))))) (def arithmetic Test diff --git a/stdlib/source/test/lux/world.lux b/stdlib/source/test/lux/world.lux index 2229ef10e..bfd4710b7 100644 --- a/stdlib/source/test/lux/world.lux +++ b/stdlib/source/test/lux/world.lux @@ -15,7 +15,8 @@ ["[1]/[0]" resolution]]] ["[1][0]" net] ["[1][0]" time] - ["[1][0]" locale]]) + ["[1][0]" locale] + ["[1][0]" logging]]) (def .public test Test @@ -29,4 +30,5 @@ /net.test /time.test /locale.test + /logging.test )) diff --git a/stdlib/source/test/lux/world/logging.lux b/stdlib/source/test/lux/world/logging.lux new file mode 100644 index 000000000..f2d56ff15 --- /dev/null +++ b/stdlib/source/test/lux/world/logging.lux @@ -0,0 +1,119 @@ +(.require + [library + [lux (.except) + [abstract + [monad (.only do)]] + [control + ["[0]" try] + [concurrency + ["[0]" async (.only Async) (.use "[1]#[0]" monad)]]] + [data + ["[0]" text (.use "[1]#[0]" equivalence) + ["%" \\format]]] + [math + ["[0]" random (.only Random)]] + [test + ["_" property (.only Test)] + ["[0]" unit]]]] + [\\library + ["[0]" / (.only) + [// + ["[0]" console]]]]) + +(def mock + (console.Mock Text) + (implementation + (def (on_read _) + {try.#Failure ""}) + (def (on_read_line feed) + (when (text.split_by text.\n feed) + {.#Some [line rest]} + {try.#Success [rest line]} + + {.#None} + {try.#Failure ""})) + (def (on_write line state) + {try.#Success (%.format state line)}) + (def (on_close _) + {try.#Failure ""}))) + +(def .public test + Test + (<| (_.covering /._) + (do [! random.monad] + [expected_message (random.upper_cased 3) + expected_appendix (random.lower_cased 3) + expected_instant random.instant]) + (_.for [/.Logger]) + (`` (all _.and + (let [console (console.async (console.mock ..mock "")) + it (/.console console)] + (in (do async.monad + [logged? (at it log expected_message) + actual_message (at console read_line [])] + (unit.coverage [/.console /.log] + (when [logged? actual_message] + [{try.#Success _} + {try.#Success actual_message}] + (text#= expected_message actual_message) + + _ + false))))) + (,, (with_template [<level>] + [(let [console (console.async (console.mock ..mock "")) + it (/.console console)] + (in (do async.monad + [logged? (<level> expected_message it) + actual_message (at console read_line [])] + (unit.coverage [<level>] + (when [logged? actual_message] + [{try.#Success _} + {try.#Success actual_message}] + (and (not (text#= expected_message actual_message)) + (text.contains? expected_message actual_message)) + + _ + false)))))] + + [/.error] + [/.warn] + [/.info] + [/.debug] + )) + (let [console (console.async (console.mock ..mock "")) + it (is (/.Logger Async) + (/.with (text.suffix expected_appendix) + (/.console console)))] + (in (do async.monad + [logged? (at it log expected_message) + actual_message (at console read_line [])] + (unit.coverage [/.with] + (when [logged? actual_message] + [{try.#Success _} + {try.#Success actual_message}] + (text#= (text.suffix expected_appendix expected_message) + actual_message) + + _ + false))))) + (let [console (console.async (console.mock ..mock "")) + it (is (/.Logger Async) + (/.timed async.monad + (function (_ _) + (async#in expected_instant)) + (/.console console)))] + (in (do async.monad + [logged? (at it log expected_message) + actual_message (at console read_line [])] + (unit.coverage [/.timed] + (when [logged? actual_message] + [{try.#Success _} + {try.#Success actual_message}] + (and (text.contains? expected_message + actual_message) + (text.contains? (%.instant expected_instant) + actual_message)) + + _ + false))))) + )))) diff --git a/stdlib/source/test/lux/world/net/http/request.lux b/stdlib/source/test/lux/world/net/http/request.lux index afc7e88ad..fb30692d0 100644 --- a/stdlib/source/test/lux/world/net/http/request.lux +++ b/stdlib/source/test/lux/world/net/http/request.lux @@ -44,6 +44,15 @@ (_.for [/.Request /.#identification /.#message /.#protocol /.#resource]) (`` (all _.and + (_.coverage [/.Identification + /.#local /.#remote] + true) + (_.coverage [/.Protocol + /.#version /.#scheme] + true) + (_.coverage [/.Resource + /.#method /.#uri] + true) (_.coverage [/.utf8 /.text] (and (same? /.utf8 /.text) (let [it (/.utf8 identity.monad expected_text)] |