aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--documentation/bookmark/analysis/static/separation_logic.md4
-rw-r--r--documentation/bookmark/bookmarklet.md4
-rw-r--r--documentation/bookmark/css.md2
-rw-r--r--documentation/bookmark/data/structure/probabilistic/cuckoo_filter.md5
-rw-r--r--documentation/bookmark/database/local.md4
-rw-r--r--documentation/bookmark/design/input.md3
-rw-r--r--documentation/bookmark/error/message.md1
-rw-r--r--documentation/bookmark/game/platform/ps2__playstation_2.md4
-rw-r--r--documentation/bookmark/observability.md4
-rw-r--r--documentation/bookmark/optimization/condensation.md4
-rw-r--r--documentation/bookmark/optimization/low_level/x86.md4
-rw-r--r--documentation/bookmark/paradigm/probabilistic_programming.md1
-rw-r--r--documentation/bookmark/research/data.md4
-rw-r--r--documentation/bookmark/security/ifc__information_flow_control.md5
-rw-r--r--documentation/bookmark/software/modifiability.md4
-rw-r--r--documentation/bookmark/state_machine/behavior_tree.md4
-rw-r--r--stdlib/source/library/lux/data/color.lux3
-rw-r--r--stdlib/source/library/lux/data/color/terminal.lux103
-rw-r--r--stdlib/source/library/lux/meta/type/unit.lux58
-rw-r--r--stdlib/source/library/lux/test/unit.lux13
-rw-r--r--stdlib/source/library/lux/world/console.lux3
-rw-r--r--stdlib/source/library/lux/world/logging.lux66
-rw-r--r--stdlib/source/test/lux/control/try.lux3
-rw-r--r--stdlib/source/test/lux/data/color.lux4
-rw-r--r--stdlib/source/test/lux/data/color/rgb.lux3
-rw-r--r--stdlib/source/test/lux/data/color/terminal.lux102
-rw-r--r--stdlib/source/test/lux/meta/type/unit.lux80
-rw-r--r--stdlib/source/test/lux/world.lux4
-rw-r--r--stdlib/source/test/lux/world/logging.lux119
-rw-r--r--stdlib/source/test/lux/world/net/http/request.lux9
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)]