From 6b4a53e68bf3155c61e83d0d71822d8daec4fae1 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Mon, 17 Feb 2025 05:34:47 -0400 Subject: [PATCH] Improving test coverage [part 9] --- README.md | 2 +- documentation/bookmark/agriculture.md | 2 +- documentation/bookmark/business/funding.md | 1 + .../compilation/target/wasm__web_assembly.md | 2 +- documentation/bookmark/database.md | 2 +- documentation/bookmark/economics/taxation.md | 4 + documentation/bookmark/name.md | 4 + documentation/bookmark/open_source/funding.md | 2 + .../bookmark/open_source/maintenance.md | 4 + .../bookmark/os__operating_system/android.md | 4 + documentation/bookmark/quality.md | 4 + documentation/bookmark/research.md | 1 + documentation/bookmark/testing/contract.md | 5 + lux-mode/lux-mode.el | 2 +- stdlib/source/library/lux.lux | 12 +- .../library/lux/abstract/functor/pro.lux | 20 +- .../lux/compiler/language/lux/syntax.lux | 4 +- .../library/lux/control/concatenative.lux | 1 + stdlib/source/library/lux/function.lux | 20 +- stdlib/source/library/lux/logic/bit.lux | 1 + stdlib/source/library/lux/meta/binding.lux | 49 ++--- .../library/lux/world/net/http/client.lux | 14 +- stdlib/source/test/lux.lux | 5 +- stdlib/source/test/lux/abstract/functor.lux | 7 +- .../source/test/lux/abstract/functor/pro.lux | 207 +++++++++++++++++- .../lux/compiler/language/lux/analysis.lux | 75 +++++-- .../language/lux/analysis/complex.lux | 1 - .../compiler/language/lux/phase/extension.lux | 9 +- .../test/lux/compiler/language/lux/syntax.lux | 85 ++++++- stdlib/source/test/lux/compiler/type.lux | 2 +- stdlib/source/test/lux/data/text.lux | 21 +- stdlib/source/test/lux/debug.lux | 126 ++++++----- stdlib/source/test/lux/function.lux | 47 ++-- stdlib/source/test/lux/macro/syntax.lux | 34 +-- stdlib/source/test/lux/meta/binding.lux | 2 + stdlib/source/test/lux/meta/binding/local.lux | 3 + 36 files changed, 593 insertions(+), 191 deletions(-) create mode 100644 documentation/bookmark/economics/taxation.md create mode 100644 documentation/bookmark/name.md create mode 100644 documentation/bookmark/open_source/maintenance.md create mode 100644 documentation/bookmark/os__operating_system/android.md create mode 100644 documentation/bookmark/quality.md create mode 100644 documentation/bookmark/testing/contract.md diff --git a/README.md b/README.md index 200f8938d9..72bcf3c433 100644 --- a/README.md +++ b/README.md @@ -108,4 +108,4 @@ I'll be putting there tasks that people can contribute to; both in the compiler Writing libraries in Lux will also help a lot in making this a more practical language for day to day use. -##### Copyright (c) 2014-2024 Eduardo Emilio Julián Pereyra. All rights reserved. +##### Copyright (c) 2014-2025 Eduardo Emilio Julián Pereyra. All rights reserved. diff --git a/documentation/bookmark/agriculture.md b/documentation/bookmark/agriculture.md index 14ccda9ff1..afecfbb63e 100644 --- a/documentation/bookmark/agriculture.md +++ b/documentation/bookmark/agriculture.md @@ -1,6 +1,6 @@ # Reference -0. []() +0. [Top Farm Robots](https://www.topfarmrobots.com/) 0. [Soil.Spectroscopy](https://soilspectroscopy.org/) 0. [Agrivoltaics: Opportunities for Agriculture and Energy Transition](https://agri-pv.org/en/) diff --git a/documentation/bookmark/business/funding.md b/documentation/bookmark/business/funding.md index 4762c7ea28..2432d81bda 100644 --- a/documentation/bookmark/business/funding.md +++ b/documentation/bookmark/business/funding.md @@ -1,4 +1,5 @@ # Reference +0. [A different way to fund freedom-respecting software](https://contrapunctus.codeberg.page/blog/a-different-way-to-fund-freedom-respecting-software.html) 0. [More money if you do, more money if you don’t](https://longform.asmartbear.com/more-money/) diff --git a/documentation/bookmark/compilation/target/wasm__web_assembly.md b/documentation/bookmark/compilation/target/wasm__web_assembly.md index d6be39bd4c..c195590723 100644 --- a/documentation/bookmark/compilation/target/wasm__web_assembly.md +++ b/documentation/bookmark/compilation/target/wasm__web_assembly.md @@ -1,6 +1,5 @@ # Interoperability -0. []() 0. [How to Extend WebAssembly with Host Functions](https://www.secondstate.io/articles/extend-webassembly/) 0. [js-wasm: JavaScript and WebAssembly should be a joy to use together.](https://wasm.js.org/) @@ -31,6 +30,7 @@ 0. [The best WebAssembly runtime may be no runtime at all](https://00f.net/2023/12/11/webassembly-compilation-to-c/) 0. [just-in-time code generation within webassembly](https://wingolog.org/archives/2022/08/18/just-in-time-code-generation-within-webassembly) 0. [TeaVM: Build Fast, Modern Web Apps in Java](https://teavm.org/) + 0. [Release 0.11.0: New WebAssembly backend](https://teavm.org/docs/release-notes/0.11.0.html) 0. [Recommendations when publishing a Wasm library](https://nickb.dev/blog/recommendations-when-publishing-a-wasm-library) 0. [Building host implementations for WebAssembly interfaces](https://radu-matei.com/blog/wasm-components-host-implementations/) 0. [WebAssembly Techniques to Speed Up Matrix Multiplication by 120x](https://jott.live/markdown/mm_wasm) diff --git a/documentation/bookmark/database.md b/documentation/bookmark/database.md index d903456339..d1d88ec51b 100644 --- a/documentation/bookmark/database.md +++ b/documentation/bookmark/database.md @@ -10,7 +10,7 @@ # Reference -0. []() +0. [Awesome Identifiers: Pick the best database primary key](https://adileo.github.io/awesome-identifiers/) 0. [The Slotted Counter Pattern](https://planetscale.com/blog/the-slotted-counter-pattern) 0. ["Temporal Databases for Streaming Architectures" by Jeremy Taylor and Jon Pither](https://www.youtube.com/watch?v=ykbYNBE-V3k) 0. ["Makings of a Modern ACID Compliant Distributed Database" by Attila Szegedi](https://www.youtube.com/watch?v=pn8mCeX3LDE) diff --git a/documentation/bookmark/economics/taxation.md b/documentation/bookmark/economics/taxation.md new file mode 100644 index 0000000000..3d7a699887 --- /dev/null +++ b/documentation/bookmark/economics/taxation.md @@ -0,0 +1,4 @@ +# Reference + +0. [Correcting the Top 10 Tax Myths](https://manhattan.institute/article/correcting-the-top-10-tax-myths) + diff --git a/documentation/bookmark/name.md b/documentation/bookmark/name.md new file mode 100644 index 0000000000..2827a74b62 --- /dev/null +++ b/documentation/bookmark/name.md @@ -0,0 +1,4 @@ +# Reference + +0. [Naming Conventions That Need to Die](https://willcrichton.net/notes/naming-conventions-that-need-to-die/) + diff --git a/documentation/bookmark/open_source/funding.md b/documentation/bookmark/open_source/funding.md index 20e5436ddf..a8ea7f910a 100644 --- a/documentation/bookmark/open_source/funding.md +++ b/documentation/bookmark/open_source/funding.md @@ -1,5 +1,7 @@ # Reference +0. [ecosyste.ms](https://funds.ecosyste.ms/) +0. [thanks.dev](https://thanks.dev/home) 0. [Drips: a decentralized toolkit for rewarding open source projects within your ecosystem](https://www.drips.network/) 0. [Sustain: Holding a space for conversations about sustaining Open Source](https://sustainoss.org/) 0. [Awesome OSS Monetization v1.1](https://github.com/PayDevs/awesome-oss-monetization) diff --git a/documentation/bookmark/open_source/maintenance.md b/documentation/bookmark/open_source/maintenance.md new file mode 100644 index 0000000000..e82574bf04 --- /dev/null +++ b/documentation/bookmark/open_source/maintenance.md @@ -0,0 +1,4 @@ +# Reference + +0. [Do Not Fix Bugs Reported in Your Open Source Projects](https://code.dblock.org/2024/12/19/do-not-fix-bugs-reported-in-your-open-source-projects.html) + diff --git a/documentation/bookmark/os__operating_system/android.md b/documentation/bookmark/os__operating_system/android.md new file mode 100644 index 0000000000..4d2ad0410a --- /dev/null +++ b/documentation/bookmark/os__operating_system/android.md @@ -0,0 +1,4 @@ +# Reference + +0. [Android Debug Bridge (ADB) Commands: A comprehensive guide to ADB commands for Android development, debugging, and device management](https://www.adb-command.top/) + diff --git a/documentation/bookmark/quality.md b/documentation/bookmark/quality.md new file mode 100644 index 0000000000..fb744b6e48 --- /dev/null +++ b/documentation/bookmark/quality.md @@ -0,0 +1,4 @@ +# Reference + +0. [Most people don't care about quality](https://shkspr.mobi/blog/2024/12/most-people-dont-care-about-quality/) + diff --git a/documentation/bookmark/research.md b/documentation/bookmark/research.md index 119702b13d..7cd38f7ca5 100644 --- a/documentation/bookmark/research.md +++ b/documentation/bookmark/research.md @@ -1,4 +1,5 @@ # Reference +0. [Software Papers as Software Modules: Towards a Culture of Reusable Results](https://github.com/andreas-zeller/papers-as-modules) 0. [ResearchRabbit](https://researchrabbitapp.com/) diff --git a/documentation/bookmark/testing/contract.md b/documentation/bookmark/testing/contract.md new file mode 100644 index 0000000000..748bd5eceb --- /dev/null +++ b/documentation/bookmark/testing/contract.md @@ -0,0 +1,5 @@ +# Reference + +0. [test.contract](https://github.com/griffinbank/test.contract) + 0. ["Breaking the bank with test contract" by Allen Rohner](https://youtu.be/dvHASrrQSzg) + diff --git a/lux-mode/lux-mode.el b/lux-mode/lux-mode.el index d13f8494d3..77e920c03f 100644 --- a/lux-mode/lux-mode.el +++ b/lux-mode/lux-mode.el @@ -1,6 +1,6 @@ ;;; lux-mode.el --- Major mode for Lux code -*- lexical-binding: t; -*- -;; Copyright © 2014-2022 Eduardo Julian +;; Copyright © 2014-2025 Eduardo Julian ;; ;; Authors: Eduardo Julian ;; URL: https://github.com/LuxLang/lux/tree/master/lux-mode diff --git a/stdlib/source/library/lux.lux b/stdlib/source/library/lux.lux index 36c7bd0550..8ef36c55a4 100644 --- a/stdlib/source/library/lux.lux +++ b/stdlib/source/library/lux.lux @@ -3220,13 +3220,17 @@ size (let' [interpositions (.i64_-# 1 size) - new_size (.i64_+# interpositions size)] + new_size (.i64_+# interpositions size) + last_item (.i64_-# 1 new_size)] (|> it (list:mix' (function' (_ address item it) (let' [address (.i64_+# address address)] - (|> it - (.array_has# address item) - (.array_has# (.i64_+# 1 address) delimiter)))) + (if (.i64_=# last_item address) + (|> it + (.array_has# address item)) + (|> it + (.array_has# address item) + (.array_has# (.i64_+# 1 address) delimiter))))) (.array# new_size)) (.as# (for_any (_ it) (-> ($ Array it) diff --git a/stdlib/source/library/lux/abstract/functor/pro.lux b/stdlib/source/library/lux/abstract/functor/pro.lux index 7bdc4f695e..dd1ebe3f10 100644 --- a/stdlib/source/library/lux/abstract/functor/pro.lux +++ b/stdlib/source/library/lux/abstract/functor/pro.lux @@ -14,27 +14,27 @@ (=> cause' effect')))) each))) -(every .public (Cartesian =>) +(every .public (Co_Cartesian =>) (Interface (is (for_any (_ head head' tail) (-> (=> head head') - (=> (And head tail) (And head' tail)))) - in_left) + (=> (Or head tail) (Or head' tail)))) + when_left) (is (for_any (_ tail tail' head) (-> (=> tail tail') - (=> (And head tail) (And head tail')))) - in_right))) + (=> (Or head tail) (Or head tail')))) + when_right))) -(every .public (Co_Cartesian =>) +(every .public (Cartesian =>) (Interface (is (for_any (_ head head' tail) (-> (=> head head') - (=> (Or head tail) (Or head' tail)))) - when_left) + (=> (And head tail) (And head' tail)))) + in_left) (is (for_any (_ tail tail' head) (-> (=> tail tail') - (=> (Or head tail) (Or head tail')))) - when_right))) + (=> (And head tail) (And head tail')))) + in_right))) (every .public (Monoidal =>) (Interface diff --git a/stdlib/source/library/lux/compiler/language/lux/syntax.lux b/stdlib/source/library/lux/compiler/language/lux/syntax.lux index 595d5f9fa3..2dc8335629 100644 --- a/stdlib/source/library/lux/compiler/language/lux/syntax.lux +++ b/stdlib/source/library/lux/compiler/language/lux/syntax.lux @@ -462,12 +462,12 @@ [(!letE [source' full_name] (..full_name_projection the_globals aliases offset source) (..success source' {tag where full_name}))])) - (error.the .public error_of_natural_is_not_valid) + (error.the .public not_a_number) (the (natural_is_not_valid the_globals @) (-> types_of_the_globals (Projection Natural)) - (..failure @ ..error_of_natural_is_not_valid)) + (..failure @ ..not_a_number)) (template.with [,format ,name ,predicate ,suffix ,parent] [(the (,name the_globals @) diff --git a/stdlib/source/library/lux/control/concatenative.lux b/stdlib/source/library/lux/control/concatenative.lux index 58c24f121b..97991669a8 100644 --- a/stdlib/source/library/lux/control/concatenative.lux +++ b/stdlib/source/library/lux/control/concatenative.lux @@ -1,6 +1,7 @@ ... This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. ... If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +... "Techniques for embedding postfix languages in Haskell" by Chris Okasaki (.using [library [lux (.except Alias Stack diff --git a/stdlib/source/library/lux/function.lux b/stdlib/source/library/lux/function.lux index 6a0f6b2752..0cbbe59f0c 100644 --- a/stdlib/source/library/lux/function.lux +++ b/stdlib/source/library/lux/function.lux @@ -52,16 +52,6 @@ (the (each before after it) (|>> before it after)))) -(the .public cartesian - (pro.Cartesian Function) - (implementation - (the (in_left it) - (function (_ [cause extra]) - [(it cause) extra])) - (the (in_right it) - (function (_ [extra cause]) - [extra (it cause)])))) - (the .public co_cartesian (pro.Co_Cartesian Function) (implementation @@ -74,6 +64,16 @@ {0b left} {0b left} {1b right} {1b (it right)})))) +(the .public cartesian + (pro.Cartesian Function) + (implementation + (the (in_left it) + (function (_ [cause extra]) + [(it cause) extra])) + (the (in_right it) + (function (_ [extra cause]) + [extra (it cause)])))) + (the .public monoidal (pro.Monoidal Function) (implementation diff --git a/stdlib/source/library/lux/logic/bit.lux b/stdlib/source/library/lux/logic/bit.lux index dea131521e..9964a766e4 100644 --- a/stdlib/source/library/lux/logic/bit.lux +++ b/stdlib/source/library/lux/logic/bit.lux @@ -1,6 +1,7 @@ ... This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. ... If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +... https://en.wikipedia.org/wiki/Boolean_algebra (.using [library [lux (.except text) diff --git a/stdlib/source/library/lux/meta/binding.lux b/stdlib/source/library/lux/meta/binding.lux index 174414b1a7..2b2ba3ad8f 100644 --- a/stdlib/source/library/lux/meta/binding.lux +++ b/stdlib/source/library/lux/meta/binding.lux @@ -141,31 +141,26 @@ else false)) -(with_template [] - [(the .public ( name) - (-> Name - (Meta [Bit Global])) - (monad.let //.monad - [name (..normal name) - .let [[normal_module normal_proper] name]] - (function (_ lux) - (when (is (Maybe [Bit Global]) - (monad.let maybe.monad - [it (|> lux - (its .:modules) - (property.value normal_module))] - (|> it - (its .:definitions) - (property.value normal_proper)))) - {.:Some exported?,definition} - {try.:Success [lux exported?,definition]} - - _ - {try.:Failure (..not_known lux name)}))))] - - [[definition] - [default'] - [alias']]) +(the .public (definition name) + (-> Name + (Meta [Bit Global])) + (monad.let //.monad + [name (..normal name) + .let [[normal_module normal_proper] name]] + (function (_ lux) + (when (is (Maybe [Bit Global]) + (monad.let maybe.monad + [it (|> lux + (its .:modules) + (property.value normal_module))] + (|> it + (its .:definitions) + (property.value normal_proper)))) + {.:Some exported?,definition} + {try.:Success [lux exported?,definition]} + + _ + {try.:Failure (..not_known lux name)})))) (the .public (export name) (-> Name @@ -196,7 +191,7 @@ (Meta Definition)) (monad.let [! //.monad] [name (..normal name) - [exported? definition] (..default' name)] + [exported? definition] (..definition name)] (when definition {.:Definition it} (if (default? (product.left it)) @@ -220,7 +215,7 @@ (Meta Name)) (monad.let [! //.monad] [name (..normal name) - [exported? it] (..alias' name)] + [exported? it] (..definition name)] (when it {.:Alias it} (pure it) diff --git a/stdlib/source/library/lux/world/net/http/client.lux b/stdlib/source/library/lux/world/net/http/client.lux index b6c9ff2a98..3ccdbc3bfc 100644 --- a/stdlib/source/library/lux/world/net/http/client.lux +++ b/stdlib/source/library/lux/world/net/http/client.lux @@ -121,7 +121,8 @@ (ffi.the java/net/HttpURLConnection "[1]:[0]" (setRequestMethod [java/lang/String] "io" "try" void) - (getResponseCode [] "io" "try" int)) + (getResponseCode [] "io" "try" int) + (getErrorStream [] "io" "try" java/io/InputStream)) (ffi.the java/net/URL "[1]:[0]" @@ -227,11 +228,14 @@ {.:None} (pure [])) status (java/net/HttpURLConnection:getResponseCode [] connection) + .let [status (.natural (ffi.of_int status))] headers (..default_headers connection) - input (|> connection - (java/net/URLConnection:getInputStream []) - (by ! each (|>> [] java/io/BufferedInputStream:new)))] - (pure [(.natural (ffi.of_int status)) + input (by ! each (|>> [] java/io/BufferedInputStream:new) + (if (and (n.>= 200 status) + (n.< 400 status)) + (java/net/URLConnection:getInputStream [] connection) + (java/net/HttpURLConnection:getErrorStream [] connection)))] + (pure [status [//.:headers headers //.:body (..default_body input)]]))))))) .python (these (ffi.the Dict diff --git a/stdlib/source/test/lux.lux b/stdlib/source/test/lux.lux index 087d497cbd..c782f0ea3f 100644 --- a/stdlib/source/test/lux.lux +++ b/stdlib/source/test/lux.lux @@ -1298,7 +1298,10 @@ /.:Local /.:Captured /.Bindings - /.:counter /.:mappings] + /.:counter /.:mappings + + @type.Bindings + @type.:counter @type.:mappings] verdict))) 0 1 2)) diff --git a/stdlib/source/test/lux/abstract/functor.lux b/stdlib/source/test/lux/abstract/functor.lux index e8be25a538..559423ac5f 100644 --- a/stdlib/source/test/lux/abstract/functor.lux +++ b/stdlib/source/test/lux/abstract/functor.lux @@ -28,7 +28,8 @@ ["_" property (.only Test)]]]] ["[0]" \\polytypic] [\\library - ["[0]" / (.only Functor)]] + ["[0]" / (.only Functor) + ["[0]" pro]]] ["[0]" / ["[1][0]" contravariant] ["[1][0]" effect]]) @@ -186,6 +187,10 @@ ..\\polytypic /contravariant.test /effect.test + + (<| (_.covering pro._) + (_.test "Placeholder..." + true)) )))) (every .public (Injection !) diff --git a/stdlib/source/test/lux/abstract/functor/pro.lux b/stdlib/source/test/lux/abstract/functor/pro.lux index 73f18ebc28..fc99f0a383 100644 --- a/stdlib/source/test/lux/abstract/functor/pro.lux +++ b/stdlib/source/test/lux/abstract/functor/pro.lux @@ -14,7 +14,9 @@ [/64 ["[0]" natural]]]] [test - ["_" property (.only Test)]]]] + ["_" property (.only Test)]] + [data + ["[0]" product]]]] [\\library ["[0]" /]]) @@ -22,11 +24,12 @@ (-> it Test)) -(the .public (specification concrete random - functor) +(the .public (specification_of_functor concrete random + functor) (for_any (_ it) - (-> (-> (it Natural Natural) - (-> Natural Natural)) + (-> (for_any (_ parameter|return) + (-> (it parameter|return parameter|return) + (-> parameter|return parameter|return))) (Random (it Natural Natural)) (Specification (/.Functor it)))) (<| (monad.let [! random.monad] @@ -39,7 +42,7 @@ function.identity it) - identity! + satisfaction_of_identity! (by natural.equivalence = ((concrete it) cause) ((concrete it') cause)) @@ -69,9 +72,195 @@ after_1) it) - composite! + satisfaction_of_composition! (by natural.equivalence = ((concrete left) cause) ((concrete right) cause))] - (and identity! - composite!))))) + (and satisfaction_of_identity! + satisfaction_of_composition!))))) + +(the (left_0 it) + (for_any (_ it to_ignore) + (-> (Or to_ignore it) + it)) + (when it + {.:Left it} (undefined) + {.:Right it} it)) + +(the (left_0' it) + (for_any (_ it) + (-> it + (Or Nothing it))) + {.:Right it}) + +(the (right_0 it) + (for_any (_ it to_ignore) + (-> (Or it to_ignore) + it)) + (when it + {.:Left it} it + {.:Right it} (undefined))) + +(the (right_0' it) + (for_any (_ it) + (-> it + (Or it Nothing))) + {.:Left it}) + +(the (co_association _0|_1|_2) + (for_any (_ _0 _1 _2) + (-> (Either _0 (Either _1 _2)) + (Either (Either _0 _1) _2))) + (when _0|_1|_2 + {.:Left _0} + {.:Left {.:Left _0}} + + {.:Right {.:Left _1}} + {.:Left {.:Right _1}} + + {.:Right {.:Right _2}} + {.:Right _2})) + +(the (co_association' _0|_1|_2) + (for_any (_ _0 _1 _2) + (-> (Either (Either _0 _1) _2) + (Either _0 (Either _1 _2)))) + (when _0|_1|_2 + {.:Left {.:Left _0}} + {.:Left _0} + + {.:Left {.:Right _1}} + {.:Right {.:Left _1}} + + {.:Right _2} + {.:Right {.:Right _2}})) + +(the .public (specification_of_co_cartesian concrete random + functor + cartesian) + (for_any (_ it) + (-> (for_any (_ parameter|return) + (-> (it parameter|return parameter|return) + (-> parameter|return parameter|return))) + (Random (it Natural Natural)) + (/.Functor it) + (Specification (/.Co_Cartesian it)))) + (<| (monad.let [! random.monad] + [cause random.natural + it random]) + (_.for [/.Co_Cartesian]) + (all _.and + (_.coverage [/.when_left] + (let [satisfaction_of_identity! + (by natural.equivalence = + (right_0 ((concrete (by cartesian when_left it)) {.:Left cause})) + (right_0 ((concrete (by functor each ..right_0 ..right_0' it)) {.:Left cause}))) + + satisfaction_of_association! + (by natural.equivalence = + (right_0 ((concrete (by cartesian when_left it)) + {.:Left cause})) + (right_0 ((concrete (by functor each ..co_association ..co_association' + (by cartesian when_left (by cartesian when_left it)))) + {.:Left cause})))] + (and satisfaction_of_identity! + satisfaction_of_association!))) + (_.coverage [/.when_right] + (let [satisfaction_of_identity! + (by natural.equivalence = + (left_0 ((concrete (by cartesian when_right it)) {.:Right cause})) + (left_0 ((concrete (by functor each ..left_0 ..left_0' it)) {.:Right cause}))) + + satisfaction_of_association! + (by natural.equivalence = + (left_0 ((concrete (by cartesian when_right it)) + {.:Right cause})) + (left_0 ((concrete (by functor each ..co_association' ..co_association + (by cartesian when_right (by cartesian when_right it)))) + {.:Right cause})))] + (and satisfaction_of_identity! + satisfaction_of_association!))) + ))) + +(the (left_1 [_ it]) + (for_any (_ it) + (-> (And Any it) + it)) + it) + +(the (left_1' it) + (for_any (_ it) + (-> it + (And Any it))) + [[] it]) + +(the (right_1 [it _]) + (for_any (_ it) + (-> (And it Any) + it)) + it) + +(the (right_1' it) + (for_any (_ it) + (-> it + (And it Any))) + [it []]) + +(the (association [_0 [_1 _2]]) + (for_any (_ _0 _1 _2) + (-> (And _0 (And _1 _2)) + (And (And _0 _1) _2))) + [[_0 _1] _2]) + +(the (association' [[_0 _1] _2]) + (for_any (_ _0 _1 _2) + (-> (And (And _0 _1) _2) + (And _0 (And _1 _2)))) + [_0 [_1 _2]]) + +(the .public (specification_of_cartesian concrete random + functor + cartesian) + (for_any (_ it) + (-> (for_any (_ parameter|return) + (-> (it parameter|return parameter|return) + (-> parameter|return parameter|return))) + (Random (it Natural Natural)) + (/.Functor it) + (Specification (/.Cartesian it)))) + (<| (monad.let [! random.monad] + [cause random.natural + it random]) + (_.for [/.Cartesian]) + (all _.and + (_.coverage [/.in_left] + (let [satisfaction_of_identity! + (by natural.equivalence = + (product.left ((concrete (by cartesian in_left it)) [cause []])) + (product.left ((concrete (by functor each ..right_1 ..right_1' it)) [cause []]))) + + satisfaction_of_association! + (by natural.equivalence = + (product.left ((concrete (by cartesian in_left it)) + [cause [[] []]])) + (product.left ((concrete (by functor each ..association ..association' + (by cartesian in_left (by cartesian in_left it)))) + [cause [[] []]])))] + (and satisfaction_of_identity! + satisfaction_of_association!))) + (_.coverage [/.in_right] + (let [satisfaction_of_identity! + (by natural.equivalence = + (product.right ((concrete (by cartesian in_right it)) [[] cause])) + (product.right ((concrete (by functor each ..left_1 ..left_1' it)) [[] cause]))) + + satisfaction_of_association! + (by natural.equivalence = + (product.right ((concrete (by cartesian in_right it)) + [[[] []] cause])) + (product.right ((concrete (by functor each ..association' ..association + (by cartesian in_right (by cartesian in_right it)))) + [[[] []] cause])))] + (and satisfaction_of_identity! + satisfaction_of_association!))) + ))) diff --git a/stdlib/source/test/lux/compiler/language/lux/analysis.lux b/stdlib/source/test/lux/compiler/language/lux/analysis.lux index 973f0176b2..b4efbfaf9f 100644 --- a/stdlib/source/test/lux/compiler/language/lux/analysis.lux +++ b/stdlib/source/test/lux/compiler/language/lux/analysis.lux @@ -225,28 +225,33 @@ expected_right (..random 2) expected_lefts random.natural expected_right? random.bit] - (all _.and - (_.coverage [/.variant] - (let [expected (if expected_right? - expected_right - expected_left)] - (when (/.variant provenance.dummy [expected_lefts expected_right? expected]) - (/.variant @ [actual_lefts actual_right? actual]) - (and (identical? expected_lefts actual_lefts) - (identical? expected_right? actual_right?) - (identical? expected actual)) - - _ - false))) - (_.coverage [/.tuple] - (when (/.tuple provenance.dummy (list expected_left expected_right)) - (/.tuple @ (list actual_left actual_right)) - (and (identical? expected_left actual_left) - (identical? expected_right actual_right)) - - _ - false)) - ))) + (<| (_.for [@type.Complex + @type.:Complex_Variant @type.:Complex_Tuple]) + (all _.and + (<| (_.for [@type.Variant + @type.:lefts @type.:right? @type.:choice]) + (_.coverage [/.variant] + (let [expected (if expected_right? + expected_right + expected_left)] + (when (/.variant provenance.dummy [expected_lefts expected_right? expected]) + (/.variant @ [actual_lefts actual_right? actual]) + (and (identical? expected_lefts actual_lefts) + (identical? expected_right? actual_right?) + (identical? expected actual)) + + _ + false)))) + (<| (_.for [@type.Tuple]) + (_.coverage [/.tuple] + (when (/.tuple provenance.dummy (list expected_left expected_right)) + (/.tuple @ (list actual_left actual_right)) + (and (identical? expected_left actual_left) + (identical? expected_right actual_right)) + + _ + false))) + )))) (the test|reference Test @@ -296,6 +301,13 @@ (identical? expected_parameter/0 actual_parameter/0) (identical? expected_parameter/1 actual_parameter/1)) + _ + false)) + (_.coverage [/.coercion] + (when (/.coercion provenance.dummy expected_parameter/0) + (/.coercion _ actual_parameter) + (identical? expected_parameter/0 actual_parameter) + _ false)) ))) @@ -398,6 +410,20 @@ _ false)))) + (_.coverage [/.of_try] + (and (|> (/.of_try {try.:Failure expected_error}) + (phase.value state/0) + (pipe.when + {try.:Failure actual_error} + (and (text.contains? expected_error actual_error) + (text.contains? (provenance.as_text provenance/0) actual_error)) + + _ + false)) + (|> (/.of_try {try.:Success version/0}) + (phase.value state/0) + (by (try.equivalence n.equivalence) = + {try.:Success version/0})))) ))))) (the test|state @@ -541,8 +567,9 @@ [left (..random 2) right (..random 2)] (all _.and - (_.for [/.equivalence] - (equivalenceT.spec /.equivalence (..random 2))) + (_.for [/.equivalence /.=] + (static.when (identical? /.equivalence /.=) + (equivalenceT.spec /.equivalence (..random 2)))) ..test|simple ..test|complex diff --git a/stdlib/source/test/lux/compiler/language/lux/analysis/complex.lux b/stdlib/source/test/lux/compiler/language/lux/analysis/complex.lux index 353c53b570..62f9e100d5 100644 --- a/stdlib/source/test/lux/compiler/language/lux/analysis/complex.lux +++ b/stdlib/source/test/lux/compiler/language/lux/analysis/complex.lux @@ -67,7 +67,6 @@ Test (let [random (..random 3 random.natural)] (<| (_.covering /._) - (_.for [@type.Complex @type.Variant @type.Tuple]) (all _.and (_.for [/.equivalence] (equivalenceT.spec (/.equivalence n.equivalence) random)) diff --git a/stdlib/source/test/lux/compiler/language/lux/phase/extension.lux b/stdlib/source/test/lux/compiler/language/lux/phase/extension.lux index 9a3e0fe622..40d2a5f25a 100644 --- a/stdlib/source/test/lux/compiler/language/lux/phase/extension.lux +++ b/stdlib/source/test/lux/compiler/language/lux/phase/extension.lux @@ -28,7 +28,9 @@ ["n" natural] ["i" integer]]]] [test - ["_" property (.only Test)]]]] + ["_" property (.only Test)]] + [compiler + ["@[0]" type]]]] [\\library ["[0]" / (.only) [///// @@ -37,7 +39,7 @@ ["[0]" archive]]]]]) (the .public random - (Random (/.Extension Natural)) + (Random (@type.Extension Natural)) (all random.and (random.lower_cased 5) (random.list 2 random.natural) @@ -196,7 +198,8 @@ (the .public test Test (<| (_.covering /._) - (_.for [/.Extension]) + (_.for [@type.Extension + @type.:name @type.:parameters]) (monad.let [! random.monad] [state random.integer dummy (random.only (|>> (i.= state) not) diff --git a/stdlib/source/test/lux/compiler/language/lux/syntax.lux b/stdlib/source/test/lux/compiler/language/lux/syntax.lux index 6b61de328b..07d5eca173 100644 --- a/stdlib/source/test/lux/compiler/language/lux/syntax.lux +++ b/stdlib/source/test/lux/compiler/language/lux/syntax.lux @@ -31,7 +31,9 @@ ["[0]" provenance] ["[0]" name]] [test - ["_" property (.only Test)]]]] + ["_" property (.only Test)]] + [error + ["[0]" exception]]]] [\\library ["[0]" /]]) @@ -46,6 +48,12 @@ (random.and name_part^ name_part^)) +(the textual^ + (Random Text) + (monad.let random.monad + [size (|> random.natural (random:each (n.% 20)))] + (random.upper_cased size))) + (the code^ (Random Code) (let [numeric^ (is (Random Code) @@ -58,9 +66,7 @@ )) textual^ (is (Random Code) (all random.either - (monad.let random.monad - [size (|> random.natural (random:each (n.% 20)))] - (|> (random.upper_cased size) (random:each code.text))) + (|> textual^ (random:each code.text)) (|> name^ (random:each code.name)) )) simple^ (is (Random Code) @@ -88,12 +94,17 @@ Test (monad.let [! random.monad] [sample code^ + expected_text textual^ expected_fraction fractionT.random expected_rational rationalT.random natural_numerator random.natural integer_numerator random.integer - decimal_numerator random.safe_decimal] + decimal_numerator random.safe_decimal + + .let [random_digit (by ! each (n.% 10) random.natural)] + digit_0 random_digit + digit_1 random_digit] (`` (all _.and (_.test "Can parse Lux code." (when (let [source_code (code.as_text sample)] @@ -122,6 +133,66 @@ {.:Right [_ =other]} (and (by code.equivalence = sample =sample) (by code.equivalence = other =other))))))) + (,, (template.with [,open ,close ,code] + [(_.coverage [,open ,close] + (let [sample (,code (list sample)) + source_code (code.as_text sample)] + (when (/.parse source_code "" (dictionary.empty text.hash) + [provenance.dummy 0 source_code]) + {.:Left error} + false + + {.:Right [_ parsed]} + (and (by code.equivalence = parsed sample) + (text.starts_with? ,open source_code) + (text.ends_with? ,close source_code)))))] + + [[/.open_variant /.close_variant code.variant] + [/.open_tuple /.close_tuple code.tuple] + [/.open_form /.close_form code.form]])) + (_.coverage [/.text_delimiter] + (let [source_code (code.as_text (code.text expected_text))] + (when (/.parse source_code "" (dictionary.empty text.hash) + [provenance.dummy 0 source_code]) + {.:Left error} + false + + {.:Right [_ parsed]} + (and (by code.equivalence = (code.text expected_text) parsed) + (text.starts_with? /.text_delimiter source_code) + (text.ends_with? /.text_delimiter source_code))))) + (_.coverage [/.digit_delimiter] + (let [expected (n.+ (n.x 10 digit_0) + digit_1) + source_code (text (%.natural digit_0) + /.digit_delimiter + (%.natural digit_1))] + (when (/.parse source_code "" (dictionary.empty text.hash) + [provenance.dummy 0 source_code]) + {.:Left error} + false + + {.:Right [_ parsed]} + (by code.equivalence = (code.natural expected) parsed)))) + (_.coverage [/.text_cannot_contain_new_lines] + (let [source_code (code.as_text (code.text (text expected_text + \n + expected_text)))] + (when (/.parse source_code "" (dictionary.empty text.hash) + [provenance.dummy 0 source_code]) + {.:Left [_ error]} + (exception.is? /.text_cannot_contain_new_lines error) + + else + false))) + (_.coverage [/.end_of_file] + (when (/.parse "" "" (dictionary.empty text.hash) + [provenance.dummy 0 ""]) + {.:Left [_ error]} + (exception.is? /.end_of_file error) + + else + false)) (_.coverage [fraction.extension] (when (let [source_code (by fraction.text as expected_fraction)] (/.parse source_code "" (dictionary.empty text.hash) @@ -264,7 +335,11 @@ (the .public test Test (<| (_.covering /._) + (_.for [/.Source_Code /.parse]) (all _.and ..code ..comments + (_.for [/.Alias /.Aliases] + (_.coverage [/.no_aliases] + (dictionary.empty? /.no_aliases))) ))) diff --git a/stdlib/source/test/lux/compiler/type.lux b/stdlib/source/test/lux/compiler/type.lux index dd776a8b9e..a6239dd7be 100644 --- a/stdlib/source/test/lux/compiler/type.lux +++ b/stdlib/source/test/lux/compiler/type.lux @@ -124,7 +124,7 @@ (n.= expected_amount)))] [[/.:alias] - [/.:name]])))) + [/.:real_name]])))) (_.coverage [,each_type] (let [every_type (list ,each_type)] (list.every? (function (_ expected) diff --git a/stdlib/source/test/lux/data/text.lux b/stdlib/source/test/lux/data/text.lux index 5f5337ef4d..c7dd7fdedf 100644 --- a/stdlib/source/test/lux/data/text.lux +++ b/stdlib/source/test/lux/data/text.lux @@ -28,6 +28,7 @@ [data [collection ["[0]" set] + ["[0]" stack] ["[0]" list (.use "[1]:[0]" functor) ["?[1]" \\projection]] [tree @@ -58,7 +59,9 @@ ["[0]" code (.only) ["<[1]>" \\projection]]] [test - ["_" property (.only Test)]]]] + ["_" property (.only Test)]] + [aspect + ["[0]" view]]]] ["$[0]" // [// ["[1][0]" type] @@ -209,6 +212,22 @@ (_.coverage [\\injection.modulo] (/.= (by (modular.text modulus) as sample) (\\injection.modulo sample)))) + (with (stack.equivalence natural.equivalence) + (monad.let [! random.monad] + [expected_size (by ! each (|>> (natural.% 100) ++) random.natural) + .let [random_stack (is (Random (Stack Natural)) + (|> random.natural + (random.set natural.hash expected_size) + (by ! each (|>> set.as_list + (view.as list.stack)))))] + expected_stack random_stack + alternative_stack (random.only (|>> (= expected_stack) not) + random_stack)] + (_.coverage [\\injection.stack] + (bit.= (= expected_stack + alternative_stack) + (/.= (\\injection.stack \\injection.natural expected_stack) + (\\injection.stack \\injection.natural alternative_stack)))))) )))) (the !expect diff --git a/stdlib/source/test/lux/debug.lux b/stdlib/source/test/lux/debug.lux index 4847fcd9e4..a6c3ebd5d1 100644 --- a/stdlib/source/test/lux/debug.lux +++ b/stdlib/source/test/lux/debug.lux @@ -18,6 +18,7 @@ ["[0]" text (.only) ["%" \\injection]] [collection + ["[0]" array] ["[0]" list (.use "[1]:[0]" functor) ["?[1]" \\projection]]]] [logic @@ -272,68 +273,73 @@ Bit)) (|>> (match? {try.:Success _}))) -(the failure? +(the (failure? it) (for_any (_ it) (-> (try.Try it) Bit)) - (|>> ..success? - not)) + (when it + {try.:Failure it} + (exception.is? /.not_of_type it) + + else + false)) (the cast Test - (monad.let random.monad - [sample_bit random.bit - sample_natural random.natural - sample_integer random.integer - sample_revolution random.revolution - sample_decimal random.decimal - sample_text (random.unicode 1)] - (all _.and - (_.coverage [/.bit] - (and (success? (/.bit sample_bit)) - - (failure? (/.bit sample_natural)) - (failure? (/.bit sample_decimal)) - (failure? (/.bit sample_text)))) - (_.coverage [/.i64] - (and (success? (/.i64 sample_natural)) - (success? (/.i64 sample_integer)) - (success? (/.i64 sample_revolution)) - - (failure? (/.i64 sample_bit)) - (failure? (/.i64 sample_decimal)) - (failure? (/.i64 sample_text)))) - (_.coverage [/.decimal] - (and (success? (/.decimal sample_decimal)) - - (failure? (/.decimal sample_bit)) - (failure? (/.decimal sample_natural)) - (failure? (/.decimal sample_text)))) - (_.coverage [/.text] - (and (success? (/.text sample_text)) - - (failure? (/.text sample_bit)) - (failure? (/.text sample_natural)) - (failure? (/.text sample_decimal)))) - (_.coverage [/.variant] - (and (success? (/.variant (is (Either Decimal Decimal) {.:Left sample_decimal}))) - (success? (/.variant (is (Either Decimal Decimal) {.:Right sample_decimal}))) - - (failure? (/.variant sample_bit)) - (failure? (/.variant sample_natural)) - (failure? (/.variant sample_decimal)) - (failure? (/.variant sample_text)) - (failure? (/.variant [sample_decimal sample_decimal])))) - (_.coverage [/.tuple] - (and (success? (/.tuple [sample_decimal sample_decimal])) - - (failure? (/.tuple sample_bit)) - (failure? (/.tuple sample_natural)) - (failure? (/.tuple sample_decimal)) - (failure? (/.tuple sample_text)) - (failure? (/.tuple (is (Either Decimal Decimal) {.:Left sample_decimal}))) - (failure? (/.tuple (is (Either Decimal Decimal) {.:Right sample_decimal}))))) - ))) + (<| (monad.let random.monad + [sample_bit random.bit + sample_natural random.natural + sample_integer random.integer + sample_revolution random.revolution + sample_decimal random.decimal + sample_text (random.unicode 1)]) + (_.for [/.not_of_type]) + (all _.and + (_.coverage [/.bit] + (and (success? (/.bit sample_bit)) + + (failure? (/.bit sample_natural)) + (failure? (/.bit sample_decimal)) + (failure? (/.bit sample_text)))) + (_.coverage [/.i64] + (and (success? (/.i64 sample_natural)) + (success? (/.i64 sample_integer)) + (success? (/.i64 sample_revolution)) + + (failure? (/.i64 sample_bit)) + (failure? (/.i64 sample_decimal)) + (failure? (/.i64 sample_text)))) + (_.coverage [/.decimal] + (and (success? (/.decimal sample_decimal)) + + (failure? (/.decimal sample_bit)) + (failure? (/.decimal sample_natural)) + (failure? (/.decimal sample_text)))) + (_.coverage [/.text] + (and (success? (/.text sample_text)) + + (failure? (/.text sample_bit)) + (failure? (/.text sample_natural)) + (failure? (/.text sample_decimal)))) + (_.coverage [/.variant] + (and (success? (/.variant (is (Either Decimal Decimal) {.:Left sample_decimal}))) + (success? (/.variant (is (Either Decimal Decimal) {.:Right sample_decimal}))) + + (failure? (/.variant sample_bit)) + (failure? (/.variant sample_natural)) + (failure? (/.variant sample_decimal)) + (failure? (/.variant sample_text)) + (failure? (/.variant [sample_decimal sample_decimal])))) + (_.coverage [/.tuple] + (and (success? (/.tuple [sample_decimal sample_decimal])) + + (failure? (/.tuple sample_bit)) + (failure? (/.tuple sample_natural)) + (failure? (/.tuple sample_decimal)) + (failure? (/.tuple sample_text)) + (failure? (/.tuple (is (Either Decimal Decimal) {.:Left sample_decimal}))) + (failure? (/.tuple (is (Either Decimal Decimal) {.:Right sample_decimal}))))) + ))) (the .public test Test @@ -374,4 +380,12 @@ (/.log! expected_message))] (text.= (text expected_message text.\n) actual_message))) + (_.coverage [/.also] + (with (try.equivalence text.equivalence) + (|> (is (Array Text) + (array.empty 1)) + (/.also (|>> (array.has! 0 expected_message) + io.io)) + (array.item 0) + (= {try.:Success expected_message})))) )))) diff --git a/stdlib/source/test/lux/function.lux b/stdlib/source/test/lux/function.lux index 57f8e015fd..ff3c31f0b8 100644 --- a/stdlib/source/test/lux/function.lux +++ b/stdlib/source/test/lux/function.lux @@ -10,7 +10,7 @@ ["[0]" monoid ["[1]T" \\test]] [functor - ["[0]" pro + ["[0]" pro (.only) ["[1]T" \\test]]]] [math ["[0]" random (.only Random)] @@ -81,18 +81,39 @@ (_.coverage [/.of] (n.= (f0 extra) (/.of extra f0))) - ... (<| (_.for [/.Function]) - ... (all _.and - ... (_.for [/.pro_functor] - ... (let [as_function (is (-> (/.Function Natural Natural) - ... (-> Natural Natural)) - ... (function (_ it cause) - ... (it cause)))] - ... (proT.specification as_function - ... (is (Random (/.Function Natural Natural)) - ... (pure ++)) - ... /.pro_functor))) - ... )) + (<| (_.for [/.Function]) + (let [as_function (is (for_any (_ parameter|return) + (-> (/.Function parameter|return parameter|return) + (-> parameter|return parameter|return))) + (function (_ it cause) + (it cause))) + random (is (Random (/.Function Natural Natural)) + (pure ++))]) + (all _.and + (_.for [/.functor] + ((as (-> (type_of proT.specification_of_functor) + ((type_of proT.specification_of_functor) /.Function)) + proT.specification_of_functor) + as_function + random + /.functor)) + (_.for [/.co_cartesian] + ((as (-> (type_of proT.specification_of_co_cartesian) + ((type_of proT.specification_of_co_cartesian) /.Function)) + proT.specification_of_co_cartesian) + as_function + random + /.functor + /.co_cartesian)) + (_.for [/.cartesian] + ((as (-> (type_of proT.specification_of_cartesian) + ((type_of proT.specification_of_cartesian) /.Function)) + proT.specification_of_cartesian) + as_function + random + /.functor + /.cartesian)) + )) /continuation.test /contract.test diff --git a/stdlib/source/test/lux/macro/syntax.lux b/stdlib/source/test/lux/macro/syntax.lux index b7c9d71701..af9c523e9d 100644 --- a/stdlib/source/test/lux/macro/syntax.lux +++ b/stdlib/source/test/lux/macro/syntax.lux @@ -20,7 +20,8 @@ [/64 ["n" natural (.use "[1]:[0]" base_10)]]]] [macro - ["^" pattern]] + ["^" pattern] + ["[0]" expansion]] [meta ["[0]" code (.only) ["<[1]>" \\projection] @@ -38,23 +39,30 @@ ["[1][0]" type ["[1]/[0]" variable]]]) -(the +/3 - (/.macro (_ [a ?list.any - b ?list.any - c ?list.any]) - (pure (list (` (all n.+ (, a) (, b) (, c))))))) +(expansion.let [,*inputs (these [a ?list.any + b ?list.any + c ?list.any]) + ,*body (these (pure (list (` (all n.+ (, a) (, b) (, c))))))] + (these (the +/3 + (/.macro (_ ,*inputs) + ,*body)) + (/.the (the_+/3 ,*inputs) + ,*body))) (the .public test Test (<| (_.covering /._) + (monad.let [! random.monad] + [x random.natural + y random.natural + z random.natural]) (all _.and - (monad.let random.monad - [x random.natural - y random.natural - z random.natural] - (_.coverage [/.macro] - (n.= (all n.+ x y z) - (+/3 x y z)))) + (_.coverage [/.macro] + (n.= (all n.+ x y z) + (+/3 x y z))) + (_.coverage [/.the] + (n.= (+/3 x y z) + (the_+/3 x y z))) (monad.let [! random.monad] [expected_code codeT.random expected_error (by ! each n:as random.natural)] diff --git a/stdlib/source/test/lux/meta/binding.lux b/stdlib/source/test/lux/meta/binding.lux index 7acff92ccf..957991981c 100644 --- a/stdlib/source/test/lux/meta/binding.lux +++ b/stdlib/source/test/lux/meta/binding.lux @@ -184,6 +184,8 @@ @type.:Definition @type.:Alias @type.Definition + @type.:type @type.:expression @type.:value + @type.Alias /.globals] (let [[current_globals macro_globals expected_lux] (expected_lux true {.:Some .Macro}) diff --git a/stdlib/source/test/lux/meta/binding/local.lux b/stdlib/source/test/lux/meta/binding/local.lux index 1021735c7b..183091562b 100644 --- a/stdlib/source/test/lux/meta/binding/local.lux +++ b/stdlib/source/test/lux/meta/binding/local.lux @@ -96,6 +96,9 @@ (_.coverage [.Scope .:locals .:captured + @type.Scope + @type.:locals @type.:captured + /.all] (let [equivalence (is (Equivalence (Stack (List [Text Type]))) (stack.equivalence