Skip to content

Commit db35f8f

Browse files
authored
Support running against Basilisp (#840)
* Support running against Basilisp * Support Basilisp * Fixes * README and Babashka * More updates * Fix string tests * Fix test * More tests * Parse tests * Fixes * Fixes * Atom * More changes * More * Use pip/setuptools * fix bb.edn * Fix * More fixes * More fixes * More changes * More * More changes * Ignore * Missed it * Pos int * Fixing * Ignore all sorted-set * More fixes * denominator / numerator * Many more fixes * More and more and more * Fix CLJS * More * Changes * Fix cycle * assoc * Fix * rationalize * Transients * nth * hierarchies * subvec * Flake * merge * byte * Fix case * Run tests in parallel * Run in parallel * Trigger build * Fix * Use `main` * Update project description language * Couple of PR comments * Fixing some peculiar whitespace * Align * Comments and conditionals
1 parent cb1274e commit db35f8f

File tree

119 files changed

+962
-397
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+962
-397
lines changed

.github/workflows/ci.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,26 @@ jobs:
136136
137137
- name: Run ClojureCLR Tests
138138
run: cljr -X:test
139+
140+
test-basilisp:
141+
runs-on: ubuntu-latest
142+
steps:
143+
- uses: actions/checkout@v4
144+
145+
- uses: actions/setup-python@v5
146+
with:
147+
python-version: "3.13"
148+
149+
- name: Install pip and dependencies
150+
run: |
151+
pip install -U pip
152+
python -m venv .venv
153+
source .venv/bin/activate
154+
pip install .
155+
156+
- name: Run tests
157+
run: |
158+
source .venv/bin/activate
159+
BASILISP_TEST_PATH="$(pwd)/test" \
160+
BASILISP_TEST_FILE_PATTERN='.*\.(lpy|cljc)' \
161+
basilisp test -p test -- -n auto

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ pom.xml.asc
2222
/.cpcache
2323
.idea
2424
*.iml
25+
__pycache__/
26+
.python-version
27+
poetry.lock
28+
*.egg-info/

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,29 @@ npx nodemon -w target/js taget/js/node-tests.js --test=clojure.core-test.int-que
8686
cljr -X:test
8787
```
8888

89+
## Running the Basilisp tests
90+
91+
### Pre-requisites
92+
- Python 3 / `pip`
93+
94+
You can install Python and `pip` using a tool such as [pyenv](https://github.com/pyenv/pyenv).
95+
With `pip` installed, you can install Basilisp:
96+
97+
```bash
98+
pip install -U pip
99+
python -m venv .venv
100+
source .venv/bin/activate
101+
pip install .
102+
```
103+
104+
Tests can be run using the Babashka task:
105+
106+
```bash
107+
source .venv/bin/activate
108+
bb test-lpy
109+
deactivate
110+
```
111+
89112
## Babashka Tasks
90113

91114
You can see which Babashka tasks are available with:

bb.edn

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
:exec-args {:patterns [".*"]}}
1212
test-cljs {:doc "Runs CLJS tests"
1313
:task (shell "npx shadow-cljs compile test")}
14+
test-lpy {:doc "Run Basilisp tests"
15+
:task (shell
16+
{:extra-env {"BASILISP_TEST_PATH" "./test"
17+
"BASILISP_TEST_FILE_PATTERN" ".*\\.(lpy|cljc)"}}
18+
"basilisp test -p test -- -n auto")}
1419
new-test {:doc "Creates new test for the Clojure symbols named by <args>. Unqualified symbols assume clojure.core"
1520
:requires ([new-test])
1621
:task (new-test/new-test *command-line-args*)}

pyproject.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[project]
2+
name = "clojure-test-suite"
3+
version = "0.1.0"
4+
description = "Dialect-independent tests for clojure.core, and others, focused on characterizing how Clojure JVM behaves so that other dialects to reach parity."
5+
authors = []
6+
license = "MPL-2.0"
7+
readme = "README.md"
8+
requires-python = ">=3.10"
9+
dependencies = [
10+
"basilisp[pytest] @ git+https://github.com/basilisp-lang/basilisp",
11+
"pytest-xdist"
12+
]
13+
14+
[tool.setuptools]
15+
packages = []
16+
17+
[build-system]
18+
requires = ["setuptools >= 77.0.3"]
19+
build-backend = "setuptools.build_meta"

test/clojure/core_test/abs.cljc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@
99
(are [in ex] (= ex (abs in))
1010
-1 1
1111
1 1
12-
(inc r/min-int) (- (inc r/min-int))
1312
-1.0 1.0
1413
-0.0 0.0
1514
##-Inf ##Inf
1615
##Inf ##Inf
1716
-123.456M 123.456M
1817
-123N 123N
1918

19+
;; Python VMs integer types are arbitrary precision and have no min or max
20+
#?@(:lpy []
21+
:default [(inc r/min-int) (- (inc r/min-int))])
22+
2023
#?@(:cljr []
24+
:lpy []
2125
:clj [r/min-int r/min-int] ; fixed int 2's complement oddity, see below for :cljr
2226
:default [r/min-int (* -1 r/min-int)])
2327
#?@(:cljs []

test/clojure/core_test/add_watch.cljc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
(swap! x inc)
2020
(catch #?(:cljs :default
2121
:clj clojure.lang.ExceptionInfo
22-
:cljr clojure.lang.ExceptionInfo) e
22+
:cljr clojure.lang.ExceptionInfo
23+
:lpy basilisp.lang.exception/ExceptionInfo) e
2324
(let [data (ex-data e)]
2425
(vswap! state conj data)))))]
2526
(do-update a)
@@ -89,7 +90,8 @@
8990
(alter-var-root x inc)
9091
(catch #?(:cljs :default
9192
:clj clojure.lang.ExceptionInfo
92-
:cljr clojure.lang.ExceptionInfo) e
93+
:cljr clojure.lang.ExceptionInfo
94+
:lpy basilisp.lang.exception/ExceptionInfo) e
9395
(let [{:keys [old] :as data} (ex-data e)]
9496
(vswap! state conj data)))))]
9597
(do-update #'testvar-a)
@@ -142,6 +144,7 @@
142144
{:key :e :ref #'testvar-b :old 14 :new 15 :tester :err})))))])
143145

144146
#?(:cljs nil
147+
:lpy nil
145148
:default
146149
(testing "watch ref"
147150
(let [state (volatile! [])
@@ -213,6 +216,7 @@
213216
(keyed :e @state)))))))
214217

215218
#?@(:cljs []
219+
:lpy []
216220
:default
217221
[(testing "watch agent"
218222
(let [state (volatile! [])

test/clojure/core_test/ancestors.cljc

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
(when-var-exists ancestors
66

77
; Some classes for testing ancestors by type inheritance
8-
(def AncestorT #?(:cljs js/Object :default Object))
9-
(def ChildT #?(:cljs :default :default clojure.lang.PersistentHashSet))
8+
(def AncestorT #?(:cljs js/Object :lpy python/object :default Object))
9+
(def ChildT #?(:cljs :default :lpy basilisp.lang.set/PersistentSet :default clojure.lang.PersistentHashSet))
1010

1111
; Some custom types for testing ancestors by type inheritance
1212
(defprotocol TestAncestorsProtocol)
@@ -29,9 +29,11 @@
2929
(doseq [[tag parent] global-hierarchy]
3030
(underive tag parent)))
3131

32-
(defn with-global-hierarchy [tests]
32+
;; Basilisp does not support clojure.test style fixtures right now
33+
;; https://github.com/basilisp-lang/basilisp/issues/1306
34+
(defn with-global-hierarchy [#?@(:lpy [] :default [tests])]
3335
(register-global-hierarchy)
34-
(tests)
36+
#?(:lpy (yield) :default (tests))
3537
(unregister-global-hierarchy))
3638

3739
(use-fixtures :once with-global-hierarchy)
@@ -76,9 +78,9 @@
7678
#?(:bb "bb doesn't report ancestors by type inheritance for custom types"
7779
:cljs "cljs doesn't report ancestors by type inheritance yet (CLJS-3464)"
7880
:default (testing "returns ancestors by type inheritance when tag is a custom type"
79-
(is (contains? (ancestors TestAncestorsType) clojure.core_test.ancestors.TestAncestorsProtocol))
80-
(is (contains? (ancestors TestAncestorsRecord) clojure.core_test.ancestors.TestAncestorsProtocol))
81-
(is (contains? (ancestors TestAncestorsRecord) clojure.lang.Associative))
81+
(is (contains? (ancestors TestAncestorsType) #?(:lpy (:interface TestAncestorsProtocol) :default clojure.core_test.ancestors.TestAncestorsProtocol)))
82+
(is (contains? (ancestors TestAncestorsRecord) #?(:lpy (:interface TestAncestorsProtocol) :default clojure.core_test.ancestors.TestAncestorsProtocol)))
83+
(is (contains? (ancestors TestAncestorsRecord) #?(:lpy basilisp.lang.interfaces/IAssociative :default clojure.lang.Associative)))
8284
(is (nil? (ancestors TestAncestorsProtocol)))))
8385

8486
(testing "does not throw on invalid tag"
@@ -140,8 +142,8 @@
140142
:cljs "cljs doesn't report ancestors by type inheritance yet (CLJS-3464)"
141143
:default (testing "returns ancestors by type inheritance when tag is a custom type, whether the tag is in h or not"
142144
(are [h tag] (let [actual-ancestors (ancestors h tag)]
143-
(and (contains? actual-ancestors clojure.core_test.ancestors.TestAncestorsProtocol)
144-
(contains? actual-ancestors clojure.lang.Associative)))
145+
(and (contains? actual-ancestors #?(:lpy (:interface TestAncestorsProtocol) :default clojure.core_test.ancestors.TestAncestorsProtocol))
146+
(contains? actual-ancestors #?(:lpy basilisp.lang.interfaces/IAssociative :default clojure.lang.Associative))))
145147
; tag in h
146148
datatypes TestAncestorsRecord
147149
; tag not in h

test/clojure/core_test/assoc.cljc

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
{:a 1 :b 2} {} [:a 1 :b 2]
2020
{:a 1 :b 3} {} [:a 1 :b 2 :b 3]
2121
{:a 1 :b 3 :c 5 :d 7} {:a 1 :b 2} [:b 3 :c 5 :d 7]))
22-
(testing "maps - sorted type preservation"
23-
(is (sorted? (assoc (sorted-map) :a 1 :b 2)))
24-
(is (sorted? (assoc (sorted-map :a 1 :b 2) :b 3)))))
22+
(when-var-exists sorted-map
23+
(testing "maps - sorted type preservation"
24+
(is (sorted? (assoc (sorted-map) :a 1 :b 2)))
25+
(is (sorted? (assoc (sorted-map :a 1 :b 2) :b 3))))))
2526

2627
(testing "vectors"
2728
(testing "vectors - single value"
@@ -37,14 +38,24 @@
3738
[1 2] [] [0 1 1 2]
3839
[1 3 5 7] [1 2] [1 3 2 5 3 7]))
3940
(testing "vectors - out-of-bounds indices"
41+
;; Basilisp vectors support indices 1 greater than the current max index
42+
;; and negative indices. Negative indices count backwards from the final
43+
;; element: -1 is the last element, -2 is the second-to-last, etc.
44+
#?(:lpy
45+
(are [expected vec ivs] (= expected (apply assoc vec ivs))
46+
[0 1 -1] [0 1 2] [-1 -1]
47+
[1 3 5] [1 2] [-1 3 2 5]))
48+
4049
(are [vec ivs] (thrown? #?(:cljs js/Error :default Exception) (apply assoc vec ivs))
4150
[] [-1 0]
4251
[] [1 0]
43-
[0 1 2] [-1 -1]
4452
[0 1 2] [4 4]
4553
[1 2] [1 3 3 5]
46-
[1 2] [-1 3 2 5]
47-
[1 2] [-1 3 3 5])))
54+
[1 2] [-1 3 3 5]
55+
#?@(:lpy []
56+
:default
57+
[[0 1 2] [-1 -1]
58+
[1 2] [-1 3 2 5]]))))
4859

4960
(testing "meta preservation"
5061
(let [test-meta {:me "ta"}

test/clojure/core_test/assoc_bang.cljc

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,21 @@
3030
(are [expected vec ivs] (= expected (persistent! (apply assoc! (transient vec) ivs)))
3131
[1 nil] [] [0 1 1]
3232
[1 2] [] [0 1 1 2]
33-
[1 3 5 7] [1 2] [1 3 2 5 3 7]))
33+
[1 3 5 7] [1 2] [1 3 2 5 3 7]
34+
#?@(:lpy
35+
[[0 1 -1] [0 1 2] [-1 -1]
36+
[1 3 5] [1 2] [-1 3 2 5]])))
3437
(testing "vectors - out-of-bounds indices"
3538
(are [vec ivs] (thrown? #?(:cljs js/Error :default Exception) (apply assoc! (transient vec) ivs))
3639
[] [-1 0]
3740
[] [1 0]
38-
[0 1 2] [-1 -1]
3941
[0 1 2] [4 4]
4042
[1 2] [1 3 3 5]
41-
[1 2] [-1 3 2 5]
42-
[1 2] [-1 3 3 5])))
43+
[1 2] [-1 3 3 5]
44+
#?@(:lpy []
45+
:default
46+
[[0 1 2] [-1 -1]
47+
[1 2] [-1 3 2 5]]))))
4348

4449
(testing "odd number of args"
4550
; on the contrary to assoc, assoc! accepts an odd number (> 1) of args and assumes missing value is nil
@@ -49,11 +54,13 @@
4954
[1] [0 1 1]
5055
[1] [0 1 1 2 2]))
5156

52-
(testing "cannot assoc! transient after persistent! call"
53-
(let [t (transient {:a 1}), _ (persistent! t)]
54-
(is (thrown? #?(:cljs js/Error :cljr Exception :default Error) (assoc! t :b 2))))
55-
(let [t (transient [1]), _ (persistent! t)]
56-
(is (thrown? #?(:cljs js/Error :cljr Exception :default Error) (assoc! t 0 2)))))
57+
#?@(:lpy []
58+
:default
59+
[(testing "cannot assoc! transient after persistent! call"
60+
(let [t (transient {:a 1}), _ (persistent! t)]
61+
(is (thrown? #?(:cljs js/Error :cljr Exception :lpy Exception :default Error) (assoc! t :b 2))))
62+
(let [t (transient [1]), _ (persistent! t)]
63+
(is (thrown? #?(:cljs js/Error :cljr Exception :lpy Exception :default Error) (assoc! t 0 2)))))])
5764

5865
(testing "bad shape"
5966
(are [coll] (thrown? #?(:cljs js/Error :default Exception) (assoc! coll 1 3))

0 commit comments

Comments
 (0)