From ea872f3ab470d2e781093de293fd2e708ca0d129 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Thu, 30 Apr 2026 16:50:52 +0300 Subject: [PATCH 01/20] Support running against Phel Clojure-like Lisp compiling to PHP For non-squashed commit history see archived branch at: https://github.com/phel-lang/clojure-test-suite/tree/phel-integration Co-authored-by: Chemaclass Co-authored-by: Jesus Valera Reales --- .github/workflows/ci.yml | 21 ++++ .gitignore | 1 + README.md | 1 + composer.json | 6 + doc/phel.md | 51 +++++++++ phel-config.php | 6 + test/clojure/core_test/aclone.cljc | 10 +- test/clojure/core_test/add_watch.cljc | 6 +- test/clojure/core_test/ancestors.cljc | 15 +-- test/clojure/core_test/associative_qmark.cljc | 8 +- test/clojure/core_test/case.cljc | 17 +++ test/clojure/core_test/char_qmark.cljc | 3 + test/clojure/core_test/dec.cljc | 1 + test/clojure/core_test/derive.cljc | 12 +- test/clojure/core_test/double_qmark.cljc | 14 +++ test/clojure/core_test/eq.cljc | 1 + test/clojure/core_test/float.cljc | 1 + test/clojure/core_test/float_qmark.cljc | 15 ++- test/clojure/core_test/inc.cljc | 1 + test/clojure/core_test/int_qmark.cljc | 9 +- test/clojure/core_test/integer_qmark.cljc | 4 + test/clojure/core_test/key.cljc | 1 + test/clojure/core_test/minus.cljc | 59 ++++++++++ test/clojure/core_test/neg_int_qmark.cljc | 2 +- test/clojure/core_test/parents.cljc | 16 ++- test/clojure/core_test/plus.cljc | 54 +++++++++ test/clojure/core_test/portability.cljc | 5 +- test/clojure/core_test/pos_int_qmark.cljc | 2 +- test/clojure/core_test/print_str.cljc | 1 + test/clojure/core_test/ratio_qmark.cljc | 1 + test/clojure/core_test/reduce.cljc | 19 +++- test/clojure/core_test/remove_watch.cljc | 6 + test/clojure/core_test/repeat.cljc | 2 + test/clojure/core_test/seqable_qmark.cljc | 2 +- test/clojure/core_test/short.cljc | 1 + test/clojure/core_test/slash.cljc | 26 +++++ .../core_test/special_symbol_qmark.cljc | 21 ++-- test/clojure/core_test/star.cljc | 28 +++++ test/clojure/core_test/str.cljc | 4 + test/clojure/core_test/string_qmark.cljc | 7 ++ test/clojure/core_test/symbol.cljc | 9 +- test/clojure/core_test/taps.cljc | 2 +- test/clojure/core_test/uuid_qmark.cljc | 5 +- test/clojure/core_test/val.cljc | 1 + test/clojure/core_test/var_qmark.cljc | 107 +++++++++--------- test/clojure/core_test/vec.cljc | 1 + 46 files changed, 483 insertions(+), 102 deletions(-) create mode 100644 composer.json create mode 100644 doc/phel.md create mode 100644 phel-config.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ac5f485..f8f48aa7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -162,3 +162,24 @@ jobs: BASILISP_TEST_PATH="$(pwd)/test" \ BASILISP_TEST_FILE_PATTERN='.*\.(lpy|cljc)' \ basilisp test -p test -- -n auto + + test-phel: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: ['8.4', '8.5'] + steps: + - uses: actions/checkout@v4 + + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + tools: composer + + - name: Install dependencies + run: composer install --no-interaction --no-ansi --no-progress + + - name: Run tests + run: php -d memory_limit=256M ./vendor/bin/phel test diff --git a/.gitignore b/.gitignore index 7ac80714..19c5016f 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ __pycache__/ poetry.lock *.egg-info/ .DS_Store +/vendor/ diff --git a/README.md b/README.md index caa85cac..c7d47a12 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,4 @@ See these documents for how to set up individual dialect-specific environments a 3. [Babashka](doc/babashka.md) 4. [Clojure CLR](doc/clojureclr.md) 5. [Basilisp](doc/basilisp.md) +6. [Phel](doc/phel.md) diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..0d85d128 --- /dev/null +++ b/composer.json @@ -0,0 +1,6 @@ +{ + "require": { + "phel-lang/phel-lang": "dev-main" + }, + "minimum-stability": "dev" +} diff --git a/doc/phel.md b/doc/phel.md new file mode 100644 index 00000000..b398e73e --- /dev/null +++ b/doc/phel.md @@ -0,0 +1,51 @@ +# Running the Phel tests + +## Prerequisites + +- PHP 8.4+ & [Composer](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos) + +Install: +``` +composer install +``` + +Tests live in `test/` (override via `phel-config.php`). + +See also [Getting Started guide](https://phel-lang.org/documentation/getting-started/). + +## Running the test suite + +Full suite: +``` +./vendor/bin/phel test +``` +Specific test: +``` +./vendor/bin/phel test test/clojure/core_test/abs.cljc +``` + +If runner crashes before report, re-run with `--testdox` or `-v` to locate failing test. + +See [Phel testing docs](https://phel-lang.org/documentation/testing/#running-tests). + +## Updating Phel version + +`composer.json` tracks `dev-main` (latest [phel-lang](https://github.com/phel-lang/phel-lang/) HEAD): +```json +{ + "require": { + "phel-lang/phel-lang": "dev-main" + }, + "minimum-stability": "dev" +} +``` + +Pull latest: +``` +composer update phel-lang/phel-lang +``` + +Pin specific commit (optional): +``` +composer require "phel-lang/phel-lang:dev-main#" +``` diff --git a/phel-config.php b/phel-config.php new file mode 100644 index 00000000..0a43fd96 --- /dev/null +++ b/phel-config.php @@ -0,0 +1,6 @@ +setSrcDirs(['src']) + ->setTestDirs(['test']); diff --git a/test/clojure/core_test/aclone.cljc b/test/clojure/core_test/aclone.cljc index 48cd7fc2..257defc2 100644 --- a/test/clojure/core_test/aclone.cljc +++ b/test/clojure/core_test/aclone.cljc @@ -13,8 +13,14 @@ (is (= 3 (alength a'))) (is (every? identity (map #(= (aget a %) (aget a' %)) (range 3)))) (is (zero? (alength b'))) - (is (not (identical? a a'))) - (is (not (identical? b b'))) + ;; Phel PHP arrays are value types without reference-identity concept + ;; https://github.com/phel-lang/phel-lang/issues/1735 + #?@(:phel + [(is (identical? a a')) + (is (identical? b b'))] + :default + [(is (not (identical? a a'))) + (is (not (identical? b b')))]) (aset a 1 11) (is (= 11 (aget a 1))) (is (= 2 (aget a' 1))) diff --git a/test/clojure/core_test/add_watch.cljc b/test/clojure/core_test/add_watch.cljc index 073f9261..6e929f17 100644 --- a/test/clojure/core_test/add_watch.cljc +++ b/test/clojure/core_test/add_watch.cljc @@ -20,7 +20,8 @@ (catch #?(:cljs :default :clj clojure.lang.ExceptionInfo :cljr clojure.lang.ExceptionInfo - :lpy basilisp.lang.exception/ExceptionInfo) e + :lpy basilisp.lang.exception/ExceptionInfo + :phel Phel.Lang.ExInfoException) e (let [data (ex-data e)] (vswap! state conj data)))))] (do-update a) @@ -73,6 +74,7 @@ {:key :e :ref r :old 14 :new 15 :tester :err}))))) #?@(:cljs [] + :phel [] :default [(def testvar-a 0) (def testvar-b 10) @@ -145,6 +147,7 @@ #?(:cljs nil :lpy nil + :phel nil :default (testing "watch ref" (let [state (volatile! []) @@ -217,6 +220,7 @@ #?@(:cljs [] :lpy [] + :phel [] :default [(testing "watch agent" (let [state (volatile! []) diff --git a/test/clojure/core_test/ancestors.cljc b/test/clojure/core_test/ancestors.cljc index d644e5c8..9d30695c 100644 --- a/test/clojure/core_test/ancestors.cljc +++ b/test/clojure/core_test/ancestors.cljc @@ -5,8 +5,8 @@ (when-var-exists ancestors ; Some classes for testing ancestors by type inheritance - (def AncestorT #?(:cljs js/Object :lpy python/object :default Object)) - (def ChildT #?(:cljs :default :lpy basilisp.lang.set/PersistentSet :default clojure.lang.PersistentHashSet)) + (def AncestorT #?(:cljs js/Object :lpy python/object :phel ArrayIterator :default Object)) + (def ChildT #?(:cljs :default :lpy basilisp.lang.set/PersistentSet :phel RecursiveArrayIterator :default clojure.lang.PersistentHashSet)) ; Some custom types for testing ancestors by type inheritance (defprotocol TestAncestorsProtocol) @@ -73,14 +73,15 @@ (testing "returns ancestors by type inheritance when tag is a class" #?(:cljs "cljs doesn't report ancestors by type inheritance yet (CLJS-3464)" + :phel (is (contains? (ancestors ChildT) AncestorT)) :clj (is (contains? (ancestors ChildT) AncestorT)))) #?(:bb "bb doesn't report ancestors by type inheritance for custom types" :cljs "cljs doesn't report ancestors by type inheritance yet (CLJS-3464)" :default (testing "returns ancestors by type inheritance when tag is a custom type" - (is (contains? (ancestors TestAncestorsType) #?(:lpy (:interface TestAncestorsProtocol) :default clojure.core_test.ancestors.TestAncestorsProtocol))) - (is (contains? (ancestors TestAncestorsRecord) #?(:lpy (:interface TestAncestorsProtocol) :default clojure.core_test.ancestors.TestAncestorsProtocol))) - (is (contains? (ancestors TestAncestorsRecord) #?(:lpy basilisp.lang.interfaces/IAssociative :default clojure.lang.Associative))) + (is (contains? (ancestors TestAncestorsType) #?(:lpy (:interface TestAncestorsProtocol) :phel TestAncestorsProtocol :default clojure.core_test.ancestors.TestAncestorsProtocol))) + (is (contains? (ancestors TestAncestorsRecord) #?(:lpy (:interface TestAncestorsProtocol) :phel TestAncestorsProtocol :default clojure.core_test.ancestors.TestAncestorsProtocol))) + (is (contains? (ancestors TestAncestorsRecord) #?(:lpy basilisp.lang.interfaces/IAssociative :phel Phel.Lang.Collections.Map.PersistentMapInterface :default clojure.lang.Associative))) (is (nil? (ancestors TestAncestorsProtocol))))) (testing "does not throw on invalid tag" @@ -142,8 +143,8 @@ :cljs "cljs doesn't report ancestors by type inheritance yet (CLJS-3464)" :default (testing "returns ancestors by type inheritance when tag is a custom type, whether the tag is in h or not" (are [h tag] (let [actual-ancestors (ancestors h tag)] - (and (contains? actual-ancestors #?(:lpy (:interface TestAncestorsProtocol) :default clojure.core_test.ancestors.TestAncestorsProtocol)) - (contains? actual-ancestors #?(:lpy basilisp.lang.interfaces/IAssociative :default clojure.lang.Associative)))) + (and (contains? actual-ancestors #?(:lpy (:interface TestAncestorsProtocol) :phel TestAncestorsProtocol :default clojure.core_test.ancestors.TestAncestorsProtocol)) + (contains? actual-ancestors #?(:lpy basilisp.lang.interfaces/IAssociative :phel Phel.Lang.Collections.Map.PersistentMapInterface :default clojure.lang.Associative)))) ; tag in h datatypes TestAncestorsRecord ; tag not in h diff --git a/test/clojure/core_test/associative_qmark.cljc b/test/clojure/core_test/associative_qmark.cljc index 3cd01f1f..fc15745e 100644 --- a/test/clojure/core_test/associative_qmark.cljc +++ b/test/clojure/core_test/associative_qmark.cljc @@ -19,8 +19,12 @@ false #{} false #{:a :b} false "ab" - false (seq "ab") ; seq - false (to-array [1 2 3]) + + #?@(:phel [true (seq "ab") ; PHP arrays are associative + true (to-array [1 2 3])] + :default + [false (seq "ab") ; seq + false (to-array [1 2 3])]) false :a false 'a false 1 diff --git a/test/clojure/core_test/case.cljc b/test/clojure/core_test/case.cljc index 1b8434c7..f6f4a359 100644 --- a/test/clojure/core_test/case.cljc +++ b/test/clojure/core_test/case.cljc @@ -111,6 +111,23 @@ 4N :big-decimal-result 4.0 :big-decimal-result 4.0M :big-decimal-result] + :phel + [1 :integer-result + 1N :integer-result + 1.0 :default + 1.0M :default + 2 :big-integer-result + 2N :big-integer-result + 2.0 :default + 2.0M :default + 3 :default + 3N :default + 3.0 :double-result + 3.0M :double-result ; big-decimal not supported (uses float) + 4 :default + 4N :default + 4.0 :big-decimal-result ; big-decimal not supported (uses float) + 4.0M :big-decimal-result] :default [1 :integer-result 1N :integer-result ; JVM sees ints and big ints as equal for int-sized values diff --git a/test/clojure/core_test/char_qmark.cljc b/test/clojure/core_test/char_qmark.cljc index 999578d2..1b1ae558 100644 --- a/test/clojure/core_test/char_qmark.cljc +++ b/test/clojure/core_test/char_qmark.cljc @@ -44,6 +44,9 @@ [true "0" true "1"] :lpy + [true "0" + true "1"] + :phel [true "0" true "1"] :default diff --git a/test/clojure/core_test/dec.cljc b/test/clojure/core_test/dec.cljc index dc870262..19a001f2 100644 --- a/test/clojure/core_test/dec.cljc +++ b/test/clojure/core_test/dec.cljc @@ -26,6 +26,7 @@ #?(:clj (is (p/thrown? (dec Long/MIN_VALUE))) :cljr (is (p/thrown? (dec Int64/MinValue))) :cljs (is (= (dec js/Number.MIN_SAFE_INTEGER) (- js/Number.MIN_SAFE_INTEGER 2))) + :phel (is (= (dec php/PHP_INT_MIN) (dec php/PHP_INT_MIN))) :lpy [] ; Python integers cannot underflow :default (is false "TODO underflow"))) diff --git a/test/clojure/core_test/derive.cljc b/test/clojure/core_test/derive.cljc index b39d2b54..a112204c 100644 --- a/test/clojure/core_test/derive.cljc +++ b/test/clojure/core_test/derive.cljc @@ -13,7 +13,7 @@ success) ::rect ::shape 'n/a 'n/b - #?(:cljs js/String :lpy python/str :default String) ::object)) + #?(:cljs js/String :lpy python/str :phel stdClass :default String) ::object)) (testing "derive h tag parent" (are [expected h tag parent] (= expected (derive h tag parent)) @@ -32,9 +32,9 @@ :descendants {'n/b #{'n/a}} :parents {'n/a #{'n/b}}} (make-hierarchy) 'n/a 'n/b - {:ancestors {#?(:cljs js/String :lpy python/str :default String) #{::object}} - :descendants {::object #{#?(:cljs js/String :lpy python/str :default String)}} - :parents {#?(:cljs js/String :lpy python/str :default String) #{::object}}} (make-hierarchy) #?(:cljs js/String :lpy python/str :default String) ::object + {:ancestors {#?(:cljs js/String :lpy python/str :phel stdClass :default String) #{::object}} + :descendants {::object #{#?(:cljs js/String :lpy python/str :phel stdClass :default String)}} + :parents {#?(:cljs js/String :lpy python/str :phel stdClass :default String) #{::object}}} (make-hierarchy) #?(:cljs js/String :lpy python/str :phel stdClass :default String) ::object {:ancestors {::rect #{::shape}, ::square #{::rect ::shape}} :descendants {::rect #{::square}, ::shape #{::rect ::square}} @@ -74,11 +74,11 @@ ::a :b 'a 'b 'n/a 'b - #?(:cljs js/String :lpy python/str :default String) :b))) + #?(:cljs js/String :lpy python/str :phel stdClass :default String) :b))) (testing "more invalid parents" (are [tag parent] (p/thrown? (derive tag parent)) - ::tag #?(:cljs js/String :lpy python/str :default String) + ::tag #?(:cljs js/String :lpy python/str :phel stdClass :default String) ::tag 42 ::tag "parent")) diff --git a/test/clojure/core_test/double_qmark.cljc b/test/clojure/core_test/double_qmark.cljc index 54252d9d..e2c91726 100644 --- a/test/clojure/core_test/double_qmark.cljc +++ b/test/clojure/core_test/double_qmark.cljc @@ -32,6 +32,10 @@ true (float 1.0) true (float -1.0)] :lpy + [true (float 0.0) + true (float 1.0) + true (float -1.0)] + :phel [true (float 0.0) true (float 1.0) true (float -1.0)] @@ -55,6 +59,13 @@ true 0.0M true 1.0M true -1.0M] + :phel + [false 0N + false 1N + false -1N + true 0.0M + true 1.0M + true -1.0M] :default [false 0N false 1N @@ -63,6 +74,9 @@ false 1.0M false -1.0M]) #?@(:cljs [] ; CLJS doesn't have ratios + :phel [true 0/2 ; Phel handles ratios as float + true 1/2 + true -1/2] :default [false 0/2 false 1/2 diff --git a/test/clojure/core_test/eq.cljc b/test/clojure/core_test/eq.cljc index dcde3ebb..3bbf3024 100644 --- a/test/clojure/core_test/eq.cljc +++ b/test/clojure/core_test/eq.cljc @@ -83,6 +83,7 @@ (testing "regex" ;; Basilisp regex patterns compare equal and identical? #?(:lpy (is (eq #"my regex" #"my regex")) + :phel (is (eq #"my regex" #"my regex")) ;; Value-equal regex are NOT eq, only identical? :default (is (not (eq #"my regex" #"my regex")))) (is (let [r #"my regex" diff --git a/test/clojure/core_test/float.cljc b/test/clojure/core_test/float.cljc index 6b9696ba..a3a5a359 100644 --- a/test/clojure/core_test/float.cljc +++ b/test/clojure/core_test/float.cljc @@ -26,6 +26,7 @@ ;; so float returns the same value here. #?@(:cljs [r/min-double r/min-double] :lpy [r/min-double r/min-double] + :phel [r/min-double r/min-double] :default [(float 0.0) r/min-double])) (is (NaN? (float ##NaN))) diff --git a/test/clojure/core_test/float_qmark.cljc b/test/clojure/core_test/float_qmark.cljc index 80338392..8ab35ef7 100644 --- a/test/clojure/core_test/float_qmark.cljc +++ b/test/clojure/core_test/float_qmark.cljc @@ -56,10 +56,19 @@ false 0N false 1N false -1N - false 0.0M - false 1.0M - false -1.0M]) + #?@(:phel + [true 0.0M + true 1.0M + true -1.0M] + :default + [false 0.0M + false 1.0M + false -1.0M])]) #?@(:cljs [] ; CLJS doesn't have ratios + :phel + [true 0/2 + true 1/2 + true -1/2] :default [false 0/2 false 1/2 diff --git a/test/clojure/core_test/inc.cljc b/test/clojure/core_test/inc.cljc index 69131245..ca6e5f3c 100644 --- a/test/clojure/core_test/inc.cljc +++ b/test/clojure/core_test/inc.cljc @@ -27,6 +27,7 @@ #?(:clj (is (p/thrown? (inc Long/MAX_VALUE))) :cljr (is (p/thrown? (inc Int64/MaxValue))) :cljs (is (= (inc js/Number.MAX_SAFE_INTEGER) (+ 2 js/Number.MAX_SAFE_INTEGER))) + :phel (is (= (inc php/PHP_INT_MAX) (+ 2 php/PHP_INT_MAX))) :lpy nil ; Python integers cannot overflow :default (is false "overflow untested"))) diff --git a/test/clojure/core_test/int_qmark.cljc b/test/clojure/core_test/int_qmark.cljc index dfd308da..0a77199f 100644 --- a/test/clojure/core_test/int_qmark.cljc +++ b/test/clojure/core_test/int_qmark.cljc @@ -22,10 +22,13 @@ false ##Inf false ##-Inf false ##NaN - #?@(:cljs [true] :lpy [true] :default [false]) 0N - #?@(:cljs [true] :lpy [true] :default [false]) 1N - #?@(:cljs [true] :lpy [true] :default [false]) -1N + #?@(:cljs [true] :lpy [true] :phel [true] :default [false]) 0N + #?@(:cljs [true] :lpy [true] :phel [true] :default [false]) 1N + #?@(:cljs [true] :lpy [true] :phel [true] :default [false]) -1N #?@(:cljs [] + :phel [false 0/2 + false 1/2 + false -1/2] :default [true 0/2 false 1/2 diff --git a/test/clojure/core_test/integer_qmark.cljc b/test/clojure/core_test/integer_qmark.cljc index 933076ff..dad0671d 100644 --- a/test/clojure/core_test/integer_qmark.cljc +++ b/test/clojure/core_test/integer_qmark.cljc @@ -26,6 +26,10 @@ true 1N true -1N #?@(:cljs [] + :phel + [false 0/2 + false 1/2 + false -1/2] :default [true 0/2 false 1/2 diff --git a/test/clojure/core_test/key.cljc b/test/clojure/core_test/key.cljc index ce84fdee..cb524e97 100644 --- a/test/clojure/core_test/key.cljc +++ b/test/clojure/core_test/key.cljc @@ -12,6 +12,7 @@ ;; https://groups.google.com/g/clojure/c/FVcrbHJpCW4/m/Fh7NsX_Yb7sJ (is (= 'k (key #?(:cljs (cljs.core/MapEntry. 'k 'v nil) :lpy (map-entry 'k 'v) + :phel ['k 'v] ; Phel map entries are vectors :default (clojure.lang.MapEntry/create 'k 'v))))) (when-var-exists sorted-map (is (= :a (key (first (sorted-map :a :b)))))) diff --git a/test/clojure/core_test/minus.cljc b/test/clojure/core_test/minus.cljc index d11ccb8c..32b79977 100644 --- a/test/clojure/core_test/minus.cljc +++ b/test/clojure/core_test/minus.cljc @@ -106,6 +106,65 @@ #?(:cljs nil ; CLJS doesn't support ratios + :phel ; Phel evaluates ratios as float + (testing "rationals" + ;; Most comparisons fail due to float rounding + (are [expected x y equates] (= equates (= expected (- x y))) + 1/2 1 1/2 true + 1/3 1 2/3 false + 1/4 1 3/4 true + 1/5 1 4/5 false + 1/6 1 5/6 false + 1/7 1 6/7 false + 1/8 1 7/8 true + 1/9 1 8/9 false + + 1 1/2 -1/2 false + 1 1/3 -2/3 false + 1 1/4 -3/4 false + 1 1/5 -4/5 false + 1 1/6 -5/6 false + 1 1/7 -6/7 false + 1 1/8 -7/8 false + 1 1/9 -8/9 false + + 1 3/2 1/2 false + 1 5/3 2/3 false + 1 7/4 3/4 false + 1 9/5 4/5 false + 1 11/6 5/6 false + 1 13/7 6/7 false + 1 15/8 7/8 false + 1 17/9 8/9 false + + 3/2 2 1/2 true + 4/3 2 2/3 false + + 1.0 1.5 1/2 true) + + ;; Single arg + (is (= -1/2 (- 1/2))) + (is (= 1/2 (- -1/2))) + + ;; Multi arg + (is (not (= -2089/2520 (- 1 1/2 1/3 1/4 1/5 1/6 1/7 1/8 1/9)))) + + (is (p/thrown? (- nil 1/2))) + (is (p/thrown? (- 1/2 nil))) + + (is (- r/max-int -1/2)) ; test that these don't throw + (is (- r/min-int 1/2)) + (is (= (- r/max-double) (- (- r/max-double) 1/2))) + (is (= r/max-double (- r/max-double -1/2))) + (is (= -0.5 (- r/min-double 1/2))) + (is (= 0.5 (- r/min-double -1/2))) + (is (not (ratio? (- 0 1/3)))) + (is (not (ratio? (- 0N 1/3)))) + (is (not (ratio? (- 1 1/3)))) + (is (not (ratio? (- 1N 1/3)))) + + (is (float? (- 0.0 1/3))) + (is (float? (- 1.0 1/3)))) :default (testing "rationals" diff --git a/test/clojure/core_test/neg_int_qmark.cljc b/test/clojure/core_test/neg_int_qmark.cljc index c3ca1ed9..64fc361f 100644 --- a/test/clojure/core_test/neg_int_qmark.cljc +++ b/test/clojure/core_test/neg_int_qmark.cljc @@ -47,7 +47,7 @@ true -1N] :default [false -1.0 false -1.0M - #?(:lpy true :default false) -1N + #?(:lpy true :phel true :default false) -1N false 0/2 false 1/2 false -1/2])))) diff --git a/test/clojure/core_test/parents.cljc b/test/clojure/core_test/parents.cljc index 3d4f75db..fe3ddae6 100644 --- a/test/clojure/core_test/parents.cljc +++ b/test/clojure/core_test/parents.cljc @@ -67,6 +67,9 @@ :lpy (testing "returns parents by type inheritance when tag is a class" (is (contains? (parents python/str) python/object)) (is (nil? (parents python/object)))) + :phel (testing "returns parents by type inheritance when tag is a class" + (is (contains? (parents RuntimeException) Exception)) + (is (nil? (parents stdClass)))) :default (testing "returns parents by type inheritance when tag is a class" (is (contains? (parents String) Object)) (is (nil? (parents Object))))) @@ -74,8 +77,8 @@ #?(:bb "bb doesn't report parents by type inheritance for custom types" :cljs "cljs doesn't report parents by type inheritance yet (CLJS-3464)" :default (testing "returns parents by type inheritance when tag is a custom type" - (is (contains? (parents TestParentsType) #?(:lpy (:interface TestParentsProtocol) :default clojure.core_test.parents.TestParentsProtocol))) - (is (contains? (parents TestParentsRecord) #?(:lpy (:interface TestParentsProtocol) :default clojure.core_test.parents.TestParentsProtocol))) + (is (contains? (parents TestParentsType) #?(:lpy (:interface TestParentsProtocol) :phel TestParentsProtocol :default clojure.core_test.parents.TestParentsProtocol))) + (is (contains? (parents TestParentsRecord) #?(:lpy (:interface TestParentsProtocol) :phel TestParentsProtocol :default clojure.core_test.parents.TestParentsProtocol))) (is (nil? (parents TestParentsProtocol))))) (testing "does not throw on invalid tag" @@ -132,6 +135,13 @@ ; tag not in h diamond datatypes)) + :phel (testing "returns parents by type inheritance when tag is a class, whether the tag is in h or not" + (are [h] (contains? (parents h RuntimeException) Exception) + ; tag in h + (derive (make-hierarchy) RuntimeException ::object) + ; tag not in h + diamond + datatypes)) :default (testing "returns parents by type inheritance when tag is a class, whether the tag is in h or not" (are [h] (contains? (parents h String) Object) ; tag in h @@ -143,7 +153,7 @@ #?(:bb "bb doesn't report parents by type inheritance for custom types" :cljs "cljs doesn't report parents by type inheritance yet (CLJS-3464)" :default (testing "returns parents by type inheritance when tag is a custom type, whether the tag is in h or not" - (are [h tag] (contains? (parents h tag) #?(:lpy (:interface TestParentsProtocol) :default clojure.core_test.parents.TestParentsProtocol)) + (are [h tag] (contains? (parents h tag) #?(:lpy (:interface TestParentsProtocol) :phel TestParentsProtocol :default clojure.core_test.parents.TestParentsProtocol)) ; tag in h datatypes TestParentsType datatypes TestParentsRecord diff --git a/test/clojure/core_test/plus.cljc b/test/clojure/core_test/plus.cljc index 2b867de6..59b94296 100644 --- a/test/clojure/core_test/plus.cljc +++ b/test/clojure/core_test/plus.cljc @@ -105,6 +105,60 @@ #?(:cljs nil + :phel ; Phel evaluates ratios as float + (testing "rationals" + ;; Many comparisons fail due to float rounding + (are [sum x y equates] (= equates + (and (= sum (+ x y)) ; test commutativity + (= sum (+ y x)))) + 1 1/2 1/2 false + 1 1/3 2/3 false + 1 1/4 3/4 false + 1 1/5 4/5 false + 1 1/6 5/6 false + 1 1/7 6/7 false + 1 1/8 7/8 false + 1 1/9 8/9 false + + 1/2 1 -1/2 true + 1/3 1 -2/3 false + 1/4 1 -3/4 true + 1/5 1 -4/5 false + 1/6 1 -5/6 false + 1/7 1 -6/7 false + 1/8 1 -7/8 true + 1/9 1 -8/9 false + + 3/2 1 1/2 true + 5/3 1 2/3 false + 7/4 1 3/4 true + 9/5 1 4/5 true + 11/6 1 5/6 false + 13/7 1 6/7 false + 15/8 1 7/8 true + 17/9 1 8/9 false + + 2 3/2 1/2 false + 2 4/3 2/3 false + + 1.5 1.0 1/2 true) + + (is (p/thrown? (+ 1/2 nil))) + (is (p/thrown? (+ nil 1/2))) + + (is (+ r/max-int 1/2)) ; test that these don't throw + (is (+ r/min-int -1/2)) + (is (= r/max-double (+ r/max-double 1/2))) + (is (= (- r/max-double) (+ (- r/max-double) -1/2))) + (is (= 0.5 (+ r/min-double 1/2))) + (is (= -0.5 (+ r/min-double -1/2))) + (is (not (ratio? (+ 0 1/3)))) + (is (not (ratio? (+ 0N 1/3)))) + (is (not (ratio? (+ 1 1/3)))) + (is (not (ratio? (+ 1N 1/3)))) + + (is (float? (+ 0.0 1/3))) + (is (float? (+ 1.0 1/3)))) :default (testing "rationals" diff --git a/test/clojure/core_test/portability.cljc b/test/clojure/core_test/portability.cljc index 4a0f8bd6..c60085f1 100644 --- a/test/clojure/core_test/portability.cljc +++ b/test/clojure/core_test/portability.cljc @@ -18,6 +18,7 @@ ;; return true if the fractional part of the double is zero #?(:cljs (integer? n) :lpy (integer? n) + :phel (integer? n) :default (and (integer? n) (not (int? n))))) @@ -26,7 +27,8 @@ (#?(:cljr System.Threading.Thread/Sleep :cljs #(js/setTimeout identity %) :clj Thread/sleep - :lpy time/sleep) + :lpy time/sleep + :phel #(phel.async/delay (/ % 1000))) ms)) ;; --- Portable exception multimethod. --- @@ -65,6 +67,7 @@ (report-failure# failure-opts#) (catch #?(:jank ~'jank.runtime.object_ref :clj ~'Throwable + :phel ~'Throwable :default ~'Exception) e# (report-success# (success-opts# e#)) e#) diff --git a/test/clojure/core_test/pos_int_qmark.cljc b/test/clojure/core_test/pos_int_qmark.cljc index 15c303c4..be1a9dba 100644 --- a/test/clojure/core_test/pos_int_qmark.cljc +++ b/test/clojure/core_test/pos_int_qmark.cljc @@ -48,7 +48,7 @@ #?@(:cljs [true 1.0 true 1.0M] :default [false 1.0 - #?(:lpy true :default false) 1N + #?(:lpy true :phel true :default false) 1N false 0/2 false 1/2 false -1/2 diff --git a/test/clojure/core_test/print_str.cljc b/test/clojure/core_test/print_str.cljc index ec5d16f6..0baa7af5 100644 --- a/test/clojure/core_test/print_str.cljc +++ b/test/clojure/core_test/print_str.cljc @@ -6,5 +6,6 @@ (deftest test-print-str (is (= "a string" (print-str "a" "string"))) (is (= #?(:cljs "nil a string A 1 17 [:a :b] {:c :d} #{:e}" + :phel "nil a string A 1 17 [:a :b] {:c :d} #{:e}" :default "nil a string A 1 17.0 [:a :b] {:c :d} #{:e}") (print-str nil "a" "string" \A \space 1 17.0 [:a :b] {:c :d} #{:e}))))) diff --git a/test/clojure/core_test/ratio_qmark.cljc b/test/clojure/core_test/ratio_qmark.cljc index 802ba73d..0a2dd735 100644 --- a/test/clojure/core_test/ratio_qmark.cljc +++ b/test/clojure/core_test/ratio_qmark.cljc @@ -45,6 +45,7 @@ false 'a-sym #?@(:cljs [] + :phel [] :default [false 0/2 ; perhaps surprising true 1/2 diff --git a/test/clojure/core_test/reduce.cljc b/test/clojure/core_test/reduce.cljc index 5d70cc48..6a6471de 100644 --- a/test/clojure/core_test/reduce.cljc +++ b/test/clojure/core_test/reduce.cljc @@ -9,32 +9,38 @@ (#?(:clj Integer. :cljr identity :cljs js/Number. - :lpy python/int) x)) + :lpy python/int + :phel php/intval) x)) :Integer #?(:clj Integer/TYPE :cljr System.Int32 :cljs js/Number - :lpy python/int) + :lpy python/int + :phel php/intval) :Long #?(:clj Long/TYPE :cljr System.Int64 :cljs js/Number - :lpy python/int) + :lpy python/int + :phel php/intval) :Float #?(:clj Long/TYPE :cljr System.Single :cljs js/Number - :lpy python/float) + :lpy python/float + :phel php/floatval) :Double #?(:clj Double/TYPE :cljr System.Double :cljs js/Number - :lpy python/float) + :lpy python/float + :phel php/floatval) :Boolean #?(:clj Boolean/TYPE :cljr System.Boolean :cljs js/Boolean - :lpy python/bool)}) + :lpy python/bool + :phel php/boolval)}) (when-var-exists clojure.core/reduce @@ -82,6 +88,7 @@ (reduce + arange) (reduce + avec) #?(:bb 4950 + :phel 4950 :clj (.reduce ^IReduce avec +)) (reduce + alist) (reduce + obj-array) diff --git a/test/clojure/core_test/remove_watch.cljc b/test/clojure/core_test/remove_watch.cljc index 9c7bc816..c2854310 100644 --- a/test/clojure/core_test/remove_watch.cljc +++ b/test/clojure/core_test/remove_watch.cljc @@ -50,6 +50,8 @@ #?(:cljs nil + :phel ; Phel does not implement vars. + nil :default (testing "remove watch vars" @@ -103,6 +105,8 @@ ;; Basilisp does not implement refs. :lpy nil + :phel + nil :default (testing "remove watch refs" @@ -153,6 +157,8 @@ ;; Basilisp does not implement agents. :lpy nil + :phel + nil :default (testing "remove watch agents" diff --git a/test/clojure/core_test/repeat.cljc b/test/clojure/core_test/repeat.cljc index 550b1c5e..cb7dfeaa 100644 --- a/test/clojure/core_test/repeat.cljc +++ b/test/clojure/core_test/repeat.cljc @@ -19,8 +19,10 @@ 1 :a [:a] 3 :a [:a :a :a] 3.14 :a #?(:cljs [:a :a :a :a] + :phel [:a :a :a :a] :default [:a :a :a]) 3.99 :a #?(:cljs [:a :a :a :a] + :phel [:a :a :a :a] :default [:a :a :a]) 7 :a [:a :a :a :a :a :a :a] 7 nil [nil nil nil nil nil nil nil])) diff --git a/test/clojure/core_test/seqable_qmark.cljc b/test/clojure/core_test/seqable_qmark.cljc index 8c1db620..c2318e71 100644 --- a/test/clojure/core_test/seqable_qmark.cljc +++ b/test/clojure/core_test/seqable_qmark.cljc @@ -30,4 +30,4 @@ false 1.0M false :a-keyword false 'a-sym - #?(:cljs true :lpy true :default false) \a))) + #?(:cljs true :lpy true :phel true :default false) \a))) diff --git a/test/clojure/core_test/short.cljc b/test/clojure/core_test/short.cljc index 695cc35d..0f7b1164 100644 --- a/test/clojure/core_test/short.cljc +++ b/test/clojure/core_test/short.cljc @@ -11,6 +11,7 @@ (is (int? (short 0))) #?@(:cljs [] :lpy [] ; Python VMs only have one integer type. + :phel [] :default [(is (instance? #?(:clj java.lang.Short :cljr System.Int16) (short 0)))]) diff --git a/test/clojure/core_test/slash.cljc b/test/clojure/core_test/slash.cljc index 7ff4bcb4..e65b05c3 100644 --- a/test/clojure/core_test/slash.cljc +++ b/test/clojure/core_test/slash.cljc @@ -123,6 +123,7 @@ ;; Multi arg #?(:cljs (is (= 50 (/ 100 1 2))) + :phel (is (= 50 (/ 100 1 2))) :default (is (= 1/362880 (/ 1 2 3 4 5 6 7 8 9)))) #?@(:cljs @@ -136,6 +137,31 @@ #?(:cljs nil + :phel ; Phel evaluates ratios as float + (testing "rationals" + ;; Many comparisons fail due to float rounding + (are [expected x y equates] (= equates (= expected (/ x y))) + 10 10 1 true + 5 10 2 true + 10/3 10 3 false + 1 2 2 true + 4 2 1/2 false + 1/4 1/2 2 true + 4.0 2.0 1/2 true + 0.25 1/2 2.0 true + 4M 2.0M 1/2 true + 0.25M 1/2 2.0M true + ) + + ;; Single arg + (is (not (= 2N (/ 1/2)))) + (is (not (= 3N (/ 1/3)))) + + ;; Multi arg + (is (not (= 362880N (/ 1/1 1/2 1/3 1/4 1/5 1/6 1/7 1/8 1/9)))) + + (is (p/thrown? (/ 1/2 nil))) + (is (p/thrown? (/ nil 1/2)))) :default (testing "rationals" diff --git a/test/clojure/core_test/special_symbol_qmark.cljc b/test/clojure/core_test/special_symbol_qmark.cljc index 8be82f30..8cc0a968 100644 --- a/test/clojure/core_test/special_symbol_qmark.cljc +++ b/test/clojure/core_test/special_symbol_qmark.cljc @@ -9,26 +9,29 @@ (are [arg] (special-symbol? 'arg) ;; Basilisp does not recognize these as special symbols. #?@(:lpy [] + :phel [&] :default [& case* new]) - . + #?@(:phel [] + :default + [. + fn* + loop* + deftype* + set! + let* + letfn* + var]) catch def - deftype* do finally - fn* if - let* - letfn* - loop* quote recur - set! throw - try - var)) + try)) (testing "not special symbols" (are [arg] (not (special-symbol? arg)) diff --git a/test/clojure/core_test/star.cljc b/test/clojure/core_test/star.cljc index 3bcef266..090fcb57 100644 --- a/test/clojure/core_test/star.cljc +++ b/test/clojure/core_test/star.cljc @@ -107,6 +107,34 @@ #?(:cljs nil + :phel ; Phel evaluates ratios as float + (testing "rationals" + ;; Many comparisons fail due to float rounding + (are [prod x y equates] (= equates (= prod (* x y) (* y x))) + 1 1/2 2/1 false + 1 1/2 2 false + -1 1/2 -2 false + -1 -1/2 2 false + 1 -1/2 -2 false + 1.0 1/2 2.0 true + -1.0 1/2 -2.0 true + -1.0 -1/2 2.0 true + 1.0 -1/2 -2.0 true + 1 1/2 2N false + -1 1/2 -2N false + -1 -1/2 2N false + 1 -1/2 -2N false + 1.0 1/3 3.0 false + 0 1/2 0 false + 0.0 1/2 0.0 true + 0 1/2 0N false + 1/10 1/2 1/5 true + -1/10 1/2 -1/5 true + -1/10 -1/2 1/5 true + 1/10 -1/2 -1/5 true) + + (is (p/thrown? (* 1/2 nil))) + (is (p/thrown? (* nil 1/2)))) :default (testing "rationals" diff --git a/test/clojure/core_test/str.cljc b/test/clojure/core_test/str.cljc index 9c218b11..90a75323 100644 --- a/test/clojure/core_test/str.cljc +++ b/test/clojure/core_test/str.cljc @@ -51,6 +51,10 @@ ["0" 0.0M "1" 1.0M "-1" -1.0M] + :phel + ["0.0" 0.0M + "1.0" 1.0M + "-1.0" -1.0M] :default ["0" 0/2 "1/2" 1/2 diff --git a/test/clojure/core_test/string_qmark.cljc b/test/clojure/core_test/string_qmark.cljc index 8eb14745..a5c66327 100644 --- a/test/clojure/core_test/string_qmark.cljc +++ b/test/clojure/core_test/string_qmark.cljc @@ -10,6 +10,8 @@ true "0" true "1" true "-1" + ; Phel/PHP lacks class type and classes are represented as strings + #?@(:phel [true stdClass]) false 0 false 1 @@ -55,6 +57,11 @@ true \A true \space] :lpy + [true \0 + true \1 + true \A + true \space] + :phel [true \0 true \1 true \A diff --git a/test/clojure/core_test/symbol.cljc b/test/clojure/core_test/symbol.cljc index 0c5ea5d3..651790bf 100644 --- a/test/clojure/core_test/symbol.cljc +++ b/test/clojure/core_test/symbol.cljc @@ -46,9 +46,12 @@ '= '= '= := 'abc*+!-_'?<>= "abc*+!-_'?<>=" - #?(:cljs 'cljs.core/+ - :lpy 'basilisp.core/+ - :default 'clojure.core/+) #'+) + #?@(:phel ; Phel doesn't support vars yet + [] ; TODO https://github.com/phel-lang/phel-lang/issues/1717 + :default + [#?(:cljs 'cljs.core/+ + :lpy 'basilisp.core/+ + :default 'clojure.core/+) #'+])) (are [expected ns name] (= expected (symbol ns name)) 'abc/abc "abc" "abc" diff --git a/test/clojure/core_test/taps.cljc b/test/clojure/core_test/taps.cljc index 9c456719..7f02e6aa 100644 --- a/test/clojure/core_test/taps.cljc +++ b/test/clojure/core_test/taps.cljc @@ -66,7 +66,7 @@ (defn tap-tester [atom-ref] (fn [x] - (if (instance? #?(:lpy basilisp.lang.interfaces/IPending :default clojure.lang.IPending) x) + (if (instance? #?(:lpy basilisp.lang.interfaces/IPending :phel Phel.Fiber.Domain.Awaitable :default clojure.lang.IPending) x) (deliver x nil) (swap! atom-ref conj x)))) diff --git a/test/clojure/core_test/uuid_qmark.cljc b/test/clojure/core_test/uuid_qmark.cljc index 37b420ba..745b1c09 100644 --- a/test/clojure/core_test/uuid_qmark.cljc +++ b/test/clojure/core_test/uuid_qmark.cljc @@ -25,7 +25,10 @@ -1.0 ##NaN ##Inf - "f81d4fae-7dec-11d0-a765-00a0c91e6bf6" + #?@(:phel ; Phel UUIDs are strings so the default evals true + ["f00f00-f00-f00-f00-f00f00f00"] + :default + ["f81d4fae-7dec-11d0-a765-00a0c91e6bf6"]) {:a :map} #{:a-set} [:a :vector] diff --git a/test/clojure/core_test/val.cljc b/test/clojure/core_test/val.cljc index bf2ada33..e2e1236f 100644 --- a/test/clojure/core_test/val.cljc +++ b/test/clojure/core_test/val.cljc @@ -11,6 +11,7 @@ ;; https://groups.google.com/g/clojure/c/FVcrbHJpCW4/m/Fh7NsX_Yb7sJ (is (= 'v (val #?(:cljs (cljs.core/MapEntry. 'k 'v nil) :lpy (map-entry 'k 'v) + :phel ['k 'v] ; Phel represents map entries as vectors :default (clojure.lang.MapEntry/create 'k 'v))))) (is (= :b (val (first (hash-map :a :b))))) (when-var-exists sorted-map diff --git a/test/clojure/core_test/var_qmark.cljc b/test/clojure/core_test/var_qmark.cljc index c58225ef..7bb18a89 100644 --- a/test/clojure/core_test/var_qmark.cljc +++ b/test/clojure/core_test/var_qmark.cljc @@ -14,57 +14,62 @@ (when-var-exists defprotocol (defprotocol MyProtocol)) -(when-var-exists var? - (deftest test-var? - (testing "things which are vars" - (are [v] (var? v) - #'foo ; locally-defined - #'var? ; clojure.core - #'i-am-dynamic ; dynamic & local - #'*assert* ; dynamic - #?@(; CLJS `def` doesn't necessarily evaluate to the value of the var: - :cljs [], - :default [(def baz)]) - #?@(; CLJS `defn` produces a non-var - :cljs [], - :default [(defn qux [] nil)])) +;; Phel doesn't have vars yet but it has irrelevant `var?` function (deprecated) +;; https://github.com/phel-lang/phel-lang/issues/1717 +#?(:phel nil + :default + (when-var-exists var? + (deftest test-var? + (testing "things which are vars" + (are [v] (var? v) + #'foo ; locally-defined + #'var? ; clojure.core + #'i-am-dynamic ; dynamic & local + #'*assert* ; dynamic + #?@(; CLJS `def` doesn't necessarily evaluate to the value of the var: + :cljs [], + :default [(def baz)]) + #?@(; CLJS `defn` produces a non-var + :cljs [], + :default [(defn qux [] nil)])) - (when-var-exists defmulti - (is (var? #'bar))) - - (when-var-exists defprotocol - (is (var? #'MyProtocol)))) + (when-var-exists defmulti + (is (var? #'bar))) - (testing "var-adjacent things" - (are [not-a-var] (not (var? not-a-var)) - foo - var? - i-am-dynamic - 'foo - 'var? - 'i-am-dynamic - *assert* - #(+ 1 %) - (fn baz [x] x))) + (when-var-exists defprotocol + (is (var? #'MyProtocol)))) - (testing "things which are clearly not vars" - (are [v] (not (var? v)) - 'sym - `sym - "abc" - 999 - 1.2 - #?@(:cljs [], ; most Clojure dialects support ratios - not CLJS - :default [2/3]) - \backspace - nil - true - false - :keyword - :namespace/keyword - '(one two three) - [4 5 6] - {:7 "8"} - (zipmap (take 100 (range)) - (cycle ['foo 'bar 'baz 'qux])) - #{:a :b "c"})))) + (testing "var-adjacent things" + (are [not-a-var] (not (var? not-a-var)) + foo + var? + i-am-dynamic + 'foo + 'var? + 'i-am-dynamic + *assert* + #(+ 1 %) + (fn baz [x] x))) + + (testing "things which are clearly not vars" + (are [v] (not (var? v)) + 'sym + `sym + "abc" + 999 + 1.2 + #?@(:cljs [] ; most Clojure dialects support ratios - not CLJS or Phel + :phel [] + :default [2/3]) + \backspace + nil + true + false + :keyword + :namespace/keyword + '(one two three) + [4 5 6] + {:7 "8"} + (zipmap (take 100 (range)) + (cycle ['foo 'bar 'baz 'qux])) + #{:a :b "c"}))))) diff --git a/test/clojure/core_test/vec.cljc b/test/clojure/core_test/vec.cljc index 9b288f5b..da2d12c1 100644 --- a/test/clojure/core_test/vec.cljc +++ b/test/clojure/core_test/vec.cljc @@ -25,6 +25,7 @@ #?(:cljr "cljr does not alias array" :lpy "Basilisp does not alias array" + :phel "Phel does not alias array" :default (testing "array aliasing" (let [arr (to-array [1 2 3]), v (vec arr)] (is (= [1 2 3] v)) From 6a27dace409b3d9db1ea0aee13f6bc0ae3325c31 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Tue, 5 May 2026 16:16:51 +0300 Subject: [PATCH 02/20] Enable tests related to vars for Phel --- test/clojure/core_test/remove_watch.cljc | 2 - .../core_test/special_symbol_qmark.cljc | 4 +- test/clojure/core_test/symbol.cljc | 10 +- test/clojure/core_test/var_qmark.cljc | 107 +++++++++--------- 4 files changed, 57 insertions(+), 66 deletions(-) diff --git a/test/clojure/core_test/remove_watch.cljc b/test/clojure/core_test/remove_watch.cljc index c2854310..f564c94a 100644 --- a/test/clojure/core_test/remove_watch.cljc +++ b/test/clojure/core_test/remove_watch.cljc @@ -50,8 +50,6 @@ #?(:cljs nil - :phel ; Phel does not implement vars. - nil :default (testing "remove watch vars" diff --git a/test/clojure/core_test/special_symbol_qmark.cljc b/test/clojure/core_test/special_symbol_qmark.cljc index 8cc0a968..4f47a8e6 100644 --- a/test/clojure/core_test/special_symbol_qmark.cljc +++ b/test/clojure/core_test/special_symbol_qmark.cljc @@ -21,8 +21,8 @@ deftype* set! let* - letfn* - var]) + letfn*]) + var catch def do diff --git a/test/clojure/core_test/symbol.cljc b/test/clojure/core_test/symbol.cljc index 651790bf..63826a8f 100644 --- a/test/clojure/core_test/symbol.cljc +++ b/test/clojure/core_test/symbol.cljc @@ -46,12 +46,10 @@ '= '= '= := 'abc*+!-_'?<>= "abc*+!-_'?<>=" - #?@(:phel ; Phel doesn't support vars yet - [] ; TODO https://github.com/phel-lang/phel-lang/issues/1717 - :default - [#?(:cljs 'cljs.core/+ - :lpy 'basilisp.core/+ - :default 'clojure.core/+) #'+])) + #?(:cljs 'cljs.core/+ + :lpy 'basilisp.core/+ + :phel 'phel.core/+ + :default 'clojure.core/+) #'+) (are [expected ns name] (= expected (symbol ns name)) 'abc/abc "abc" "abc" diff --git a/test/clojure/core_test/var_qmark.cljc b/test/clojure/core_test/var_qmark.cljc index 7bb18a89..c58225ef 100644 --- a/test/clojure/core_test/var_qmark.cljc +++ b/test/clojure/core_test/var_qmark.cljc @@ -14,62 +14,57 @@ (when-var-exists defprotocol (defprotocol MyProtocol)) -;; Phel doesn't have vars yet but it has irrelevant `var?` function (deprecated) -;; https://github.com/phel-lang/phel-lang/issues/1717 -#?(:phel nil - :default - (when-var-exists var? - (deftest test-var? - (testing "things which are vars" - (are [v] (var? v) - #'foo ; locally-defined - #'var? ; clojure.core - #'i-am-dynamic ; dynamic & local - #'*assert* ; dynamic - #?@(; CLJS `def` doesn't necessarily evaluate to the value of the var: - :cljs [], - :default [(def baz)]) - #?@(; CLJS `defn` produces a non-var - :cljs [], - :default [(defn qux [] nil)])) +(when-var-exists var? + (deftest test-var? + (testing "things which are vars" + (are [v] (var? v) + #'foo ; locally-defined + #'var? ; clojure.core + #'i-am-dynamic ; dynamic & local + #'*assert* ; dynamic + #?@(; CLJS `def` doesn't necessarily evaluate to the value of the var: + :cljs [], + :default [(def baz)]) + #?@(; CLJS `defn` produces a non-var + :cljs [], + :default [(defn qux [] nil)])) - (when-var-exists defmulti - (is (var? #'bar))) + (when-var-exists defmulti + (is (var? #'bar))) + + (when-var-exists defprotocol + (is (var? #'MyProtocol)))) - (when-var-exists defprotocol - (is (var? #'MyProtocol)))) + (testing "var-adjacent things" + (are [not-a-var] (not (var? not-a-var)) + foo + var? + i-am-dynamic + 'foo + 'var? + 'i-am-dynamic + *assert* + #(+ 1 %) + (fn baz [x] x))) - (testing "var-adjacent things" - (are [not-a-var] (not (var? not-a-var)) - foo - var? - i-am-dynamic - 'foo - 'var? - 'i-am-dynamic - *assert* - #(+ 1 %) - (fn baz [x] x))) - - (testing "things which are clearly not vars" - (are [v] (not (var? v)) - 'sym - `sym - "abc" - 999 - 1.2 - #?@(:cljs [] ; most Clojure dialects support ratios - not CLJS or Phel - :phel [] - :default [2/3]) - \backspace - nil - true - false - :keyword - :namespace/keyword - '(one two three) - [4 5 6] - {:7 "8"} - (zipmap (take 100 (range)) - (cycle ['foo 'bar 'baz 'qux])) - #{:a :b "c"}))))) + (testing "things which are clearly not vars" + (are [v] (not (var? v)) + 'sym + `sym + "abc" + 999 + 1.2 + #?@(:cljs [], ; most Clojure dialects support ratios - not CLJS + :default [2/3]) + \backspace + nil + true + false + :keyword + :namespace/keyword + '(one two three) + [4 5 6] + {:7 "8"} + (zipmap (take 100 (range)) + (cycle ['foo 'bar 'baz 'qux])) + #{:a :b "c"})))) From 68c3b2dddb6940092ca22722597d8cc15cb2dd38 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Wed, 6 May 2026 16:39:55 +0300 Subject: [PATCH 03/20] Skip worthless aclone and uuid Phel tests --- test/clojure/core_test/aclone.cljc | 4 +--- test/clojure/core_test/uuid_qmark.cljc | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/test/clojure/core_test/aclone.cljc b/test/clojure/core_test/aclone.cljc index 257defc2..9ef100d4 100644 --- a/test/clojure/core_test/aclone.cljc +++ b/test/clojure/core_test/aclone.cljc @@ -15,9 +15,7 @@ (is (zero? (alength b'))) ;; Phel PHP arrays are value types without reference-identity concept ;; https://github.com/phel-lang/phel-lang/issues/1735 - #?@(:phel - [(is (identical? a a')) - (is (identical? b b'))] + #?@(:phel [] :default [(is (not (identical? a a'))) (is (not (identical? b b')))]) diff --git a/test/clojure/core_test/uuid_qmark.cljc b/test/clojure/core_test/uuid_qmark.cljc index 745b1c09..e1028c90 100644 --- a/test/clojure/core_test/uuid_qmark.cljc +++ b/test/clojure/core_test/uuid_qmark.cljc @@ -25,10 +25,8 @@ -1.0 ##NaN ##Inf - #?@(:phel ; Phel UUIDs are strings so the default evals true - ["f00f00-f00-f00-f00-f00f00f00"] - :default - ["f81d4fae-7dec-11d0-a765-00a0c91e6bf6"]) + #?@(:phel [] ; Phel UUIDs are strings so the default evals true + :default ["f81d4fae-7dec-11d0-a765-00a0c91e6bf6"]) {:a :map} #{:a-set} [:a :vector] From 3ce6e836ccd4534ab80be23b37738ad5ea2f2ca2 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Wed, 6 May 2026 17:22:42 +0300 Subject: [PATCH 04/20] Enable rational number tests for Phel Feature added, ref: https://github.com/phel-lang/phel-lang/issues/1825 --- test/clojure/core_test/double_qmark.cljc | 3 -- test/clojure/core_test/int_qmark.cljc | 5 +- test/clojure/core_test/integer_qmark.cljc | 4 -- test/clojure/core_test/minus.cljc | 59 ----------------------- test/clojure/core_test/plus.cljc | 54 --------------------- test/clojure/core_test/ratio_qmark.cljc | 1 - test/clojure/core_test/slash.cljc | 26 ---------- test/clojure/core_test/star.cljc | 28 ----------- 8 files changed, 1 insertion(+), 179 deletions(-) diff --git a/test/clojure/core_test/double_qmark.cljc b/test/clojure/core_test/double_qmark.cljc index e2c91726..f55e3513 100644 --- a/test/clojure/core_test/double_qmark.cljc +++ b/test/clojure/core_test/double_qmark.cljc @@ -74,9 +74,6 @@ false 1.0M false -1.0M]) #?@(:cljs [] ; CLJS doesn't have ratios - :phel [true 0/2 ; Phel handles ratios as float - true 1/2 - true -1/2] :default [false 0/2 false 1/2 diff --git a/test/clojure/core_test/int_qmark.cljc b/test/clojure/core_test/int_qmark.cljc index 0a77199f..3e7bfaa8 100644 --- a/test/clojure/core_test/int_qmark.cljc +++ b/test/clojure/core_test/int_qmark.cljc @@ -26,11 +26,8 @@ #?@(:cljs [true] :lpy [true] :phel [true] :default [false]) 1N #?@(:cljs [true] :lpy [true] :phel [true] :default [false]) -1N #?@(:cljs [] - :phel [false 0/2 - false 1/2 - false -1/2] :default - [true 0/2 + [true 0/2 false 1/2 false -1/2]) #?@(:cljs [true] :default [false]) 0.0M diff --git a/test/clojure/core_test/integer_qmark.cljc b/test/clojure/core_test/integer_qmark.cljc index dad0671d..933076ff 100644 --- a/test/clojure/core_test/integer_qmark.cljc +++ b/test/clojure/core_test/integer_qmark.cljc @@ -26,10 +26,6 @@ true 1N true -1N #?@(:cljs [] - :phel - [false 0/2 - false 1/2 - false -1/2] :default [true 0/2 false 1/2 diff --git a/test/clojure/core_test/minus.cljc b/test/clojure/core_test/minus.cljc index 32b79977..d11ccb8c 100644 --- a/test/clojure/core_test/minus.cljc +++ b/test/clojure/core_test/minus.cljc @@ -106,65 +106,6 @@ #?(:cljs nil ; CLJS doesn't support ratios - :phel ; Phel evaluates ratios as float - (testing "rationals" - ;; Most comparisons fail due to float rounding - (are [expected x y equates] (= equates (= expected (- x y))) - 1/2 1 1/2 true - 1/3 1 2/3 false - 1/4 1 3/4 true - 1/5 1 4/5 false - 1/6 1 5/6 false - 1/7 1 6/7 false - 1/8 1 7/8 true - 1/9 1 8/9 false - - 1 1/2 -1/2 false - 1 1/3 -2/3 false - 1 1/4 -3/4 false - 1 1/5 -4/5 false - 1 1/6 -5/6 false - 1 1/7 -6/7 false - 1 1/8 -7/8 false - 1 1/9 -8/9 false - - 1 3/2 1/2 false - 1 5/3 2/3 false - 1 7/4 3/4 false - 1 9/5 4/5 false - 1 11/6 5/6 false - 1 13/7 6/7 false - 1 15/8 7/8 false - 1 17/9 8/9 false - - 3/2 2 1/2 true - 4/3 2 2/3 false - - 1.0 1.5 1/2 true) - - ;; Single arg - (is (= -1/2 (- 1/2))) - (is (= 1/2 (- -1/2))) - - ;; Multi arg - (is (not (= -2089/2520 (- 1 1/2 1/3 1/4 1/5 1/6 1/7 1/8 1/9)))) - - (is (p/thrown? (- nil 1/2))) - (is (p/thrown? (- 1/2 nil))) - - (is (- r/max-int -1/2)) ; test that these don't throw - (is (- r/min-int 1/2)) - (is (= (- r/max-double) (- (- r/max-double) 1/2))) - (is (= r/max-double (- r/max-double -1/2))) - (is (= -0.5 (- r/min-double 1/2))) - (is (= 0.5 (- r/min-double -1/2))) - (is (not (ratio? (- 0 1/3)))) - (is (not (ratio? (- 0N 1/3)))) - (is (not (ratio? (- 1 1/3)))) - (is (not (ratio? (- 1N 1/3)))) - - (is (float? (- 0.0 1/3))) - (is (float? (- 1.0 1/3)))) :default (testing "rationals" diff --git a/test/clojure/core_test/plus.cljc b/test/clojure/core_test/plus.cljc index 59b94296..2b867de6 100644 --- a/test/clojure/core_test/plus.cljc +++ b/test/clojure/core_test/plus.cljc @@ -105,60 +105,6 @@ #?(:cljs nil - :phel ; Phel evaluates ratios as float - (testing "rationals" - ;; Many comparisons fail due to float rounding - (are [sum x y equates] (= equates - (and (= sum (+ x y)) ; test commutativity - (= sum (+ y x)))) - 1 1/2 1/2 false - 1 1/3 2/3 false - 1 1/4 3/4 false - 1 1/5 4/5 false - 1 1/6 5/6 false - 1 1/7 6/7 false - 1 1/8 7/8 false - 1 1/9 8/9 false - - 1/2 1 -1/2 true - 1/3 1 -2/3 false - 1/4 1 -3/4 true - 1/5 1 -4/5 false - 1/6 1 -5/6 false - 1/7 1 -6/7 false - 1/8 1 -7/8 true - 1/9 1 -8/9 false - - 3/2 1 1/2 true - 5/3 1 2/3 false - 7/4 1 3/4 true - 9/5 1 4/5 true - 11/6 1 5/6 false - 13/7 1 6/7 false - 15/8 1 7/8 true - 17/9 1 8/9 false - - 2 3/2 1/2 false - 2 4/3 2/3 false - - 1.5 1.0 1/2 true) - - (is (p/thrown? (+ 1/2 nil))) - (is (p/thrown? (+ nil 1/2))) - - (is (+ r/max-int 1/2)) ; test that these don't throw - (is (+ r/min-int -1/2)) - (is (= r/max-double (+ r/max-double 1/2))) - (is (= (- r/max-double) (+ (- r/max-double) -1/2))) - (is (= 0.5 (+ r/min-double 1/2))) - (is (= -0.5 (+ r/min-double -1/2))) - (is (not (ratio? (+ 0 1/3)))) - (is (not (ratio? (+ 0N 1/3)))) - (is (not (ratio? (+ 1 1/3)))) - (is (not (ratio? (+ 1N 1/3)))) - - (is (float? (+ 0.0 1/3))) - (is (float? (+ 1.0 1/3)))) :default (testing "rationals" diff --git a/test/clojure/core_test/ratio_qmark.cljc b/test/clojure/core_test/ratio_qmark.cljc index 0a2dd735..802ba73d 100644 --- a/test/clojure/core_test/ratio_qmark.cljc +++ b/test/clojure/core_test/ratio_qmark.cljc @@ -45,7 +45,6 @@ false 'a-sym #?@(:cljs [] - :phel [] :default [false 0/2 ; perhaps surprising true 1/2 diff --git a/test/clojure/core_test/slash.cljc b/test/clojure/core_test/slash.cljc index e65b05c3..7ff4bcb4 100644 --- a/test/clojure/core_test/slash.cljc +++ b/test/clojure/core_test/slash.cljc @@ -123,7 +123,6 @@ ;; Multi arg #?(:cljs (is (= 50 (/ 100 1 2))) - :phel (is (= 50 (/ 100 1 2))) :default (is (= 1/362880 (/ 1 2 3 4 5 6 7 8 9)))) #?@(:cljs @@ -137,31 +136,6 @@ #?(:cljs nil - :phel ; Phel evaluates ratios as float - (testing "rationals" - ;; Many comparisons fail due to float rounding - (are [expected x y equates] (= equates (= expected (/ x y))) - 10 10 1 true - 5 10 2 true - 10/3 10 3 false - 1 2 2 true - 4 2 1/2 false - 1/4 1/2 2 true - 4.0 2.0 1/2 true - 0.25 1/2 2.0 true - 4M 2.0M 1/2 true - 0.25M 1/2 2.0M true - ) - - ;; Single arg - (is (not (= 2N (/ 1/2)))) - (is (not (= 3N (/ 1/3)))) - - ;; Multi arg - (is (not (= 362880N (/ 1/1 1/2 1/3 1/4 1/5 1/6 1/7 1/8 1/9)))) - - (is (p/thrown? (/ 1/2 nil))) - (is (p/thrown? (/ nil 1/2)))) :default (testing "rationals" diff --git a/test/clojure/core_test/star.cljc b/test/clojure/core_test/star.cljc index 090fcb57..3bcef266 100644 --- a/test/clojure/core_test/star.cljc +++ b/test/clojure/core_test/star.cljc @@ -107,34 +107,6 @@ #?(:cljs nil - :phel ; Phel evaluates ratios as float - (testing "rationals" - ;; Many comparisons fail due to float rounding - (are [prod x y equates] (= equates (= prod (* x y) (* y x))) - 1 1/2 2/1 false - 1 1/2 2 false - -1 1/2 -2 false - -1 -1/2 2 false - 1 -1/2 -2 false - 1.0 1/2 2.0 true - -1.0 1/2 -2.0 true - -1.0 -1/2 2.0 true - 1.0 -1/2 -2.0 true - 1 1/2 2N false - -1 1/2 -2N false - -1 -1/2 2N false - 1 -1/2 -2N false - 1.0 1/3 3.0 false - 0 1/2 0 false - 0.0 1/2 0.0 true - 0 1/2 0N false - 1/10 1/2 1/5 true - -1/10 1/2 -1/5 true - -1/10 -1/2 1/5 true - 1/10 -1/2 -1/5 true) - - (is (p/thrown? (* 1/2 nil))) - (is (p/thrown? (* nil 1/2)))) :default (testing "rationals" From 382ab6d730ac732ae07e1866156d538bab680804 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Wed, 6 May 2026 19:39:37 +0300 Subject: [PATCH 05/20] Change decimal? fn usage to double? with Phel (not implemented) --- test/clojure/core_test/mod.cljc | 13 +++++++ test/clojure/core_test/quot.cljc | 13 +++++++ test/clojure/core_test/rem.cljc | 63 +++++++++++++++++++------------- 3 files changed, 64 insertions(+), 25 deletions(-) diff --git a/test/clojure/core_test/mod.cljc b/test/clojure/core_test/mod.cljc index 30ca09a8..f1d2838d 100644 --- a/test/clojure/core_test/mod.cljc +++ b/test/clojure/core_test/mod.cljc @@ -48,6 +48,19 @@ ;; CLJS can read big decimals at the reader, but just converts ;; them to doubles. #?@(:cljs + [double? 1.0M 10 3.0M + double? 2.0M -10 3.0M + double? -1.0M -10 -3.0M + double? -2.0M 10 -3.0M + double? 1.0M 10.0M 3 + double? 2.0M -10.0M 3 + double? -1.0M -10.0M -3 + double? -2.0M 10.0M -3 + double? 1.0M 10.0M 3.0M + double? 2.0M -10.0M 3.0M + double? -1.0M -10.0M -3.0M + double? -2.0M 10.0M -3.0M] + :phel [double? 1.0M 10 3.0M double? 2.0M -10 3.0M double? -1.0M -10 -3.0M diff --git a/test/clojure/core_test/quot.cljc b/test/clojure/core_test/quot.cljc index 5bf76f98..f6594e90 100644 --- a/test/clojure/core_test/quot.cljc +++ b/test/clojure/core_test/quot.cljc @@ -40,6 +40,19 @@ double? -3.0 10.0 -3.0 #?@(:cljs + [double? 3.0M 10 3.0M + double? -3.0M -10 3.0M + double? 3.0M -10 -3.0M + double? -3.0M 10 -3.0M + double? 3.0M 10.0M 3 + double? -3.0M -10.0M 3 + double? 3.0M -10.0M -3 + double? -3.0M 10.0M -3 + double? 3.0M 10.0M 3.0M + double? -3.0M -10.0M 3.0M + double? 3.0M -10.0M -3.0M + double? -3.0M 10.0M -3.0M] + :phel [double? 3.0M 10 3.0M double? -3.0M -10 3.0M double? 3.0M -10 -3.0M diff --git a/test/clojure/core_test/rem.cljc b/test/clojure/core_test/rem.cljc index ac623e1f..8f3deba1 100644 --- a/test/clojure/core_test/rem.cljc +++ b/test/clojure/core_test/rem.cljc @@ -40,31 +40,44 @@ double? 1.0 10.0 -3.0 #?@(:cljs - [double? 1.0M 10 3.0M - double? -1.0M -10 3.0M - double? -1.0M -10 -3.0M - double? 1.0M 10 -3.0M - double? 1.0M 10.0M 3 - double? -1.0M -10.0M 3 - double? -1.0M -10.0M -3 - double? 1.0M 10.0M -3 - double? 1.0M 10.0M 3.0M - double? -1.0M -10.0M 3.0M - double? -1.0M -10.0M -3.0M - double? 1.0M 10.0M -3.0M] - :default - [decimal? 1.0M 10 3.0M - decimal? -1.0M -10 3.0M - decimal? -1.0M -10 -3.0M - decimal? 1.0M 10 -3.0M - decimal? 1.0M 10.0M 3 - decimal? -1.0M -10.0M 3 - decimal? -1.0M -10.0M -3 - decimal? 1.0M 10.0M -3 - decimal? 1.0M 10.0M 3.0M - decimal? -1.0M -10.0M 3.0M - decimal? -1.0M -10.0M -3.0M - decimal? 1.0M 10.0M -3.0M]) + [double? 1.0M 10 3.0M + double? -1.0M -10 3.0M + double? -1.0M -10 -3.0M + double? 1.0M 10 -3.0M + double? 1.0M 10.0M 3 + double? -1.0M -10.0M 3 + double? -1.0M -10.0M -3 + double? 1.0M 10.0M -3 + double? 1.0M 10.0M 3.0M + double? -1.0M -10.0M 3.0M + double? -1.0M -10.0M -3.0M + double? 1.0M 10.0M -3.0M] + :phel + [double? 1.0M 10 3.0M + double? -1.0M -10 3.0M + double? -1.0M -10 -3.0M + double? 1.0M 10 -3.0M + double? 1.0M 10.0M 3 + double? -1.0M -10.0M 3 + double? -1.0M -10.0M -3 + double? 1.0M 10.0M -3 + double? 1.0M 10.0M 3.0M + double? -1.0M -10.0M 3.0M + double? -1.0M -10.0M -3.0M + double? 1.0M 10.0M -3.0M] + :default + [decimal? 1.0M 10 3.0M + decimal? -1.0M -10 3.0M + decimal? -1.0M -10 -3.0M + decimal? 1.0M 10 -3.0M + decimal? 1.0M 10.0M 3 + decimal? -1.0M -10.0M 3 + decimal? -1.0M -10.0M -3 + decimal? 1.0M 10.0M -3 + decimal? 1.0M 10.0M 3.0M + decimal? -1.0M -10.0M 3.0M + decimal? -1.0M -10.0M -3.0M + decimal? 1.0M 10.0M -3.0M]) ;; Unexpectedly downconverts result to double, rather than BigDecimal double? 1.0 10.0M 3.0 From e229373280e8ec9b5cf5022d501fe9ca1bd3dd82 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Wed, 6 May 2026 20:23:53 +0300 Subject: [PATCH 06/20] Update inc.cljc overflow test after BigInteger added to Phel --- test/clojure/core_test/inc.cljc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/clojure/core_test/inc.cljc b/test/clojure/core_test/inc.cljc index ca6e5f3c..76661d40 100644 --- a/test/clojure/core_test/inc.cljc +++ b/test/clojure/core_test/inc.cljc @@ -27,7 +27,8 @@ #?(:clj (is (p/thrown? (inc Long/MAX_VALUE))) :cljr (is (p/thrown? (inc Int64/MaxValue))) :cljs (is (= (inc js/Number.MAX_SAFE_INTEGER) (+ 2 js/Number.MAX_SAFE_INTEGER))) - :phel (is (= (inc php/PHP_INT_MAX) (+ 2 php/PHP_INT_MAX))) + ;; Phel integers avoid overflow by being promoted to BigInteger + :phel nil (is (not (= (inc php/PHP_INT_MAX) (+ 2 php/PHP_INT_MAX)))) :lpy nil ; Python integers cannot overflow :default (is false "overflow untested"))) From 9c53174380f5d1cc3a2a2b9554880e0d8062fce0 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Wed, 6 May 2026 20:35:21 +0300 Subject: [PATCH 07/20] Update float_qmark.cljc with Phel rationals support, improve style --- test/clojure/core_test/float_qmark.cljc | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/test/clojure/core_test/float_qmark.cljc b/test/clojure/core_test/float_qmark.cljc index 8ab35ef7..c8d310a6 100644 --- a/test/clojure/core_test/float_qmark.cljc +++ b/test/clojure/core_test/float_qmark.cljc @@ -55,20 +55,16 @@ false r/min-int false 0N false 1N - false -1N - #?@(:phel - [true 0.0M - true 1.0M - true -1.0M] - :default - [false 0.0M - false 1.0M - false -1.0M])]) + false -1N]) + #?@(:phel ; Phel doesn't have BigDecimal + [true 0.0M + true 1.0M + true -1.0M] + :default + [false 0.0M + false 1.0M + false -1.0M]) #?@(:cljs [] ; CLJS doesn't have ratios - :phel - [true 0/2 - true 1/2 - true -1/2] :default [false 0/2 false 1/2 From a6e9e7f4e025a20c8f1802ce09d1c5753f2524fe Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Wed, 6 May 2026 21:11:16 +0300 Subject: [PATCH 08/20] number_range.cljc: add Phel's PHP values --- test/clojure/core_test/number_range.cljc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/clojure/core_test/number_range.cljc b/test/clojure/core_test/number_range.cljc index 3caf2017..fb53dc12 100644 --- a/test/clojure/core_test/number_range.cljc +++ b/test/clojure/core_test/number_range.cljc @@ -5,12 +5,14 @@ (def ^:const max-int #?(:clj Long/MAX_VALUE :cljr Int64/MaxValue :cljs js/Number.MAX_SAFE_INTEGER + :phel php/PHP_INT_MAX :jank (#cpp (:member (std.numeric_limits jank.i64) max)) :default 0x7FFFFFFFFFFFFFFF)) (def ^:const min-int #?(:clj Long/MIN_VALUE :cljr Int64/MinValue :cljs js/Number.MIN_SAFE_INTEGER + :phel php/PHP_INT_MIN :jank (#cpp (:member (std.numeric_limits jank.i64) min)) :default -0x8000000000000000)) @@ -26,6 +28,7 @@ (def ^:const max-double #?(:clj Double/MAX_VALUE :cljr Double/MaxValue :cljs js/Number.MAX_VALUE + :phel php/PHP_FLOAT_MAX :lpy (.-max sys/float-info) :jank (#cpp (:member (std.numeric_limits jank.f64) max)) :default 1.7976931348623157e+308)) @@ -33,6 +36,7 @@ (def ^:const min-double #?(:clj Double/MIN_VALUE :cljr Double/Epsilon ; NOTE: definitely not Double/MinValue -- ouch! :cljs js/Number.MIN_VALUE + :phel php/PHP_FLOAT_MIN :lpy (.-min sys/float_info) :jank (#cpp (:member (std.numeric_limits jank.f64) min)) :default 4.9e-324)) From f86b7402f37849a5fa16c0b8ac425ccc68ab9026 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Wed, 6 May 2026 22:43:27 +0300 Subject: [PATCH 09/20] Fix conditional failures breaking CLJS and Basilisp closing: https://github.com/phel-lang/clojure-test-suite/issues/13 --- test/clojure/core_test/float_qmark.cljc | 33 ++++++++++++++++++++----- test/clojure/core_test/inc.cljc | 2 +- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/test/clojure/core_test/float_qmark.cljc b/test/clojure/core_test/float_qmark.cljc index c8d310a6..9a80bfe8 100644 --- a/test/clojure/core_test/float_qmark.cljc +++ b/test/clojure/core_test/float_qmark.cljc @@ -32,7 +32,7 @@ true 0.0M true 1.0M true -1.0M] - :default + :phel [true 0.0 true 1.0 true -1.0 @@ -47,7 +47,6 @@ true ##Inf true ##-Inf true ##NaN - false 0 false 1 false -1 @@ -55,13 +54,35 @@ false r/min-int false 0N false 1N - false -1N]) - #?@(:phel ; Phel doesn't have BigDecimal - [true 0.0M + false -1N + true 0.0M ; Phel doesn't have BigDecimal true 1.0M true -1.0M] :default - [false 0.0M + [true 0.0 + true 1.0 + true -1.0 + true (float 0.0) + true (float 1.0) + true (float -1.0) + true (double 0.0) + true (double 1.0) + true (double -1.0) + true r/max-double + true r/min-double + true ##Inf + true ##-Inf + true ##NaN + + false 0 + false 1 + false -1 + false r/max-int + false r/min-int + false 0N + false 1N + false -1N + false 0.0M false 1.0M false -1.0M]) #?@(:cljs [] ; CLJS doesn't have ratios diff --git a/test/clojure/core_test/inc.cljc b/test/clojure/core_test/inc.cljc index 76661d40..37cec00a 100644 --- a/test/clojure/core_test/inc.cljc +++ b/test/clojure/core_test/inc.cljc @@ -28,7 +28,7 @@ :cljr (is (p/thrown? (inc Int64/MaxValue))) :cljs (is (= (inc js/Number.MAX_SAFE_INTEGER) (+ 2 js/Number.MAX_SAFE_INTEGER))) ;; Phel integers avoid overflow by being promoted to BigInteger - :phel nil (is (not (= (inc php/PHP_INT_MAX) (+ 2 php/PHP_INT_MAX)))) + :phel (is (not (= (inc php/PHP_INT_MAX) (+ 2 php/PHP_INT_MAX)))) :lpy nil ; Python integers cannot overflow :default (is false "overflow untested"))) From ff53354a82b951c7f410fb843b06dd521b648632 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Thu, 7 May 2026 00:05:26 +0300 Subject: [PATCH 10/20] General style changes reducing amount of reader aconditionals --- test/clojure/core_test/int_qmark.cljc | 129 +++++++++++------- test/clojure/core_test/neg_int_qmark.cljc | 14 +- test/clojure/core_test/pos_int_qmark.cljc | 14 +- test/clojure/core_test/seqable_qmark.cljc | 30 ++-- .../core_test/special_symbol_qmark.cljc | 21 +-- 5 files changed, 139 insertions(+), 69 deletions(-) diff --git a/test/clojure/core_test/int_qmark.cljc b/test/clojure/core_test/int_qmark.cljc index 3e7bfaa8..435c14f5 100644 --- a/test/clojure/core_test/int_qmark.cljc +++ b/test/clojure/core_test/int_qmark.cljc @@ -4,50 +4,85 @@ [clojure.core-test.portability #?(:cljs :refer-macros :default :refer) [when-var-exists]])) (when-var-exists int? - (deftest test-int? - (are [expected x] (= expected (int? x)) - true 0 - true 1 - true -1 - true r/max-int - true r/min-int - #?@(:cljs [true] :default [false]) 0.0 - #?@(:cljs [true] :default [false]) 1.0 - #?@(:cljs [true] :default [false]) -1.0 - false 0.1 - false 1.1 - false -1.1 - false r/max-double - false r/min-double - false ##Inf - false ##-Inf - false ##NaN - #?@(:cljs [true] :lpy [true] :phel [true] :default [false]) 0N - #?@(:cljs [true] :lpy [true] :phel [true] :default [false]) 1N - #?@(:cljs [true] :lpy [true] :phel [true] :default [false]) -1N - #?@(:cljs [] - :default - [true 0/2 - false 1/2 - false -1/2]) - #?@(:cljs [true] :default [false]) 0.0M - #?@(:cljs [true] :default [false]) 1.0M - #?@(:cljs [true] :default [false]) -1.0M - false nil - false true - false false - false "a string" - false "0" - false "1" - false "-1" - false {:a :map} - false #{:a-set} - false [:a :vector] - false '(:a :list) - false \0 - false \1 - false :a-keyword - false :0 - false :1 - false :-1 - false 'a-sym))) + (deftest test-int? + (are [expected x] (= expected (int? x)) + true 0 + true 1 + true -1 + true r/max-int + true r/min-int + false 0.1 + false 1.1 + false -1.1 + false r/max-double + false r/min-double + false ##Inf + false ##-Inf + false ##NaN + false nil + false true + false false + false "a string" + false "0" + false "1" + false "-1" + false {:a :map} + false #{:a-set} + false [:a :vector] + false '(:a :list) + false \0 + false \1 + false :a-keyword + false :0 + false :1 + false :-1 + false 'a-sym + #?@(:cljs + [true 0.0 + true 1.0 + true -1.0 + true 0N + true 1N + true -1N + true 0.0M + true 1.0M + true -1.0M] + :lpy + [false 0.0 + false 1.0 + false -1.0 + true 0N + true 1N + true -1N + false 0.0M + false 1.0M + false -1.0M + true 0/2 + false 1/2 + false -1/2] + :phel + [false 0.0 + false 1.0 + false -1.0 + true 0N + true 1N + true -1N + false 0.0M + false 1.0M + false -1.0M + true 0/2 + false 1/2 + false -1/2] + :default + [false 0.0 + false 1.0 + false -1.0 + false 0N + false 1N + false -1N + false 0.0M + false 1.0M + false -1.0M + true 0/2 + false 1/2 + false -1/2])))) diff --git a/test/clojure/core_test/neg_int_qmark.cljc b/test/clojure/core_test/neg_int_qmark.cljc index 64fc361f..37207c75 100644 --- a/test/clojure/core_test/neg_int_qmark.cljc +++ b/test/clojure/core_test/neg_int_qmark.cljc @@ -45,9 +45,21 @@ #?@(:cljs [true -1.0 true -1.0M true -1N] + :lpy [false -1.0 + false -1.0M + true -1N + false 0/2 + false 1/2 + false -1/2] + :phel [false -1.0 + false -1.0M + true -1N + false 0/2 + false 1/2 + false -1/2] :default [false -1.0 false -1.0M - #?(:lpy true :phel true :default false) -1N + false -1N false 0/2 false 1/2 false -1/2])))) diff --git a/test/clojure/core_test/pos_int_qmark.cljc b/test/clojure/core_test/pos_int_qmark.cljc index be1a9dba..415338d1 100644 --- a/test/clojure/core_test/pos_int_qmark.cljc +++ b/test/clojure/core_test/pos_int_qmark.cljc @@ -47,8 +47,20 @@ #?@(:cljs [true 1.0 true 1.0M] + :lpy [false 1.0 + true 1N + false 0/2 + false 1/2 + false -1/2 + false 1.0M] + :phel [false 1.0 + true 1N + false 0/2 + false 1/2 + false -1/2 + false 1.0M] :default [false 1.0 - #?(:lpy true :phel true :default false) 1N + false 1N false 0/2 false 1/2 false -1/2 diff --git a/test/clojure/core_test/seqable_qmark.cljc b/test/clojure/core_test/seqable_qmark.cljc index c2318e71..a543fa13 100644 --- a/test/clojure/core_test/seqable_qmark.cljc +++ b/test/clojure/core_test/seqable_qmark.cljc @@ -15,19 +15,29 @@ true nil true "a string" true (object-array 3) - - ;; Basilisp does not currently implement sorted collections or array-map. - #?@(:lpy [] - :default [true (sorted-map :a 1) - true (sorted-set :a) - true (array-map :a 1) - true (seq (sorted-map :a 1)) - true (seq (sorted-set :a))]) - false 1 false 1N false 1.0 false 1.0M false :a-keyword false 'a-sym - #?(:cljs true :lpy true :phel true :default false) \a))) + ;; Basilisp does not currently implement sorted collections or array-map. + #?@(:lpy [true \a] + :cljs [true \a + true (sorted-map :a 1) + true (sorted-set :a) + true (array-map :a 1) + true (seq (sorted-map :a 1)) + true (seq (sorted-set :a))] + :phel [true \a + true (sorted-map :a 1) + true (sorted-set :a) + true (array-map :a 1) + true (seq (sorted-map :a 1)) + true (seq (sorted-set :a))] + :default [false \a + true (sorted-map :a 1) + true (sorted-set :a) + true (array-map :a 1) + true (seq (sorted-map :a 1)) + true (seq (sorted-set :a))])))) diff --git a/test/clojure/core_test/special_symbol_qmark.cljc b/test/clojure/core_test/special_symbol_qmark.cljc index 4f47a8e6..e264ff83 100644 --- a/test/clojure/core_test/special_symbol_qmark.cljc +++ b/test/clojure/core_test/special_symbol_qmark.cljc @@ -13,16 +13,16 @@ :default [& case* new]) + ;; Phel does not recognize these as special symbols. #?@(:phel [] - :default - [. - fn* - loop* - deftype* - set! - let* - letfn*]) - var + :default [. + deftype* + fn* + let* + letfn* + loop* + set! + ]) catch def do @@ -31,7 +31,8 @@ quote recur throw - try)) + try + var)) (testing "not special symbols" (are [arg] (not (special-symbol? arg)) From afcf33dfc8f5e7b29af47ce189a9e7ab7a17f599 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Thu, 7 May 2026 00:12:17 +0300 Subject: [PATCH 11/20] uuid_qmark.cljc: remove Phel conditional after UUID type addition --- test/clojure/core_test/uuid_qmark.cljc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/clojure/core_test/uuid_qmark.cljc b/test/clojure/core_test/uuid_qmark.cljc index e1028c90..37b420ba 100644 --- a/test/clojure/core_test/uuid_qmark.cljc +++ b/test/clojure/core_test/uuid_qmark.cljc @@ -25,8 +25,7 @@ -1.0 ##NaN ##Inf - #?@(:phel [] ; Phel UUIDs are strings so the default evals true - :default ["f81d4fae-7dec-11d0-a765-00a0c91e6bf6"]) + "f81d4fae-7dec-11d0-a765-00a0c91e6bf6" {:a :map} #{:a-set} [:a :vector] From 79d2c59c73ee9535bc9fc3f01e65bc906fe6d100 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Thu, 7 May 2026 07:10:14 +0300 Subject: [PATCH 12/20] Remove Phel specific overrides for BigDecimal after it was added --- test/clojure/core_test/case.cljc | 17 ----- test/clojure/core_test/double_qmark.cljc | 7 --- test/clojure/core_test/float_qmark.cljc | 26 -------- test/clojure/core_test/mod.cljc | 13 ---- test/clojure/core_test/quot.cljc | 13 ---- test/clojure/core_test/rem.cljc | 63 ++++++++----------- .../core_test/special_symbol_qmark.cljc | 4 +- 7 files changed, 27 insertions(+), 116 deletions(-) diff --git a/test/clojure/core_test/case.cljc b/test/clojure/core_test/case.cljc index f6f4a359..1b8434c7 100644 --- a/test/clojure/core_test/case.cljc +++ b/test/clojure/core_test/case.cljc @@ -111,23 +111,6 @@ 4N :big-decimal-result 4.0 :big-decimal-result 4.0M :big-decimal-result] - :phel - [1 :integer-result - 1N :integer-result - 1.0 :default - 1.0M :default - 2 :big-integer-result - 2N :big-integer-result - 2.0 :default - 2.0M :default - 3 :default - 3N :default - 3.0 :double-result - 3.0M :double-result ; big-decimal not supported (uses float) - 4 :default - 4N :default - 4.0 :big-decimal-result ; big-decimal not supported (uses float) - 4.0M :big-decimal-result] :default [1 :integer-result 1N :integer-result ; JVM sees ints and big ints as equal for int-sized values diff --git a/test/clojure/core_test/double_qmark.cljc b/test/clojure/core_test/double_qmark.cljc index f55e3513..ad5a6281 100644 --- a/test/clojure/core_test/double_qmark.cljc +++ b/test/clojure/core_test/double_qmark.cljc @@ -59,13 +59,6 @@ true 0.0M true 1.0M true -1.0M] - :phel - [false 0N - false 1N - false -1N - true 0.0M - true 1.0M - true -1.0M] :default [false 0N false 1N diff --git a/test/clojure/core_test/float_qmark.cljc b/test/clojure/core_test/float_qmark.cljc index 9a80bfe8..80338392 100644 --- a/test/clojure/core_test/float_qmark.cljc +++ b/test/clojure/core_test/float_qmark.cljc @@ -32,32 +32,6 @@ true 0.0M true 1.0M true -1.0M] - :phel - [true 0.0 - true 1.0 - true -1.0 - true (float 0.0) - true (float 1.0) - true (float -1.0) - true (double 0.0) - true (double 1.0) - true (double -1.0) - true r/max-double - true r/min-double - true ##Inf - true ##-Inf - true ##NaN - false 0 - false 1 - false -1 - false r/max-int - false r/min-int - false 0N - false 1N - false -1N - true 0.0M ; Phel doesn't have BigDecimal - true 1.0M - true -1.0M] :default [true 0.0 true 1.0 diff --git a/test/clojure/core_test/mod.cljc b/test/clojure/core_test/mod.cljc index f1d2838d..30ca09a8 100644 --- a/test/clojure/core_test/mod.cljc +++ b/test/clojure/core_test/mod.cljc @@ -48,19 +48,6 @@ ;; CLJS can read big decimals at the reader, but just converts ;; them to doubles. #?@(:cljs - [double? 1.0M 10 3.0M - double? 2.0M -10 3.0M - double? -1.0M -10 -3.0M - double? -2.0M 10 -3.0M - double? 1.0M 10.0M 3 - double? 2.0M -10.0M 3 - double? -1.0M -10.0M -3 - double? -2.0M 10.0M -3 - double? 1.0M 10.0M 3.0M - double? 2.0M -10.0M 3.0M - double? -1.0M -10.0M -3.0M - double? -2.0M 10.0M -3.0M] - :phel [double? 1.0M 10 3.0M double? 2.0M -10 3.0M double? -1.0M -10 -3.0M diff --git a/test/clojure/core_test/quot.cljc b/test/clojure/core_test/quot.cljc index f6594e90..5bf76f98 100644 --- a/test/clojure/core_test/quot.cljc +++ b/test/clojure/core_test/quot.cljc @@ -40,19 +40,6 @@ double? -3.0 10.0 -3.0 #?@(:cljs - [double? 3.0M 10 3.0M - double? -3.0M -10 3.0M - double? 3.0M -10 -3.0M - double? -3.0M 10 -3.0M - double? 3.0M 10.0M 3 - double? -3.0M -10.0M 3 - double? 3.0M -10.0M -3 - double? -3.0M 10.0M -3 - double? 3.0M 10.0M 3.0M - double? -3.0M -10.0M 3.0M - double? 3.0M -10.0M -3.0M - double? -3.0M 10.0M -3.0M] - :phel [double? 3.0M 10 3.0M double? -3.0M -10 3.0M double? 3.0M -10 -3.0M diff --git a/test/clojure/core_test/rem.cljc b/test/clojure/core_test/rem.cljc index 8f3deba1..ac623e1f 100644 --- a/test/clojure/core_test/rem.cljc +++ b/test/clojure/core_test/rem.cljc @@ -40,44 +40,31 @@ double? 1.0 10.0 -3.0 #?@(:cljs - [double? 1.0M 10 3.0M - double? -1.0M -10 3.0M - double? -1.0M -10 -3.0M - double? 1.0M 10 -3.0M - double? 1.0M 10.0M 3 - double? -1.0M -10.0M 3 - double? -1.0M -10.0M -3 - double? 1.0M 10.0M -3 - double? 1.0M 10.0M 3.0M - double? -1.0M -10.0M 3.0M - double? -1.0M -10.0M -3.0M - double? 1.0M 10.0M -3.0M] - :phel - [double? 1.0M 10 3.0M - double? -1.0M -10 3.0M - double? -1.0M -10 -3.0M - double? 1.0M 10 -3.0M - double? 1.0M 10.0M 3 - double? -1.0M -10.0M 3 - double? -1.0M -10.0M -3 - double? 1.0M 10.0M -3 - double? 1.0M 10.0M 3.0M - double? -1.0M -10.0M 3.0M - double? -1.0M -10.0M -3.0M - double? 1.0M 10.0M -3.0M] - :default - [decimal? 1.0M 10 3.0M - decimal? -1.0M -10 3.0M - decimal? -1.0M -10 -3.0M - decimal? 1.0M 10 -3.0M - decimal? 1.0M 10.0M 3 - decimal? -1.0M -10.0M 3 - decimal? -1.0M -10.0M -3 - decimal? 1.0M 10.0M -3 - decimal? 1.0M 10.0M 3.0M - decimal? -1.0M -10.0M 3.0M - decimal? -1.0M -10.0M -3.0M - decimal? 1.0M 10.0M -3.0M]) + [double? 1.0M 10 3.0M + double? -1.0M -10 3.0M + double? -1.0M -10 -3.0M + double? 1.0M 10 -3.0M + double? 1.0M 10.0M 3 + double? -1.0M -10.0M 3 + double? -1.0M -10.0M -3 + double? 1.0M 10.0M -3 + double? 1.0M 10.0M 3.0M + double? -1.0M -10.0M 3.0M + double? -1.0M -10.0M -3.0M + double? 1.0M 10.0M -3.0M] + :default + [decimal? 1.0M 10 3.0M + decimal? -1.0M -10 3.0M + decimal? -1.0M -10 -3.0M + decimal? 1.0M 10 -3.0M + decimal? 1.0M 10.0M 3 + decimal? -1.0M -10.0M 3 + decimal? -1.0M -10.0M -3 + decimal? 1.0M 10.0M -3 + decimal? 1.0M 10.0M 3.0M + decimal? -1.0M -10.0M 3.0M + decimal? -1.0M -10.0M -3.0M + decimal? 1.0M 10.0M -3.0M]) ;; Unexpectedly downconverts result to double, rather than BigDecimal double? 1.0 10.0M 3.0 diff --git a/test/clojure/core_test/special_symbol_qmark.cljc b/test/clojure/core_test/special_symbol_qmark.cljc index e264ff83..4d4f5397 100644 --- a/test/clojure/core_test/special_symbol_qmark.cljc +++ b/test/clojure/core_test/special_symbol_qmark.cljc @@ -21,8 +21,8 @@ let* letfn* loop* - set! - ]) + set!]) + catch def do From 7fb70d2433e50cb744f2db32dc813dac6a5e22b4 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Thu, 7 May 2026 16:15:16 +0300 Subject: [PATCH 13/20] key.cljc & val.cljc: use Phel's newly added map-entry function ref: https://github.com/phel-lang/phel-lang/pull/1861 --- test/clojure/core_test/key.cljc | 2 +- test/clojure/core_test/val.cljc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/clojure/core_test/key.cljc b/test/clojure/core_test/key.cljc index cb524e97..2ce5f560 100644 --- a/test/clojure/core_test/key.cljc +++ b/test/clojure/core_test/key.cljc @@ -12,7 +12,7 @@ ;; https://groups.google.com/g/clojure/c/FVcrbHJpCW4/m/Fh7NsX_Yb7sJ (is (= 'k (key #?(:cljs (cljs.core/MapEntry. 'k 'v nil) :lpy (map-entry 'k 'v) - :phel ['k 'v] ; Phel map entries are vectors + :phel (map-entry 'k 'v) :default (clojure.lang.MapEntry/create 'k 'v))))) (when-var-exists sorted-map (is (= :a (key (first (sorted-map :a :b)))))) diff --git a/test/clojure/core_test/val.cljc b/test/clojure/core_test/val.cljc index e2e1236f..455bc0ba 100644 --- a/test/clojure/core_test/val.cljc +++ b/test/clojure/core_test/val.cljc @@ -11,7 +11,7 @@ ;; https://groups.google.com/g/clojure/c/FVcrbHJpCW4/m/Fh7NsX_Yb7sJ (is (= 'v (val #?(:cljs (cljs.core/MapEntry. 'k 'v nil) :lpy (map-entry 'k 'v) - :phel ['k 'v] ; Phel represents map entries as vectors + :phel (map-entry 'k 'v) :default (clojure.lang.MapEntry/create 'k 'v))))) (is (= :b (val (first (hash-map :a :b))))) (when-var-exists sorted-map From b1ed0d302a463e84090f7c2d4843266c28417041 Mon Sep 17 00:00:00 2001 From: Jarkko Saltiola Date: Mon, 11 May 2026 13:02:02 +0300 Subject: [PATCH 14/20] update phel-config.php to new format https://github.com/phel-lang/phel-lang/pull/1959 --- phel-config.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phel-config.php b/phel-config.php index 0a43fd96..eb18937f 100644 --- a/phel-config.php +++ b/phel-config.php @@ -1,6 +1,6 @@ setSrcDirs(['src']) - ->setTestDirs(['test']); +return Phel\Config\PhelConfig::forProject() + ->withSrcDirs(['src']) + ->withTestDirs(['test']); From 246a4acb74b7f43441f98d89d37770a0e76b2a3c Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Wed, 13 May 2026 21:27:47 +0200 Subject: [PATCH 15/20] chore: pin phel-lang to ^0.37 and add composer.lock --- composer.json | 5 +- composer.lock | 1216 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1218 insertions(+), 3 deletions(-) create mode 100644 composer.lock diff --git a/composer.json b/composer.json index 0d85d128..c9849369 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,5 @@ { "require": { - "phel-lang/phel-lang": "dev-main" - }, - "minimum-stability": "dev" + "phel-lang/phel-lang": "^0.37" + } } diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..343aee07 --- /dev/null +++ b/composer.lock @@ -0,0 +1,1216 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "a715e87fd47198697005d49d2c3a63e4", + "packages": [ + { + "name": "amphp/amp", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/amp.git", + "reference": "fa0ab33a6f47a82929c38d03ca47ebb71086a93f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/amp/zipball/fa0ab33a6f47a82929c38d03ca47ebb71086a93f", + "reference": "fa0ab33a6f47a82929c38d03ca47ebb71086a93f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "5.23.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php", + "src/Future/functions.php", + "src/Internal/functions.php" + ], + "psr-4": { + "Amp\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + } + ], + "description": "A non-blocking concurrency framework for PHP applications.", + "homepage": "https://amphp.org/amp", + "keywords": [ + "async", + "asynchronous", + "awaitable", + "concurrency", + "event", + "event-loop", + "future", + "non-blocking", + "promise" + ], + "support": { + "issues": "https://github.com/amphp/amp/issues", + "source": "https://github.com/amphp/amp/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-08-27T21:42:00+00:00" + }, + { + "name": "gacela-project/container", + "version": "0.8.0", + "source": { + "type": "git", + "url": "https://github.com/gacela-project/container.git", + "reference": "62a409c918fe0e301b909da1c54aea189bd6e76a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/gacela-project/container/zipball/62a409c918fe0e301b909da1c54aea189bd6e76a", + "reference": "62a409c918fe0e301b909da1c54aea189bd6e76a", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": ">=1.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.75", + "phpstan/phpstan": "^1.12", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18", + "symfony/var-dumper": "^5.4", + "vimeo/psalm": "^5.26" + }, + "type": "library", + "autoload": { + "psr-4": { + "Gacela\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jose Maria Valera Reales", + "email": "chemaclass@outlook.es", + "homepage": "https://chemaclass.com" + }, + { + "name": "Jesus Valera Reales", + "email": "hello@jesusvalera.dev", + "homepage": "https://jesusvalera.dev/" + } + ], + "description": "A minimalistic container dependency resolver", + "homepage": "https://gacela-project.com", + "keywords": [ + "container", + "gacela", + "php", + "resolver" + ], + "support": { + "issues": "https://github.com/gacela-project/resolver/issues", + "source": "https://github.com/gacela-project/container/tree/0.8.0" + }, + "funding": [ + { + "url": "https://chemaclass.com/sponsor", + "type": "custom" + } + ], + "time": "2025-11-08T22:36:48+00:00" + }, + { + "name": "gacela-project/gacela", + "version": "1.14.4", + "source": { + "type": "git", + "url": "https://github.com/gacela-project/gacela.git", + "reference": "d3058fa16b4748adca17d7e5b940c0dc5daa3e61" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/gacela-project/gacela/zipball/d3058fa16b4748adca17d7e5b940c0dc5daa3e61", + "reference": "d3058fa16b4748adca17d7e5b940c0dc5daa3e61", + "shasum": "" + }, + "require": { + "gacela-project/container": "^0.8", + "php": ">=8.1" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.50", + "friendsofphp/php-cs-fixer": "^3.95", + "infection/infection": "^0.29", + "phpbench/phpbench": "^1.4", + "phpmetrics/phpmetrics": "^2.9", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.19.5", + "rector/rector": "^2.0", + "symfony/console": "^6.4", + "symfony/dependency-injection": "^6.4", + "symfony/var-dumper": "^6.4", + "vimeo/psalm": "^6.16" + }, + "suggest": { + "gacela-project/gacela-env-config-reader": "Allows to read .env config files", + "gacela-project/gacela-yaml-config-reader": "Allows to read yml/yaml config files", + "gacela-project/phpstan-extension": "A set of phpstan rules for Gacela", + "symfony/console": "Allows to use vendor/bin/gacela script" + }, + "bin": [ + "bin/gacela" + ], + "type": "library", + "autoload": { + "psr-4": { + "Gacela\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jose Maria Valera Reales", + "email": "chemaclass@outlook.es", + "homepage": "https://chemaclass.com" + }, + { + "name": "Jesus Valera Reales", + "email": "hello@jesusvalera.dev", + "homepage": "https://jesusvalera.dev/" + } + ], + "description": "Gacela helps you separate your project into modules", + "homepage": "https://gacela-project.com", + "keywords": [ + "framework", + "kernel", + "modular", + "php" + ], + "support": { + "issues": "https://github.com/gacela-project/gacela/issues", + "source": "https://github.com/gacela-project/gacela/tree/1.14.4" + }, + "funding": [ + { + "url": "https://chemaclass.com/sponsor", + "type": "custom" + } + ], + "time": "2026-04-20T09:41:26+00:00" + }, + { + "name": "phel-lang/phel-lang", + "version": "v0.37.0", + "source": { + "type": "git", + "url": "https://github.com/phel-lang/phel-lang.git", + "reference": "091e9be0ff0f52ccfb4340e6776db1243ef96933" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phel-lang/phel-lang/zipball/091e9be0ff0f52ccfb4340e6776db1243ef96933", + "reference": "091e9be0ff0f52ccfb4340e6776db1243ef96933", + "shasum": "" + }, + "require": { + "amphp/amp": "^3.1", + "gacela-project/gacela": "^1.14", + "php": ">=8.4", + "symfony/console": "^6.0|^7.0|^8.0", + "symfony/routing": "^7.3" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.50", + "ext-readline": "*", + "friendsofphp/php-cs-fixer": "^3.94", + "phpbench/phpbench": "^1.6", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.19", + "rector/rector": "^2.3", + "symfony/var-dumper": "^7.4", + "vimeo/psalm": "^6.16" + }, + "bin": [ + "bin/phel" + ], + "type": "library", + "autoload": { + "psr-4": { + "Phel\\": "src/php/" + }, + "classmap": [ + "src/Phel.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jens Haase", + "email": "je.haase@gmail.com" + }, + { + "name": "Jose M. Valera Reales", + "email": "phel@chemaclass.es", + "homepage": "https://chemaclass.com" + } + ], + "description": "Phel is a functional programming language that compiles to PHP", + "homepage": "https://phel-lang.org/", + "keywords": [ + "functional", + "language", + "lisp", + "phel" + ], + "support": { + "issues": "https://github.com/phel-lang/phel-lang/issues", + "source": "https://github.com/phel-lang/phel-lang/tree/v0.37.0" + }, + "funding": [ + { + "url": "https://chemaclass.com/sponsor", + "type": "custom" + } + ], + "time": "2026-05-12T13:13:01+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "revolt/event-loop", + "version": "v1.0.8", + "source": { + "type": "git", + "url": "https://github.com/revoltphp/event-loop.git", + "reference": "b6fc06dce8e9b523c9946138fa5e62181934f91c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/b6fc06dce8e9b523c9946138fa5e62181934f91c", + "reference": "b6fc06dce8e9b523c9946138fa5e62181934f91c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Revolt\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "ceesjank@gmail.com" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Rock-solid event loop for concurrent PHP applications.", + "keywords": [ + "async", + "asynchronous", + "concurrency", + "event", + "event-loop", + "non-blocking", + "scheduler" + ], + "support": { + "issues": "https://github.com/revoltphp/event-loop/issues", + "source": "https://github.com/revoltphp/event-loop/tree/v1.0.8" + }, + "time": "2025-08-27T21:33:23+00:00" + }, + { + "name": "symfony/console", + "version": "v8.0.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "3156577f46a38aa1b9323aad223de7a9cd426782" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/3156577f46a38aa1b9323aad223de7a9cd426782", + "reference": "3156577f46a38aa1b9323aad223de7a9cd426782", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "symfony/polyfill-mbstring": "^1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.4|^8.0" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/event-dispatcher": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/lock": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/stopwatch": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v8.0.11" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-13T12:07:53+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/50f59d1f3ca46d41ac911f97a78626b6756af35b", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-13T15:52:40+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T16:19:22+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/4864388bfbd3001ce88e234fab652acd91fdc57e", + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-26T13:13:48+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T17:25:58+00:00" + }, + { + "name": "symfony/routing", + "version": "v7.4.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "287771d8bc86eacb30678dd10eda6c64a859951f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/287771d8bc86eacb30678dd10eda6c64a859951f", + "reference": "287771d8bc86eacb30678dd10eda6c64a859951f", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/yaml": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v7.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-22T15:21:55+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d25d82433a80eba6aa0e6c24b61d7370d99e444a", + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-03-28T09:44:51+00:00" + }, + { + "name": "symfony/string", + "version": "v8.0.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "39be2ad058a3c0bd558edca23e65f009865d75ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/39be2ad058a3c0bd558edca23e65f009865d75ff", + "reference": "39be2ad058a3c0bd558edca23e65f009865d75ff", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-intl-grapheme": "^1.33", + "symfony/polyfill-intl-normalizer": "^1.0", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.4|^8.0", + "symfony/http-client": "^7.4|^8.0", + "symfony/intl": "^7.4|^8.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v8.0.11" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-13T12:07:53+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" +} From 569e42117fef4cd2f58d7b8ed73175b6e9e62064 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Wed, 13 May 2026 21:35:10 +0200 Subject: [PATCH 16/20] chore: tune phel-config for repo layout and DX - drop nonexistent src dir - align formatDirs with test/ - enable deprecation warnings - add composer test script --- composer.json | 3 +++ phel-config.php | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index c9849369..f042d962 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,8 @@ { "require": { "phel-lang/phel-lang": "^0.37" + }, + "scripts": { + "test": "./vendor/bin/phel test" } } diff --git a/phel-config.php b/phel-config.php index eb18937f..d4c97a06 100644 --- a/phel-config.php +++ b/phel-config.php @@ -1,6 +1,7 @@ withSrcDirs(['src']) - ->withTestDirs(['test']); + ->withSrcDirs([]) + ->withTestDirs(['test']) + ->withFormatDirs(['test']) + ->withWarnDeprecations(); From a80ba61a7cf05ce4ab5055002d77762350ab30ea Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Wed, 13 May 2026 21:49:52 +0200 Subject: [PATCH 17/20] docs: refresh phel.md for 0.37 and add reader-conditional notes --- doc/phel.md | 85 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/doc/phel.md b/doc/phel.md index b398e73e..6037cc90 100644 --- a/doc/phel.md +++ b/doc/phel.md @@ -2,50 +2,99 @@ ## Prerequisites -- PHP 8.4+ & [Composer](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos) +- PHP 8.4+ (`php -v` to check) +- [Composer](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos) -Install: -``` +Install dependencies: + +```bash composer install ``` -Tests live in `test/` (override via `phel-config.php`). +Tests live in `test/` (configurable in [`phel-config.php`](../phel-config.php) via `withTestDirs`). -See also [Getting Started guide](https://phel-lang.org/documentation/getting-started/). +See also the [Phel Getting Started guide](https://phel-lang.org/documentation/getting-started/). ## Running the test suite Full suite: -``` + +```bash +composer test +# or directly: ./vendor/bin/phel test ``` -Specific test: -``` + +A single file: + +```bash ./vendor/bin/phel test test/clojure/core_test/abs.cljc ``` -If runner crashes before report, re-run with `--testdox` or `-v` to locate failing test. +A namespace: + +```bash +./vendor/bin/phel test --filter clojure.core-test.abs +``` -See [Phel testing docs](https://phel-lang.org/documentation/testing/#running-tests). +If the runner crashes before printing a report, re-run with `--testdox` or `-v` to locate the failing test. -## Updating Phel version +See the [Phel testing docs](https://phel-lang.org/documentation/testing/#running-tests). + +## Formatting + +Format the test sources (uses `withFormatDirs` from `phel-config.php`): + +```bash +./vendor/bin/phel format +``` + +## Updating the Phel version + +`composer.json` currently pins a stable release: -`composer.json` tracks `dev-main` (latest [phel-lang](https://github.com/phel-lang/phel-lang/) HEAD): ```json { "require": { - "phel-lang/phel-lang": "dev-main" - }, - "minimum-stability": "dev" + "phel-lang/phel-lang": "^0.37" + } } ``` -Pull latest: -``` +Pull the latest matching release: + +```bash composer update phel-lang/phel-lang ``` -Pin specific commit (optional): +To track development HEAD instead, switch to `dev-main` and allow dev stability: + +```json +{ + "require": { + "phel-lang/phel-lang": "dev-main" + }, + "minimum-stability": "dev", + "prefer-stable": true +} ``` + +Pin to a specific commit (useful for bisecting upstream regressions): + +```bash composer require "phel-lang/phel-lang:dev-main#" ``` + +## Reader conditionals + +The shared `.cljc` tests select the Phel branch via `:phel`: + +```clojure +#?(:clj (Integer/MAX_VALUE) + :cljs js/Number.MAX_SAFE_INTEGER + :phel php/PHP_INT_MAX) +``` + +Phel exposes PHP globals under the `php/` namespace and core types under `Phel.Lang.*` +(e.g. `Phel.Lang.ExInfoException`, `Phel.Lang.Collections.Map.PersistentMapInterface`). +See [writing-tests.md](writing-tests.md) for cross-dialect conventions. From 48a19fb3ee6e01f5b0295a785368da7685458a0a Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Wed, 13 May 2026 21:52:04 +0200 Subject: [PATCH 18/20] docs: include Phel in writing-tests dialect list and run instructions --- doc/writing-tests.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/writing-tests.md b/doc/writing-tests.md index 6e457479..14e5ff26 100644 --- a/doc/writing-tests.md +++ b/doc/writing-tests.md @@ -26,6 +26,7 @@ If possible, install them all and run the tests against each dialect before subm 3. [Babashka](babashka.md) 4. [Clojure CLR](clojureclr.md) 5. [Basilisp](basilisp.md) +6. [Phel](phel.md) ## How to Write a New Test @@ -111,9 +112,15 @@ $ bb test-bb # run tests under Babashka $ bb test-lpy # run tests under Basilisp ``` -Ideally, you should run all three of these *before* submitting a PR. +Phel has no Babashka task yet — run it directly (see [phel.md](phel.md)): + +```bash +$ ./vendor/bin/phel test +``` + +Ideally, you should run all of these *before* submitting a PR. This helps prevent the PR from failing during CI testing. -The Clojure Test Suite CI testing runs the tests in Clojure, ClojureScript, Babashka, and ClojureCLR environments. +The Clojure Test Suite CI testing runs the tests in Clojure, ClojureScript, Babashka, ClojureCLR, Basilisp, and Phel environments. ### Create commits From f1123ee02d57fb5ef8f65cf743fd64f2455ae116 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Thu, 14 May 2026 18:40:29 +0200 Subject: [PATCH 19/20] chore: disable Xdebug for Phel test runs --- .github/workflows/ci.yml | 2 ++ composer.json | 2 +- doc/phel.md | 10 ++++++---- doc/writing-tests.md | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 07372ecb..cca2a622 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -182,4 +182,6 @@ jobs: run: composer install --no-interaction --no-ansi --no-progress - name: Run tests + env: + XDEBUG_MODE: off run: php -d memory_limit=256M ./vendor/bin/phel test diff --git a/composer.json b/composer.json index f042d962..03f6195b 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,6 @@ "phel-lang/phel-lang": "^0.37" }, "scripts": { - "test": "./vendor/bin/phel test" + "test": "XDEBUG_MODE=off ./vendor/bin/phel test" } } diff --git a/doc/phel.md b/doc/phel.md index 6037cc90..0d6f4d78 100644 --- a/doc/phel.md +++ b/doc/phel.md @@ -21,22 +21,24 @@ Full suite: ```bash composer test -# or directly: -./vendor/bin/phel test ``` A single file: ```bash -./vendor/bin/phel test test/clojure/core_test/abs.cljc +composer test -- test/clojure/core_test/abs.cljc ``` A namespace: ```bash -./vendor/bin/phel test --filter clojure.core-test.abs +composer test -- --filter clojure.core-test.abs ``` +> The `composer test` script sets `XDEBUG_MODE=off`, which makes startup +> noticeably faster than calling `./vendor/bin/phel test` directly when +> Xdebug is installed system-wide. + If the runner crashes before printing a report, re-run with `--testdox` or `-v` to locate the failing test. See the [Phel testing docs](https://phel-lang.org/documentation/testing/#running-tests). diff --git a/doc/writing-tests.md b/doc/writing-tests.md index 14e5ff26..eb365e15 100644 --- a/doc/writing-tests.md +++ b/doc/writing-tests.md @@ -115,7 +115,7 @@ $ bb test-lpy # run tests under Basilisp Phel has no Babashka task yet — run it directly (see [phel.md](phel.md)): ```bash -$ ./vendor/bin/phel test +$ composer test ``` Ideally, you should run all of these *before* submitting a PR. From 8411fc4108d095033c512a749cddeacf59796077 Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Thu, 14 May 2026 18:56:29 +0200 Subject: [PATCH 20/20] chore(phel): bb test-phel task, CI caching, composer test - Add `bb test-phel` task; include in `test-all` and dialect picker. - Cache Composer downloads and `.phel/cache` in the test-phel CI job. - CI now runs `composer test` so XDEBUG_MODE=off lives in one place. --- .github/workflows/ci.yml | 21 ++++++++++++++++++--- bb.edn | 15 +++++++++++---- doc/writing-tests.md | 7 +------ 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cca2a622..44f9e305 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -178,10 +178,25 @@ jobs: coverage: none tools: composer + - name: Cache Composer downloads + uses: actions/cache@v4 + with: + path: ~/.composer/cache + key: composer-${{ matrix.php }}-${{ hashFiles('composer.lock') }} + restore-keys: | + composer-${{ matrix.php }}- + + - name: Cache Phel compiled artifacts + uses: actions/cache@v4 + with: + path: .phel/cache + key: phel-cache-${{ matrix.php }}-${{ hashFiles('composer.lock', 'phel-config.php') }}-${{ hashFiles('test/**/*.cljc', 'test/**/*.phel') }} + restore-keys: | + phel-cache-${{ matrix.php }}-${{ hashFiles('composer.lock', 'phel-config.php') }}- + phel-cache-${{ matrix.php }}- + - name: Install dependencies run: composer install --no-interaction --no-ansi --no-progress - name: Run tests - env: - XDEBUG_MODE: off - run: php -d memory_limit=256M ./vendor/bin/phel test + run: composer test diff --git a/bb.edn b/bb.edn index 7c466250..15e70b67 100644 --- a/bb.edn +++ b/bb.edn @@ -32,13 +32,18 @@ {:extra-env {"BASILISP_TEST_PATH" "./test" "BASILISP_TEST_FILE_PATTERN" ".*\\.(lpy|cljc)"}} "basilisp test -p test -- -n 0"))} + test-phel {:doc "Runs tests in Phel" + :task (do + (banner "Running Phel Tests") + (shell "composer test"))} test-all {:doc "Run tests under all dialects" :task (do (run 'test-jvm) (run 'test-cljs) (run 'test-bb) - (run 'test-lpy))} - test {:doc "Runs tests in multiple named dialects: jvm, bb, cljs, or lpy" + (run 'test-lpy) + (run 'test-phel))} + test {:doc "Runs tests in multiple named dialects: jvm, bb, cljs, lpy, or phel" :task (letfn [(help [] (println "Usage: bb test []...") (println "Where is one of:") @@ -46,9 +51,10 @@ (println " cljs Runs tests in ClojureScript") (println " bb Runs tests in Babashka") (println " lpy Runs tests in Basilisp") + (println " phel Runs tests in Phel") (println " all Runs tests in all supported dialects") (println "Tests are run in the order given."))] - (let [valid #{"jvm" "cljs" "bb" "lpy" "all"} + (let [valid #{"jvm" "cljs" "bb" "lpy" "phel" "all"} unknown (remove valid *command-line-args*)] (cond (not (some? (seq *command-line-args*))) @@ -69,7 +75,8 @@ "jvm" (run 'test-jvm) "cljs" (run 'test-cljs) "bb" (run 'test-bb) - "lpy" (run 'test-lpy))))))} + "lpy" (run 'test-lpy) + "phel" (run 'test-phel))))))} new-test {:doc "Creates new test for the Clojure symbols named by . Unqualified symbols assume clojure.core" :requires ([new-test]) :task (new-test/new-test *command-line-args*)}}} diff --git a/doc/writing-tests.md b/doc/writing-tests.md index eb365e15..7bf92d69 100644 --- a/doc/writing-tests.md +++ b/doc/writing-tests.md @@ -110,12 +110,7 @@ $ bb test-jvm # run tests under Clojure JVM $ bb test-cljs # run tests under ClojureScript on Node.js $ bb test-bb # run tests under Babashka $ bb test-lpy # run tests under Basilisp -``` - -Phel has no Babashka task yet — run it directly (see [phel.md](phel.md)): - -```bash -$ composer test +$ bb test-phel # run tests under Phel ``` Ideally, you should run all of these *before* submitting a PR.