Compare commits
96 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8052618fa8 | ||
|
|
238a98d9b2 | ||
|
|
57b799e63d | ||
|
|
dad646ce38 | ||
|
|
35696b7c0b | ||
|
|
00d56900e8 | ||
|
|
1fc8ef6adb | ||
|
|
158b36c645 | ||
|
|
b5c65f46e1 | ||
|
|
7e64ce5dd1 | ||
|
|
73b806dbd2 | ||
|
|
0579d6a0ec | ||
|
|
cfee65101f | ||
|
|
4da643cf63 | ||
|
|
aa15e5212a | ||
|
|
e23a222fdb | ||
|
|
6c0cfde92f | ||
|
|
5f6befc577 | ||
|
|
d7b0f9155d | ||
|
|
28c2f6947f | ||
|
|
5c4fb1ccc1 | ||
|
|
5b7678f309 | ||
|
|
f33c68293b | ||
|
|
fd69206933 | ||
|
|
689148b99c | ||
|
|
3db67a5574 | ||
|
|
8191e09314 | ||
|
|
e784f4ae8a | ||
|
|
774fe99a83 | ||
|
|
f9aafc9d96 | ||
|
|
4037154a28 | ||
|
|
35e904b547 | ||
|
|
08d60112ed | ||
|
|
a9060f0027 | ||
|
|
597f180d32 | ||
|
|
007209c0d2 | ||
|
|
1b2682b67a | ||
|
|
4a2a305e38 | ||
|
|
e3908a1306 | ||
|
|
f967e10bdd | ||
|
|
4c6fe98236 | ||
|
|
28c7c42c2a | ||
|
|
6d5fc67467 | ||
|
|
50fc2e2582 | ||
|
|
a45f76b029 | ||
|
|
9ed0507030 | ||
|
|
f9935def7e | ||
|
|
d053a3c0c5 | ||
|
|
cdcf9deb1c | ||
|
|
6f43c47f2a | ||
|
|
63a51ff669 | ||
|
|
d7c80012b1 | ||
|
|
eddf51529f | ||
|
|
d1dbafc49b | ||
|
|
bc8cd6d358 | ||
|
|
b01ee6d87d | ||
|
|
a43b55bf5c | ||
|
|
4358428464 | ||
|
|
7998e50045 | ||
|
|
8d3806a6e7 | ||
|
|
455728092c | ||
|
|
da3eff0305 | ||
|
|
51b44ba2ed | ||
|
|
3cddc33334 | ||
|
|
d8521888cc | ||
|
|
1a62a619e3 | ||
|
|
ecbdbba8d4 | ||
|
|
e186726fd9 | ||
|
|
2a50af8f68 | ||
|
|
c7a5c6c6bc | ||
|
|
024f1d5515 | ||
|
|
142e9eae06 | ||
|
|
3d909f04b8 | ||
|
|
c9b9ad64fc | ||
|
|
9070db46df | ||
|
|
b16ecfdf6c | ||
|
|
1874da1d2d | ||
|
|
c89ac0bd7f | ||
|
|
def5d8fd37 | ||
|
|
2932d82a65 | ||
|
|
d8d6876832 | ||
|
|
c538d5edbd | ||
|
|
a5ec09087e | ||
|
|
5e4ce8e093 | ||
|
|
c1412f9b31 | ||
|
|
f5d7c1bb6e | ||
|
|
1deae725ae | ||
|
|
42b9ff8f25 | ||
|
|
3442f1e505 | ||
|
|
f0943d8a14 | ||
|
|
dff3b526e9 | ||
|
|
afb566f600 | ||
|
|
3cc45ec8a7 | ||
|
|
d670bbb245 | ||
|
|
62cab79ce6 | ||
|
|
f4292e1038 |
46 changed files with 2166 additions and 612 deletions
|
|
@ -5,7 +5,7 @@
|
|||
[clojure.string :as str]
|
||||
[flatland.ordered.map :refer [ordered-map]]))
|
||||
|
||||
(def graalvm-version "23")
|
||||
(def graalvm-version "24")
|
||||
|
||||
(defn run
|
||||
([cmd-name cmd]
|
||||
|
|
@ -101,7 +101,6 @@
|
|||
"export BABASHKA_FEATURE_JDBC=true
|
||||
export BABASHKA_FEATURE_POSTGRESQL=true
|
||||
script/test\nscript/run_lib_tests")
|
||||
(run "Run as lein command" ".circleci/script/lein")
|
||||
(run
|
||||
"Create uberjar"
|
||||
"mkdir -p /tmp/release
|
||||
|
|
@ -180,10 +179,13 @@ java -jar \"$jar\" --config .build/bb.edn --deps-root . release-artifact \"$refl
|
|||
(run "Build binary" (if (= "aarch64" arch)
|
||||
"script/uberjar\nscript/compile -H:PageSize=64K # --pgo=default.iprof"
|
||||
"script/uberjar\nscript/compile # --pgo=default.iprof") "30m")
|
||||
(run "Run tests" "script/test\nscript/run_lib_tests")
|
||||
(run "Release" ".circleci/script/release")
|
||||
{:persist_to_workspace {:root "/tmp"
|
||||
:paths ["release"]}}
|
||||
(run "Run tests" "script/test\nscript/run_lib_tests")
|
||||
(run "Release + publish"
|
||||
(str/join "\n" ["export BABASHKA_RELEASE=true"
|
||||
".circleci/script/release"]))
|
||||
{:save_cache
|
||||
{:paths ["~/.m2" "~/graalvm"]
|
||||
:key cache-key}}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ tar zcvf "$archive" bb # bbk
|
|||
|
||||
cd -
|
||||
|
||||
./bb --config .build/bb.edn --deps-root . release-artifact "/tmp/release/$archive"
|
||||
if [ "$BABASHKA_RELEASE" = "true" ]; then
|
||||
./bb --config .build/bb.edn --deps-root . release-artifact "/tmp/release/$archive"
|
||||
fi
|
||||
|
||||
## cleanup
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ task:
|
|||
skip: "changesIncludeOnly('logo/*', '**.md')"
|
||||
env:
|
||||
LEIN_ROOT: "true"
|
||||
GRAALVM_VERSION: "23"
|
||||
GRAALVM_VERSION: "24"
|
||||
GRAALVM_HOME: ${HOME}/graalvm-${GRAALVM_VERSION}/Contents/Home
|
||||
BABASHKA_PLATFORM: macos # used in release script
|
||||
BABASHKA_ARCH: aarch64
|
||||
|
|
|
|||
99
.github/workflows/build-windows.yml
vendored
Normal file
99
.github/workflows/build-windows.yml
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- "logo/**"
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- "**.md"
|
||||
- "logo/**"
|
||||
|
||||
# TODO: Add deploy if needed
|
||||
jobs:
|
||||
native:
|
||||
if: "!contains(github.event.head_commit.message, 'skip ci')"
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: windows-2022
|
||||
name: windows
|
||||
static: false
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
LEIN_ROOT: "true"
|
||||
GRAALVM_VERSION: "24"
|
||||
BABASHKA_PLATFORM: ${{ matrix.name }} # used in release script
|
||||
BABASHKA_TEST_ENV: native
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BABASHKA_SHA: ${{ github.sha }}
|
||||
steps:
|
||||
- name: Git checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 1
|
||||
submodules: 'true'
|
||||
|
||||
- name: Cache deps
|
||||
uses: actions/cache@v4
|
||||
id: cache-deps
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('project.clj') }}
|
||||
restore-keys: ${{ runner.os }}-maven-
|
||||
|
||||
- name: Setup GraalVM
|
||||
if: "matrix.static == false"
|
||||
uses: graalvm/setup-graalvm@v1.3.3
|
||||
with:
|
||||
java-version: '24'
|
||||
distribution: 'graalvm'
|
||||
components: 'native-image'
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Install clojure tools
|
||||
uses: DeLaGuardo/setup-clojure@13.2
|
||||
with:
|
||||
cli: latest
|
||||
# lein: latest -- skipped because this uses some PS bullshit
|
||||
|
||||
- name: Babashka version
|
||||
id: babashka-version
|
||||
shell: bash
|
||||
run: |
|
||||
BABASHKA_VERSION=$(cat resources/BABASHKA_VERSION)
|
||||
echo "##[set-output name=version;]${BABASHKA_VERSION}"
|
||||
|
||||
- name: Build
|
||||
shell: cmd
|
||||
run: |
|
||||
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein.bat', 'lein.bat')"
|
||||
call lein self-install
|
||||
|
||||
set GRAALVM_HOME=%JAVA_HOME%
|
||||
call script/uberjar.bat
|
||||
|
||||
call script/compile.bat
|
||||
|
||||
echo Creating zip archive
|
||||
|
||||
set zip=babashka-%BABASHKA_VERSION%-windows-amd64.zip
|
||||
|
||||
jar -cMf %zip% bb.exe
|
||||
|
||||
bb --config .build/bb.edn --deps-root . release-artifact %zip%
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: bb.exe
|
||||
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-amd64
|
||||
|
||||
- name: Test binary and libs
|
||||
shell: cmd
|
||||
run: |
|
||||
set BABASHKA_CLASSPATH=
|
||||
set BABASHKA_TEST_ENV=native
|
||||
call script/test.bat :windows
|
||||
call script/run_lib_tests.bat
|
||||
31
.github/workflows/build.yml
vendored
31
.github/workflows/build.yml
vendored
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
submodules: 'true'
|
||||
|
||||
- name: Cache deps
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
id: cache-deps
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
|
|
@ -60,9 +60,6 @@ jobs:
|
|||
script/test
|
||||
script/run_lib_tests
|
||||
|
||||
- name: Run as lein command
|
||||
run: echo '{:a 1}' | lein bb '(:a *in*)'
|
||||
|
||||
- name: Build uberjar
|
||||
run: |
|
||||
mkdir -p /tmp/release
|
||||
|
|
@ -91,7 +88,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: macos-12
|
||||
- os: macos-13
|
||||
name: macos
|
||||
static: false
|
||||
#- os: ubuntu-latest
|
||||
|
|
@ -103,7 +100,7 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
LEIN_ROOT: "true"
|
||||
GRAALVM_VERSION: "23"
|
||||
GRAALVM_VERSION: "24"
|
||||
BABASHKA_PLATFORM: ${{ matrix.name }} # used in release script
|
||||
BABASHKA_TEST_ENV: native
|
||||
BABASHKA_XMX: "-J-Xmx6500m"
|
||||
|
|
@ -117,7 +114,7 @@ jobs:
|
|||
submodules: 'true'
|
||||
|
||||
- name: Cache deps
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
id: cache-deps
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
|
|
@ -128,7 +125,7 @@ jobs:
|
|||
if: "matrix.static == false"
|
||||
uses: graalvm/setup-graalvm@v1
|
||||
with:
|
||||
java-version: '23'
|
||||
java-version: '24'
|
||||
distribution: 'graalvm'
|
||||
components: 'native-image'
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
@ -137,7 +134,7 @@ jobs:
|
|||
if: "matrix.static == true"
|
||||
uses: graalvm/setup-graalvm@v1
|
||||
with:
|
||||
version: '23'
|
||||
version: '24'
|
||||
distribution: 'graalvm'
|
||||
components: 'native-image'
|
||||
native-image-musl: true
|
||||
|
|
@ -175,14 +172,6 @@ jobs:
|
|||
BABASHKA_MUSL: "true"
|
||||
run: script/compile
|
||||
|
||||
- name: Test binary and libs
|
||||
run: |
|
||||
script/test
|
||||
script/run_lib_tests
|
||||
|
||||
- name: Release
|
||||
run: .circleci/script/release
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
|
@ -196,6 +185,14 @@ jobs:
|
|||
path: bb
|
||||
name: babashka-${{ steps.babashka-version.outputs.version }}-${{ matrix.name }}-static-amd64
|
||||
|
||||
- name: Test binary and libs
|
||||
run: |
|
||||
script/test
|
||||
script/run_lib_tests
|
||||
|
||||
- name: Release
|
||||
run: .circleci/script/release
|
||||
|
||||
docker:
|
||||
if: ${{ false }} # Disabled
|
||||
# if: "!contains(github.event.head_commit.message, 'skip ci') && github.event_name == 'push' && github.ref == 'refs/heads/master'"
|
||||
|
|
|
|||
76
CHANGELOG.md
76
CHANGELOG.md
|
|
@ -7,6 +7,82 @@ A preview of the next release can be installed from
|
|||
|
||||
[Babashka](https://github.com/babashka/babashka): Native, fast starting Clojure interpreter for scripting
|
||||
|
||||
## Unreleased
|
||||
|
||||
- [#1818](https://github.com/babashka/babashka/issues/1818): wrong argument order in `clojure.java.io/resource` implementation
|
||||
- Add `java.text.BreakIterator`
|
||||
- Bump `fs` to `0.5.25`
|
||||
- Bump `jsoup` to `1.20.1`
|
||||
- Bump `edamame` to `1.4.30`
|
||||
- [#1815](https://github.com/babashka/babashka/issues/1815): Make install-script wget-compatible ([@eval](https://github.com/eval))
|
||||
|
||||
|
||||
## 1.12.200 (2025-04-26)
|
||||
|
||||
- Improve Java reflection based on provided type hints (read blog post [here](https://blog.michielborkent.nl/babashka-java-reflection-type-hints.html))
|
||||
- Add compatibility with the [fusebox](https://github.com/potetm/fusebox) library
|
||||
- Fix virtual `ThreadBuilder` interop
|
||||
- Add `java.util.concurrent.ThreadLocalRandom`
|
||||
- Add `java.util.concurrent.locks.ReentrantLock`
|
||||
- Add classes:
|
||||
- `java.time.chrono.ChronoLocalDate`
|
||||
- `java.time.temporal.TemporalUnit`
|
||||
- `java.time.chrono.ChronoLocalDateTime`
|
||||
- `java.time.chrono.ChronoZonedDateTime`
|
||||
- `java.time.chrono.Chronology`
|
||||
|
||||
## 1.12.199 (2025-04-18)
|
||||
|
||||
- [#1806](https://github.com/babashka/babashka/issues/1806): Add `cheshire.factory` namespace ([@lread](https://github.com/lread))
|
||||
|
||||
## 1.12.198 (2025-04-17)
|
||||
|
||||
- Bump GraalVM to `24`
|
||||
- Bump SCI to `0.9.45`
|
||||
- Bump edamame to `1.4.28`
|
||||
- [#1801](https://github.com/babashka/babashka/issues/1801): Add `java.util.regex.PatternSyntaxException`
|
||||
- Bump core.async to `1.8.735`
|
||||
- Bump cheshire to `6.0.0`
|
||||
- Bump babashka.cli to `0.8.65`
|
||||
|
||||
## 1.12.197 (2025-02-28)
|
||||
|
||||
- [#1785](https://github.com/babashka/babashka/issues/1785): Allow subclasses of `Throwable` to have instance methods invoked ([@bobisageek](https://github.com/bobisageek))
|
||||
- [#1791](https://github.com/babashka/babashka/issues/1791): interop problem on Jsoup form element
|
||||
- [#1793](https://github.com/babashka/babashka/issues/1793): Bump `rewrite-clj` to `1.1.49` (fixes parsing of `foo//` among other things)
|
||||
- Bump `deps.clj`
|
||||
- Bump `fs`
|
||||
|
||||
## 1.12.196 (2024-12-24)
|
||||
|
||||
- [#1771](https://github.com/babashka/babashka/issues/1771): `*e*` in REPL should contain exception thrown by user, not a wrapped one
|
||||
- [#1777](https://github.com/babashka/babashka/issues/1777) Add `java.nio.file.attribute.UserDefinedFileAttributeView`
|
||||
- [#1776](https://github.com/babashka/babashka/issues/1776) `Add java.nio.file.attribute.PosixFileAttributes`
|
||||
- [#1761](https://github.com/babashka/babashka/issues/1761) Support calling `clojure.lang.RT/iter`
|
||||
- [#1760](https://github.com/babashka/babashka/issues/1760) For compatibility with [Fireworks v0.10.3](https://github.com/paintparty/fireworks), added the following to `:instance-checks` entry in `babashka.impl.classes/classes`([@paintparty](https://github.com/paintparty))
|
||||
- `clojure.lang.PersistentArrayMap$TransientArrayMap`
|
||||
- `clojure.lang.PersistentHashMap$TransientHashMap`
|
||||
- `clojure.lang.PersistentVector$TransientVector`
|
||||
- `java.lang.NoSuchFieldException`
|
||||
- `java.util.AbstractMap`
|
||||
- `java.util.AbstractSet`
|
||||
- `java.util.AbstractList`
|
||||
- [#1760](https://github.com/babashka/babashka/issues/1760) For compatibility with [Fireworks v0.10.3](https://github.com/paintparty/fireworks), added `volatile?` entry to `babashka.impl.clojure.core/core-extras`([@paintparty](https://github.com/paintparty))
|
||||
- Bump `babashka.cli` to `0.8.61`
|
||||
- Bump `clj-yaml` to `1.0.29`
|
||||
- [#1768](https://github.com/babashka/babashka/issues/1768): Add `taoensso.timbre` `color-str` function
|
||||
- Add classes:
|
||||
- `javax.crypto.KeyAgreement`
|
||||
- `java.security.KeyPairGenerator`
|
||||
- `java.security.KeyPair`
|
||||
- `java.security.spec.ECGenParameterSpec`
|
||||
- `java.security.spec.PKCS8EncodedKeySpec`
|
||||
- `java.security.spec.X509EncodedKeySpec`
|
||||
- `java.security.Signature`
|
||||
- Add `java.util.concurrent.CompletionStage`
|
||||
- Bump `core.async` to `1.7.701`
|
||||
- Bump `org.babashka/cli` to `0.8.162`
|
||||
|
||||
## 1.12.195 (2024-11-12)
|
||||
|
||||
- Include [jsoup](https://jsoup.org/) for HTML parsing. This makes bb compatible with the [hickory](https://github.com/clj-commons/hickory) library (and possibly other libraries?).
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ RUN apt update
|
|||
RUN apt install --no-install-recommends -yy build-essential zlib1g-dev
|
||||
WORKDIR "/opt"
|
||||
|
||||
ENV GRAALVM_VERSION="23"
|
||||
ENV GRAALVM_VERSION="24"
|
||||
ARG TARGETARCH
|
||||
# Do not set those directly, use TARGETARCH instead
|
||||
ENV BABASHKA_ARCH=
|
||||
|
|
|
|||
61
README.md
61
README.md
|
|
@ -4,7 +4,7 @@
|
|||
[](https://app.slack.com/client/T03RZGPFR/CLX41ASCS)
|
||||
[](https://opencollective.com/babashka) [](https://clojars.org/babashka/babashka)
|
||||
[](https://twitter.com/search?q=%23babashka&src=typed_query&f=live)
|
||||
[](https://book.babashka.org)
|
||||
[](https://book.babashka.org) [](https://gurubase.io/g/babashka)
|
||||
|
||||
<blockquote class="twitter-tweet" data-lang="en">
|
||||
<p lang="en" dir="ltr">Life's too short to remember how to write Bash code. I feel liberated.</p>
|
||||
|
|
@ -232,6 +232,8 @@ Install via the installer script for linux and macOS:
|
|||
|
||||
``` shell
|
||||
$ curl -sLO https://raw.githubusercontent.com/babashka/babashka/master/install
|
||||
# or
|
||||
$ wget -qO install https://raw.githubusercontent.com/babashka/babashka/master/install
|
||||
$ chmod +x install
|
||||
$ ./install
|
||||
```
|
||||
|
|
@ -303,63 +305,16 @@ Go [here](https://book.babashka.org/#built-in-namespaces) to see the full list o
|
|||
A list of projects (scripts, libraries, pods and tools) known to work with babashka.
|
||||
|
||||
## Badges
|
||||
<!-- note to editor: it seems a blank line must appear before code blocks within <details> -->
|
||||
|
||||
[](https://babashka.org)
|
||||
|
||||
The babashka compatible badge indicates that a [library can be used as babashka dependency](doc/projects.md).
|
||||
|
||||
[](https://book.babashka.org#badges)
|
||||
The babashka compatible badge indicates that a library can be used as babashka dependency.
|
||||
If this is the case for your library, we encourage you to proudly display this badge.
|
||||
|
||||
<details><summary>Markdown</summary>
|
||||
|
||||
```markdown
|
||||
[](https://babashka.org)
|
||||
```
|
||||
</details>
|
||||
|
||||
<details><summary>AsciiDoc</summary>
|
||||
|
||||
```asciidoc
|
||||
https://babashka.org[image:https://raw.githubusercontent.com/babashka/babashka/master/logo/badge.svg[bb compatible]]
|
||||
```
|
||||
</details>
|
||||
|
||||
<details><summary>HTML</summary>
|
||||
|
||||
```html
|
||||
<a href="https://babashka.org" rel="nofollow"><img src="https://github.com/babashka/babashka/raw/master/logo/badge.svg" alt="bb compatible" style="max-width: 100%;"></a>
|
||||
```
|
||||
</details>
|
||||
<br/>
|
||||
|
||||
[](https://babashka.org)
|
||||
|
||||
The babashka built-in badge means that a [library has been built directly into babashka](https://book.babashka.org/#built-in-namespaces) and requires no extra dependencies to use it.
|
||||
|
||||
[](https://book.babashka.org#badges)
|
||||
The babashka built-in badge means that a library has been built directly into babashka and requires no extra dependencies to use it.
|
||||
If this rare honor belongs to your library, you should display this badge.
|
||||
|
||||
<details><summary>Markdown</summary>
|
||||
|
||||
```markdown
|
||||
[](https://babashka.org)
|
||||
```
|
||||
</details>
|
||||
|
||||
<details><summary>AsciiDoc</summary>
|
||||
|
||||
```asciidoc
|
||||
https://babashka.org[image:https://raw.githubusercontent.com/babashka/babashka/master/logo/built-in-badge.svg[bb built-in]]
|
||||
```
|
||||
</details>
|
||||
|
||||
<details><summary>HTML</summary>
|
||||
|
||||
```html
|
||||
<a href="https://babashka.org" rel="nofollow"><img src="https://github.com/babashka/babashka/raw/master/logo/built-in-badge.svg" alt="bb built-in" style="max-width: 100%;"></a>
|
||||
```
|
||||
</details>
|
||||
</br>
|
||||
See [the babashka book for details](https://book.babashka.org#badges).
|
||||
|
||||
## Swag
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ image: Visual Studio 2022
|
|||
clone_folder: C:\projects\babashka
|
||||
|
||||
environment:
|
||||
GRAALVM_HOME: C:\projects\babashka\graalvm\graalvm-jdk-23+37.1
|
||||
JAVA_HOME: C:\projects\babashka\graalvm\graalvm-jdk-23+37.1
|
||||
GRAALVM_HOME: C:\projects\babashka\graalvm\graalvm-jdk-24+36.1
|
||||
JAVA_HOME: C:\projects\babashka\graalvm\graalvm-jdk-24+36.1
|
||||
BABASHKA_XMX: "-J-Xmx5g"
|
||||
|
||||
skip_commits:
|
||||
|
|
@ -44,7 +44,7 @@ clone_script:
|
|||
build_script:
|
||||
# TODO: Extract the zip by removing the top level folder to remove the hardcoded path for GRAALVM_HOME
|
||||
- cmd: >-
|
||||
powershell -Command "if (Test-Path('graalvm')) { return } else { (New-Object Net.WebClient).DownloadFile('https://download.oracle.com/graalvm/23/archive/graalvm-jdk-23_windows-x64_bin.zip', 'graalvm.zip') }"
|
||||
powershell -Command "if (Test-Path('graalvm')) { return } else { (New-Object Net.WebClient).DownloadFile('https://download.oracle.com/graalvm/24/archive/graalvm-jdk-24_windows-x64_bin.zip', 'graalvm.zip') }"
|
||||
|
||||
powershell -Command "if (Test-Path('graalvm')) { return } else { Expand-Archive graalvm.zip graalvm }"
|
||||
|
||||
|
|
|
|||
2
deps.clj
2
deps.clj
|
|
@ -1 +1 @@
|
|||
Subproject commit 4fd62578e215b7341dd6c818259e47c461949573
|
||||
Subproject commit 976cf7b0e54901ada3f7e83f12a4c0aed039adc9
|
||||
19
deps.edn
19
deps.edn
|
|
@ -25,13 +25,12 @@
|
|||
babashka/babashka.curl {:local/root "babashka.curl"}
|
||||
babashka/fs {:local/root "fs"}
|
||||
babashka/babashka.core {:local/root "babashka.core"}
|
||||
borkdude/graal.locking {:mvn/version "0.0.2"},
|
||||
org.clojure/core.async {:mvn/version "1.6.673"},
|
||||
org.clojure/core.async {:mvn/version "1.8.741"},
|
||||
org.clojure/tools.cli {:mvn/version "1.0.214"},
|
||||
org.clojure/data.csv {:mvn/version "1.0.0"},
|
||||
cheshire/cheshire {:mvn/version "5.13.0"}
|
||||
cheshire/cheshire {:mvn/version "6.0.0"}
|
||||
org.clojure/data.xml {:mvn/version "0.2.0-alpha8"}
|
||||
clj-commons/clj-yaml {:mvn/version "1.0.28"}
|
||||
clj-commons/clj-yaml {:mvn/version "1.0.29"}
|
||||
com.cognitect/transit-clj {:mvn/version "1.0.333"}
|
||||
org.clojure/test.check {:mvn/version "1.1.1"}
|
||||
nrepl/bencode {:mvn/version "1.2.0"}
|
||||
|
|
@ -43,17 +42,17 @@
|
|||
babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"}
|
||||
org.clojure/core.match {:mvn/version "1.0.0"}
|
||||
hiccup/hiccup {:mvn/version "2.0.0-RC1"}
|
||||
rewrite-clj/rewrite-clj {:mvn/version "1.1.48"}
|
||||
rewrite-clj/rewrite-clj {:mvn/version "1.1.49"}
|
||||
selmer/selmer {:mvn/version "1.12.59"}
|
||||
com.taoensso/timbre {:mvn/version "6.6.0"}
|
||||
org.clojure/tools.logging {:mvn/version "1.1.0"}
|
||||
org.clojure/data.priority-map {:mvn/version "1.1.0"}
|
||||
insn/insn {:mvn/version "0.5.2"}
|
||||
org.clojure/core.rrb-vector {:mvn/version "0.1.2"}
|
||||
org.babashka/cli {:mvn/version "0.8.59"}
|
||||
org.babashka/cli {:mvn/version "0.8.65"}
|
||||
org.babashka/http-client {:mvn/version "0.4.22"}
|
||||
org.flatland/ordered {:mvn/version "1.15.12"}
|
||||
org.jsoup/jsoup {:mvn/version "1.18.1"}}
|
||||
org.jsoup/jsoup {:mvn/version "1.20.1"}}
|
||||
:aliases {:babashka/dev
|
||||
{:main-opts ["-m" "babashka.main"]}
|
||||
:profile
|
||||
|
|
@ -175,7 +174,11 @@
|
|||
prismatic/plumbing {:git/url "https://github.com/plumatic/plumbing",
|
||||
:git/sha "424bc704f2db422de34269c139a5494314b3a43b"}
|
||||
org.clj-commons/hickory {:git/url "https://github.com/clj-commons/hickory"
|
||||
:git/sha "27ee318928b6748075fa9954740afedf916ff795"}}
|
||||
:git/sha "9385b6708ef35f161732d8464b3a3aa57dd79f30"}
|
||||
com.potetm/fusebox {:git/url "https://github.com/potetm/fusebox"
|
||||
:git/sha "ac6d6a0a69510b009b3c1bb2247cd110fd9f7246"}
|
||||
net.sekao/odoyle-rules {:git/url "https://github.com/oakes/odoyle-rules"
|
||||
:git/sha "0b1d825ec45a998c4d3481dfb292e08ce6a47f0b"}}
|
||||
:classpath-overrides {org.clojure/clojure nil
|
||||
org.clojure/spec.alpha nil}}
|
||||
:clj-nvd
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
## Prerequisites
|
||||
|
||||
- Install [lein](https://leiningen.org/) for producing uberjars
|
||||
- Download [GraalVM](https://www.graalvm.org/downloads/). Currently we use *Oracle GraalVM 23*.
|
||||
- Download [GraalVM](https://www.graalvm.org/downloads/). Currently we use *Oracle GraalVM 24*.
|
||||
- For Windows, installing Visual Studio 2019 with the "Desktop development
|
||||
with C++" workload is recommended.
|
||||
- Set `$GRAALVM_HOME` to the GraalVM distribution directory. On macOS this can look like:
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ reasons:
|
|||
|
||||
## Requirements
|
||||
|
||||
You need [lein](https://leiningen.org/) for running JVM tests and/or producing uberjars. For building binaries you need GraalVM. Currently we use Oracle GraalVM 23.
|
||||
You need [lein](https://leiningen.org/) for running JVM tests and/or producing uberjars. For building binaries you need GraalVM. Currently we use Oracle GraalVM 24.
|
||||
|
||||
## Clone repository
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ borkdude/missing.test.assertions,https://github.com/borkdude/missing.test.assert
|
|||
borkdude/rewrite-edn,https://github.com/borkdude/rewrite-edn
|
||||
camel-snake-kebab/camel-snake-kebab,https://github.com/clj-commons/camel-snake-kebab
|
||||
cc.qbits/auspex,https://github.com/mpenet/auspex
|
||||
cheshire/cheshire,https://github.com/dakrone/cheshire
|
||||
circleci/bond,https://github.com/circleci/bond
|
||||
cli-matic/cli-matic,https://github.com/l3nz/cli-matic.git
|
||||
clj-commons/clj-yaml,https://github.com/clj-commons/clj-yaml
|
||||
|
|
|
|||
|
|
|
@ -143,7 +143,8 @@
|
|||
'info 'infof 'warn 'warnf
|
||||
'error 'errorf
|
||||
'-log! 'with-level
|
||||
'spit-appender '-spy 'spy])
|
||||
'spit-appender '-spy 'spy
|
||||
'color-str])
|
||||
'log! (sci/copy-var log! tns)
|
||||
'*config* config
|
||||
'swap-config! (sci/copy-var swap-config! tns)
|
||||
|
|
|
|||
2
fs
2
fs
|
|
@ -1 +1 @@
|
|||
Subproject commit 99d6a3b2f55b851a6949ed6eee31412b299dcf01
|
||||
Subproject commit fdd5780bc4df4931332b56082c6c3a5c3c85066d
|
||||
36
install
36
install
|
|
@ -29,6 +29,32 @@ print_help() {
|
|||
exit 1
|
||||
}
|
||||
|
||||
has() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
fetch() {
|
||||
local url=$1
|
||||
local outfile=${2:-}
|
||||
|
||||
if has wget; then
|
||||
if [[ -n $outfile ]]; then
|
||||
wget -qO "$outfile" "$url"
|
||||
else
|
||||
wget -qO - "$url"
|
||||
fi
|
||||
elif has curl; then
|
||||
if [[ -n $outfile ]]; then
|
||||
curl -fsSL "$url" -o "$outfile"
|
||||
else
|
||||
curl -fsSL "$url"
|
||||
fi
|
||||
else
|
||||
>&2 echo "Either 'wget' or 'curl' needs to be on PATH!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
key="$1"
|
||||
|
|
@ -80,9 +106,9 @@ fi
|
|||
|
||||
if [[ "$version" == "" ]]; then
|
||||
if [[ "$dev_build" == "true" ]]; then
|
||||
version="$(curl -sL https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_VERSION)"
|
||||
version="$(fetch https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_VERSION)"
|
||||
else
|
||||
version="$(curl -sL https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_RELEASED_VERSION)"
|
||||
version="$(fetch https://raw.githubusercontent.com/babashka/babashka/master/resources/BABASHKA_RELEASED_VERSION)"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
@ -144,9 +170,9 @@ download_url="https://github.com/babashka/$repo/releases/download/v$version/$fil
|
|||
|
||||
# macOS only have shasum available by default
|
||||
# Some Linux distros (RHEL-like) only have sha256sum available by default (others have both)
|
||||
if command -v sha256sum >/dev/null; then
|
||||
if has sha256sum; then
|
||||
sha256sum_cmd="sha256sum"
|
||||
elif command -v shasum >/dev/null; then
|
||||
elif has shasum; then
|
||||
sha256sum_cmd="shasum -a 256"
|
||||
else
|
||||
>&2 echo "Either 'sha256sum' or 'shasum' needs to be on PATH for '--checksum' flag!"
|
||||
|
|
@ -159,7 +185,7 @@ mkdir -p "$download_dir" && (
|
|||
cd "$download_dir"
|
||||
echo -e "Downloading $download_url to $download_dir"
|
||||
|
||||
curl -o "$filename" -sL "$download_url"
|
||||
fetch "$download_url" "$filename"
|
||||
if [[ -n "$checksum" ]]; then
|
||||
if ! echo "$checksum *$filename" | $sha256sum_cmd --check --status; then
|
||||
>&2 echo "Failed checksum on $filename"
|
||||
|
|
|
|||
2
process
2
process
|
|
@ -1 +1 @@
|
|||
Subproject commit 5160f98666363afeeea9f728d12e7f0fd39263cd
|
||||
Subproject commit 2058c79fb63f80ca71917432eddea73e0c58717c
|
||||
18
project.clj
18
project.clj
|
|
@ -22,28 +22,28 @@
|
|||
:flaky :flaky}
|
||||
:jvm-opts ["--enable-preview"]
|
||||
:dependencies [[org.clojure/clojure "1.12.0"]
|
||||
[borkdude/edamame "1.4.27"]
|
||||
[borkdude/graal.locking "0.0.2"]
|
||||
[borkdude/edamame "1.4.30"]
|
||||
[org.clojure/tools.cli "1.0.214"]
|
||||
[cheshire "5.13.0"]
|
||||
[cheshire "6.0.0"]
|
||||
[nrepl/bencode "1.2.0"]
|
||||
[borkdude/sci.impl.reflector "0.0.3"]
|
||||
[borkdude/sci.impl.reflector "0.0.4"]
|
||||
[org.babashka/sci.impl.types "0.0.2"]
|
||||
[org.babashka/babashka.impl.java "0.1.10"]
|
||||
[org.clojure/core.async "1.6.673"]
|
||||
[org.clojure/core.async "1.8.741"]
|
||||
[org.clojure/test.check "1.1.1"]
|
||||
[com.github.clj-easy/graal-build-time "0.1.0"]
|
||||
[rewrite-clj/rewrite-clj "1.1.48"]
|
||||
[rewrite-clj/rewrite-clj "1.1.49"]
|
||||
[insn/insn "0.5.2"]
|
||||
[org.babashka/cli "0.8.59"]
|
||||
[org.babashka/cli "0.8.65"]
|
||||
[org.babashka/http-client "0.4.22"]
|
||||
[org.jsoup/jsoup "1.18.1"]]
|
||||
[org.jsoup/jsoup "1.20.1"]
|
||||
[borkdude/graal.locking "0.0.2"]]
|
||||
:plugins [[org.kipz/lein-meta-bom "0.1.1"]]
|
||||
:metabom {:jar-name "metabom.jar"}
|
||||
:profiles {:feature/xml {:source-paths ["feature-xml"]
|
||||
:dependencies [[org.clojure/data.xml "0.2.0-alpha8"]]}
|
||||
:feature/yaml {:source-paths ["feature-yaml"]
|
||||
:dependencies [[clj-commons/clj-yaml "1.0.28"
|
||||
:dependencies [[clj-commons/clj-yaml "1.0.29"
|
||||
:exclusions [org.flatland/ordered]#_#_clj-commons/clj-yaml "0.7.110"]
|
||||
[org.flatland/ordered "1.15.12"]]}
|
||||
:feature/jdbc {:source-paths ["feature-jdbc"]
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
1.12.195
|
||||
1.12.200
|
||||
|
|
@ -1 +1 @@
|
|||
1.12.196-SNAPSHOT
|
||||
1.12.201-SNAPSHOT
|
||||
|
|
@ -25,13 +25,12 @@
|
|||
babashka/babashka.curl {:local/root "babashka.curl"}
|
||||
babashka/fs {:local/root "fs"}
|
||||
babashka/babashka.core {:local/root "babashka.core"}
|
||||
borkdude/graal.locking {:mvn/version "0.0.2"},
|
||||
org.clojure/core.async {:mvn/version "1.6.673"},
|
||||
org.clojure/core.async {:mvn/version "1.8.741"},
|
||||
org.clojure/tools.cli {:mvn/version "1.0.214"},
|
||||
org.clojure/data.csv {:mvn/version "1.0.0"},
|
||||
cheshire/cheshire {:mvn/version "5.13.0"}
|
||||
cheshire/cheshire {:mvn/version "6.0.0"}
|
||||
org.clojure/data.xml {:mvn/version "0.2.0-alpha8"}
|
||||
clj-commons/clj-yaml {:mvn/version "1.0.28"}
|
||||
clj-commons/clj-yaml {:mvn/version "1.0.29"}
|
||||
com.cognitect/transit-clj {:mvn/version "1.0.333"}
|
||||
org.clojure/test.check {:mvn/version "1.1.1"}
|
||||
nrepl/bencode {:mvn/version "1.2.0"}
|
||||
|
|
@ -43,17 +42,17 @@
|
|||
babashka/clojure-lanterna {:mvn/version "0.9.8-SNAPSHOT"}
|
||||
org.clojure/core.match {:mvn/version "1.0.0"}
|
||||
hiccup/hiccup {:mvn/version "2.0.0-RC1"}
|
||||
rewrite-clj/rewrite-clj {:mvn/version "1.1.48"}
|
||||
rewrite-clj/rewrite-clj {:mvn/version "1.1.49"}
|
||||
selmer/selmer {:mvn/version "1.12.59"}
|
||||
com.taoensso/timbre {:mvn/version "6.6.0"}
|
||||
org.clojure/tools.logging {:mvn/version "1.1.0"}
|
||||
org.clojure/data.priority-map {:mvn/version "1.1.0"}
|
||||
insn/insn {:mvn/version "0.5.2"}
|
||||
org.clojure/core.rrb-vector {:mvn/version "0.1.2"}
|
||||
org.babashka/cli {:mvn/version "0.8.59"}
|
||||
org.babashka/http-client {:mvn/version "0.4.21"}
|
||||
org.babashka/cli {:mvn/version "0.8.65"}
|
||||
org.babashka/http-client {:mvn/version "0.4.22"}
|
||||
org.flatland/ordered {:mvn/version "1.15.12"}
|
||||
org.jsoup/jsoup {:mvn/version "1.18.1"}}
|
||||
org.jsoup/jsoup {:mvn/version "1.20.1"}}
|
||||
:aliases {:babashka/dev
|
||||
{:main-opts ["-m" "babashka.main"]}
|
||||
:profile
|
||||
|
|
@ -173,7 +172,13 @@
|
|||
:git/sha "550dbc150a79c6ecc148d8a7e260e10bc36321c6"
|
||||
:deps/manifest :deps}
|
||||
prismatic/plumbing {:git/url "https://github.com/plumatic/plumbing",
|
||||
:git/sha "424bc704f2db422de34269c139a5494314b3a43b"}}
|
||||
:git/sha "424bc704f2db422de34269c139a5494314b3a43b"}
|
||||
org.clj-commons/hickory {:git/url "https://github.com/clj-commons/hickory"
|
||||
:git/sha "9385b6708ef35f161732d8464b3a3aa57dd79f30"}
|
||||
com.potetm/fusebox {:git/url "https://github.com/potetm/fusebox"
|
||||
:git/sha "ac6d6a0a69510b009b3c1bb2247cd110fd9f7246"}
|
||||
net.sekao/odoyle-rules {:git/url "https://github.com/oakes/odoyle-rules"
|
||||
:git/sha "0b1d825ec45a998c4d3481dfb292e08ce6a47f0b"}}
|
||||
:classpath-overrides {org.clojure/clojure nil
|
||||
org.clojure/spec.alpha nil}}
|
||||
:clj-nvd
|
||||
|
|
|
|||
2
sci
2
sci
|
|
@ -1 +1 @@
|
|||
Subproject commit fd0cb735c8b332ec4c6603e7da8b69c01be96fad
|
||||
Subproject commit e85433a0214114fdceb4ca896e1b9c27b1bdf713
|
||||
|
|
@ -45,7 +45,6 @@
|
|||
"appveyor.yml"
|
||||
"project.clj"
|
||||
"script/bump_graal_version.clj"
|
||||
".circleci/script/short_ci.clj"
|
||||
".cirrus.yml"
|
||||
"script/install-graalvm"])
|
||||
|
||||
|
|
@ -55,7 +54,7 @@
|
|||
;; OR
|
||||
;;
|
||||
;; We could have them as environment variables
|
||||
(def current-graal-version "23")
|
||||
(def current-graal-version "24")
|
||||
|
||||
(def cl-options
|
||||
[["-g" "--graal VERSION" "graal version"]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ set -euo pipefail
|
|||
|
||||
INSTALL_DIR="${1:-$HOME}"
|
||||
|
||||
GRAALVM_VERSION="${GRAALVM_VERSION:-23}"
|
||||
GRAALVM_VERSION="${GRAALVM_VERSION:-24}"
|
||||
|
||||
GRAALVM_PLATFORM=$BABASHKA_PLATFORM
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ esac
|
|||
|
||||
GRAALVM_DIR_NAME="graalvm-$GRAALVM_VERSION"
|
||||
GRAALVM_FILENAME="graalvm-jdk-${GRAALVM_VERSION}_${GRAALVM_PLATFORM}-${GRAALVM_ARCH}_bin.tar.gz"
|
||||
DOWNLOAD_URL="https://download.oracle.com/graalvm/23/archive/${GRAALVM_FILENAME}"
|
||||
DOWNLOAD_URL="https://download.oracle.com/graalvm/${GRAALVM_VERSION}/archive/${GRAALVM_FILENAME}"
|
||||
|
||||
pushd "$INSTALL_DIR" >/dev/null
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
(ns aaaa-this-has-to-be-first.because-patches
|
||||
;; we need pprint loaded first, it patches pprint to not bloat the GraalVM binary
|
||||
(:require [babashka.impl.patches.datafy]
|
||||
[babashka.impl.pprint]))
|
||||
[babashka.impl.pprint]
|
||||
))
|
||||
|
||||
;; Enable this for scanning requiring usage:
|
||||
(def enable-require-scan
|
||||
|
|
|
|||
|
|
@ -1,25 +1,120 @@
|
|||
(ns babashka.impl.cheshire
|
||||
{:no-doc true}
|
||||
(:require [cheshire.core :as json]
|
||||
[cheshire.factory :as fact]
|
||||
[sci.core :as sci :refer [copy-var]]))
|
||||
|
||||
(def tns (sci/create-ns 'cheshire.core nil))
|
||||
(def fns (sci/create-ns 'cheshire.factory nil))
|
||||
|
||||
(def json-factory (sci/new-dynamic-var '*json-factory* nil {:ns fns}))
|
||||
|
||||
;; wrap cheshire fns to support `*json-factory*` dynamic var
|
||||
|
||||
(defn generate-string
|
||||
([obj]
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/generate-string obj)))
|
||||
([obj opt-map]
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/generate-string obj opt-map))))
|
||||
|
||||
(defn generate-stream
|
||||
([obj writer]
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/generate-stream obj writer)))
|
||||
([obj writer opt-map]
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/generate-stream obj writer opt-map))))
|
||||
|
||||
(defn parse-string
|
||||
([string]
|
||||
(when string
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-string string))))
|
||||
([string key-fn]
|
||||
(when string
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-string string key-fn))))
|
||||
([^String string key-fn array-coerce-fn]
|
||||
(when string
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-string string key-fn array-coerce-fn)))))
|
||||
|
||||
(defn parse-string-strict
|
||||
([string]
|
||||
(when string
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-string-strict string))))
|
||||
([string key-fn]
|
||||
(when string
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-string-strict string key-fn))))
|
||||
([^String string key-fn array-coerce-fn]
|
||||
(when string
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-string-strict string key-fn array-coerce-fn)))))
|
||||
|
||||
(defn parse-stream
|
||||
([rdr]
|
||||
(when rdr
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-stream rdr))))
|
||||
([rdr key-fn]
|
||||
(when rdr
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-stream rdr key-fn))))
|
||||
([rdr key-fn array-coerce-fn]
|
||||
(when rdr
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-stream rdr key-fn array-coerce-fn)))))
|
||||
|
||||
(defn parse-stream-strict
|
||||
([rdr]
|
||||
(when rdr
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-stream-strict rdr))))
|
||||
([rdr key-fn]
|
||||
(when rdr
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-stream-strict rdr key-fn))))
|
||||
([rdr key-fn array-coerce-fn]
|
||||
(when rdr
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parse-stream-strict rdr key-fn array-coerce-fn)))))
|
||||
|
||||
(defn parsed-seq
|
||||
([reader]
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parsed-seq reader)))
|
||||
([reader key-fn]
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parsed-seq reader key-fn)))
|
||||
([reader key-fn array-coerce-fn]
|
||||
(binding [fact/*json-factory* @json-factory]
|
||||
(json/parsed-seq reader key-fn array-coerce-fn))))
|
||||
|
||||
(def cheshire-core-namespace
|
||||
{'encode (copy-var json/encode tns)
|
||||
'generate-string (copy-var json/generate-string tns)
|
||||
'encode-stream (copy-var json/encode-stream tns)
|
||||
'generate-stream (copy-var json/generate-stream tns)
|
||||
{'encode (copy-var generate-string tns)
|
||||
'generate-string (copy-var generate-string tns)
|
||||
'encode-stream (copy-var generate-stream tns)
|
||||
'generate-stream (copy-var generate-stream tns)
|
||||
;;'encode-smile (copy-var json/encode-smile tns)
|
||||
;;'generate-smile (copy-var json/generate-smile tns)
|
||||
'decode (copy-var json/decode tns)
|
||||
'parse-string (copy-var json/parse-string tns)
|
||||
'parse-string-strict (copy-var json/parse-string-strict tns)
|
||||
'decode (copy-var parse-string tns)
|
||||
'parse-string (copy-var parse-string tns)
|
||||
'parse-string-strict (copy-var parse-string-strict tns)
|
||||
;;'parse-smile (copy-var json/parse-smile tns)
|
||||
'parse-stream (copy-var json/parse-stream tns)
|
||||
'parse-stream-strict (copy-var json/parse-stream-strict tns)
|
||||
'parsed-seq (copy-var json/parsed-seq tns)
|
||||
'parse-stream (copy-var parse-stream tns)
|
||||
'parse-stream-strict (copy-var parse-stream-strict tns)
|
||||
'parsed-seq (copy-var parsed-seq tns)
|
||||
;;'parsed-smile-seq (copy-var json/parsed-smile-seq tns)
|
||||
;;'decode-smile (copy-var json/decode-smile tns)
|
||||
'default-pretty-print-options (copy-var json/default-pretty-print-options tns)
|
||||
'create-pretty-printer (copy-var json/create-pretty-printer tns)})
|
||||
|
||||
(def cheshire-factory-namespace
|
||||
{'*json-factory* json-factory
|
||||
'default-factory-options (copy-var fact/default-factory-options fns)
|
||||
'json-factory (copy-var fact/json-factory fns)
|
||||
'make-json-factory (copy-var fact/make-json-factory fns)})
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@
|
|||
{:methods [{:name "aget"}
|
||||
{:name "aset"}
|
||||
{:name "aclone"}
|
||||
{:name "iter"}
|
||||
;; we expose this via the Compiler/LOADER dynamic var
|
||||
{:name "baseLoader"}]}
|
||||
clojure.lang.Compiler
|
||||
|
|
@ -223,7 +224,9 @@
|
|||
java.net.http.WebSocket$Listener
|
||||
java.security.cert.X509Certificate
|
||||
java.security.cert.CertificateFactory
|
||||
java.security.Signature
|
||||
javax.crypto.Cipher
|
||||
javax.crypto.KeyAgreement
|
||||
javax.crypto.Mac
|
||||
javax.crypto.SecretKey
|
||||
javax.crypto.SecretKeyFactory
|
||||
|
|
@ -252,6 +255,10 @@
|
|||
jdk.internal.net.http.websocket.BuilderImpl
|
||||
jdk.internal.net.http.websocket.WebSocketImpl])
|
||||
|
||||
(def thread-builder
|
||||
(try (Class/forName "java.lang.Thread$Builder")
|
||||
(catch Exception _ nil)))
|
||||
|
||||
(def classes
|
||||
`{:all [clojure.lang.ArityException
|
||||
clojure.lang.BigInt
|
||||
|
|
@ -337,6 +344,8 @@
|
|||
java.lang.Throwable
|
||||
java.lang.ThreadLocal
|
||||
java.lang.Thread$UncaughtExceptionHandler
|
||||
~@(when thread-builder
|
||||
'[java.lang.Thread$Builder])
|
||||
java.lang.UnsupportedOperationException
|
||||
java.lang.ref.WeakReference
|
||||
java.lang.ref.ReferenceQueue
|
||||
|
|
@ -405,21 +414,28 @@
|
|||
java.nio.file.attribute.BasicFileAttributes
|
||||
java.nio.file.attribute.FileAttribute
|
||||
java.nio.file.attribute.FileTime
|
||||
java.nio.file.attribute.PosixFileAttributes
|
||||
java.nio.file.attribute.PosixFilePermission
|
||||
java.nio.file.attribute.PosixFilePermissions])
|
||||
java.security.spec.PKCS8EncodedKeySpec
|
||||
java.security.MessageDigest
|
||||
java.nio.file.attribute.PosixFilePermissions
|
||||
java.nio.file.attribute.UserDefinedFileAttributeView])
|
||||
java.security.DigestInputStream
|
||||
java.security.Provider
|
||||
java.security.KeyFactory
|
||||
java.security.KeyPairGenerator
|
||||
java.security.KeyPair
|
||||
java.security.KeyStore
|
||||
java.security.MessageDigest
|
||||
java.security.Provider
|
||||
java.security.SecureRandom
|
||||
java.security.Security
|
||||
java.security.spec.ECGenParameterSpec
|
||||
java.security.spec.PKCS8EncodedKeySpec
|
||||
java.security.spec.X509EncodedKeySpec
|
||||
java.sql.Date
|
||||
java.text.ParseException
|
||||
java.text.ParsePosition
|
||||
;; adds about 200kb, same functionality provided by java.time:
|
||||
java.text.SimpleDateFormat
|
||||
java.text.BreakIterator
|
||||
~@(when features/java-time?
|
||||
`[java.time.format.DateTimeFormatter
|
||||
java.time.Clock
|
||||
|
|
@ -461,7 +477,12 @@
|
|||
java.time.temporal.TemporalAccessor
|
||||
java.time.temporal.TemporalAdjuster
|
||||
java.time.temporal.TemporalQuery
|
||||
~(symbol "[Ljava.time.temporal.TemporalQuery;")])
|
||||
~(symbol "[Ljava.time.temporal.TemporalQuery;")
|
||||
java.time.chrono.ChronoLocalDate
|
||||
java.time.temporal.TemporalUnit
|
||||
java.time.chrono.ChronoLocalDateTime
|
||||
java.time.chrono.ChronoZonedDateTime
|
||||
java.time.chrono.Chronology])
|
||||
java.util.concurrent.atomic.AtomicInteger
|
||||
java.util.concurrent.atomic.AtomicLong
|
||||
java.util.concurrent.atomic.AtomicReference
|
||||
|
|
@ -491,6 +512,10 @@
|
|||
java.util.concurrent.CompletableFuture
|
||||
java.util.concurrent.Executors
|
||||
java.util.concurrent.TimeUnit
|
||||
java.util.concurrent.CompletionStage
|
||||
java.util.concurrent.locks.ReentrantLock
|
||||
java.util.concurrent.ThreadLocalRandom
|
||||
java.util.concurrent.ConcurrentHashMap
|
||||
java.util.jar.Attributes
|
||||
java.util.jar.Attributes$Name
|
||||
java.util.jar.JarFile
|
||||
|
|
@ -505,6 +530,7 @@
|
|||
java.util.Random
|
||||
java.util.regex.Matcher
|
||||
java.util.regex.Pattern
|
||||
java.util.regex.PatternSyntaxException
|
||||
java.util.ArrayDeque
|
||||
java.util.ArrayList
|
||||
java.util.Collections
|
||||
|
|
@ -579,8 +605,7 @@
|
|||
org.jsoup.nodes.TextNode
|
||||
org.jsoup.nodes.XmlDeclaration
|
||||
org.jsoup.parser.Tag
|
||||
org.jsoup.parser.Parser
|
||||
org.jsoup.select.Elements]
|
||||
org.jsoup.parser.Parser]
|
||||
:constructors [clojure.lang.Delay
|
||||
clojure.lang.DynamicClassLoader
|
||||
clojure.lang.LineNumberingPushbackReader
|
||||
|
|
@ -630,7 +655,10 @@
|
|||
clojure.lang.Named
|
||||
clojure.lang.Keyword
|
||||
clojure.lang.PersistentArrayMap
|
||||
clojure.lang.PersistentArrayMap$TransientArrayMap
|
||||
clojure.lang.PersistentHashMap$TransientHashMap
|
||||
clojure.lang.PersistentHashSet
|
||||
clojure.lang.PersistentHashSet$TransientHashSet
|
||||
clojure.lang.PersistentList
|
||||
clojure.lang.PersistentList$EmptyList
|
||||
clojure.lang.PersistentQueue
|
||||
|
|
@ -638,6 +666,7 @@
|
|||
clojure.lang.PersistentTreeMap
|
||||
clojure.lang.PersistentTreeSet
|
||||
clojure.lang.PersistentVector
|
||||
clojure.lang.PersistentVector$TransientVector
|
||||
clojure.lang.Range
|
||||
clojure.lang.Ratio
|
||||
clojure.lang.ReaderConditional
|
||||
|
|
@ -656,10 +685,14 @@
|
|||
java.lang.LinkageError
|
||||
java.lang.ThreadDeath
|
||||
java.lang.VirtualMachineError
|
||||
java.lang.NoSuchFieldException
|
||||
java.sql.Timestamp
|
||||
java.util.concurrent.TimeoutException
|
||||
java.util.Collection
|
||||
java.util.Map$Entry
|
||||
java.util.AbstractMap
|
||||
java.util.AbstractSet
|
||||
java.util.AbstractList
|
||||
~@(when features/xml? ['clojure.data.xml.node.Element])]
|
||||
:custom ~custom-map})
|
||||
|
||||
|
|
@ -745,8 +778,12 @@
|
|||
java.net.URLClassLoader
|
||||
(instance? java.lang.ClassLoader v)
|
||||
java.lang.ClassLoader
|
||||
(instance? java.nio.file.attribute.PosixFileAttributes v)
|
||||
java.nio.file.attribute.PosixFileAttributes
|
||||
(instance? java.nio.file.attribute.BasicFileAttributes v)
|
||||
java.nio.file.attribute.BasicFileAttributes
|
||||
(instance? java.nio.file.attribute.UserDefinedFileAttributeView v)
|
||||
java.nio.file.attribute.UserDefinedFileAttributeView
|
||||
(instance? java.util.concurrent.Future v)
|
||||
java.util.concurrent.Future
|
||||
(instance? java.util.concurrent.ScheduledExecutorService v)
|
||||
|
|
@ -769,14 +806,29 @@
|
|||
java.security.cert.X509Certificate
|
||||
(instance? java.io.Console v)
|
||||
java.io.Console
|
||||
(instance? java.security.KeyPairGenerator v)
|
||||
java.security.KeyPairGenerator
|
||||
(instance? java.security.Signature v)
|
||||
java.security.Signature
|
||||
(instance? java.security.Key v)
|
||||
java.security.Key
|
||||
(instance? java.util.Set v)
|
||||
java.util.Set
|
||||
(instance? java.io.Closeable v)
|
||||
java.io.Closeable
|
||||
(instance? java.util.Collection v)
|
||||
java.util.Collection
|
||||
(instance? java.lang.Throwable v)
|
||||
java.lang.Throwable
|
||||
(instance? org.jsoup.nodes.Element v)
|
||||
org.jsoup.nodes.Element
|
||||
(and thread-builder
|
||||
(instance? thread-builder v))
|
||||
thread-builder
|
||||
(instance? java.text.BreakIterator v)
|
||||
java.text.BreakIterator
|
||||
;; keep commas for merge friendliness
|
||||
)]
|
||||
,)]
|
||||
;; (prn :res res)
|
||||
res)))
|
||||
m (assoc m (list 'quote 'clojure.lang.Var) 'sci.lang.Var)
|
||||
|
|
|
|||
|
|
@ -84,8 +84,8 @@
|
|||
cp)))
|
||||
|
||||
(defn resource
|
||||
(^URL [path] (resource @the-url-loader path))
|
||||
(^URL [loader path]
|
||||
(^URL [path] (resource path @the-url-loader))
|
||||
(^URL [path loader]
|
||||
(if (str/starts-with? path "/") nil ;; non-relative paths always return nil
|
||||
(getResource loader [path] true))))
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
(:refer-clojure :exclude [future read+string clojure-version with-precision
|
||||
send-via send send-off sync into-array])
|
||||
(:require [babashka.impl.common :as common]
|
||||
[borkdude.graal.locking :as locking]
|
||||
[clojure.core :as c]
|
||||
[clojure.string :as str]
|
||||
[sci.core :as sci]
|
||||
|
|
@ -12,9 +11,6 @@
|
|||
[sci.impl.utils :refer [clojure-core-ns]]
|
||||
[sci.impl.vars :as vars]))
|
||||
|
||||
(defn locking* [form bindings v f & args]
|
||||
(apply @#'locking/locking form bindings v f args))
|
||||
|
||||
(defn core-dynamic-var
|
||||
([sym] (core-dynamic-var sym nil))
|
||||
([sym init-val] (sci/new-dynamic-var sym init-val {:ns clojure-core-ns})))
|
||||
|
|
@ -148,7 +144,6 @@
|
|||
'file-seq (copy-core-var file-seq)
|
||||
'promise (copy-core-var promise)
|
||||
'deliver (copy-core-var deliver)
|
||||
'locking (macrofy 'locking locking*)
|
||||
'shutdown-agents (copy-core-var shutdown-agents)
|
||||
'slurp (copy-core-var slurp)
|
||||
'spit (copy-core-var spit)
|
||||
|
|
|
|||
|
|
@ -2,13 +2,39 @@
|
|||
{:no-doc true}
|
||||
(:require [clojure.core.async :as async]
|
||||
[clojure.core.async.impl.protocols :as protocols]
|
||||
[clojure.core.async.impl.dispatch :as dispatch]
|
||||
[sci.core :as sci :refer [copy-var]]
|
||||
[sci.impl.copy-vars :refer [macrofy]]
|
||||
[sci.impl.vars :as vars]))
|
||||
[sci.impl.vars :as vars])
|
||||
(:import [java.util.concurrent Executors ExecutorService ThreadFactory]))
|
||||
|
||||
(set! *warn-on-reflection* true)
|
||||
|
||||
(def ^java.util.concurrent.Executor executor @#'async/thread-macro-executor)
|
||||
#_(def ^java.util.concurrent.Executor executor @#'async/thread-macro-executor)
|
||||
(def executor-for
|
||||
"Given a workload tag, returns an ExecutorService instance and memoizes the result. By
|
||||
default, core.async will defer to a user factory (if provided via sys prop) or construct
|
||||
a specialized ExecutorService instance for each tag :io, :compute, and :mixed. When
|
||||
given the tag :core-async-dispatch it will default to the executor service for :io."
|
||||
(memoize
|
||||
(fn ^ExecutorService [workload]
|
||||
(let [sysprop-factory nil #_(when-let [esf (System/getProperty "clojure.core.async.executor-factory")]
|
||||
(requiring-resolve (symbol esf)))
|
||||
sp-exec (and sysprop-factory (sysprop-factory workload))]
|
||||
(or sp-exec
|
||||
(if (= workload :core-async-dispatch)
|
||||
(executor-for :io)
|
||||
(@#'dispatch/create-default-executor workload)))))))
|
||||
|
||||
(alter-var-root #'dispatch/executor-for (constantly executor-for))
|
||||
|
||||
#_#_(defn exec
|
||||
[^Runnable r workload]
|
||||
(prn :r r :w workload)
|
||||
(let [^ExecutorService e (executor-for workload)]
|
||||
(.execute e r)))
|
||||
|
||||
(alter-var-root #'dispatch/exec (constantly exec))
|
||||
|
||||
(def ^java.util.concurrent.Executor virtual-executor
|
||||
(try (eval '(java.util.concurrent.Executors/newVirtualThreadPerTaskExecutor))
|
||||
|
|
@ -17,20 +43,25 @@
|
|||
(defn thread-call
|
||||
"Executes f in another thread, returning immediately to the calling
|
||||
thread. Returns a channel which will receive the result of calling
|
||||
f when completed, then close."
|
||||
[f]
|
||||
(let [c (async/chan 1)]
|
||||
(let [binds (vars/get-thread-binding-frame)]
|
||||
(.execute executor
|
||||
(fn []
|
||||
(vars/reset-thread-binding-frame binds)
|
||||
(try
|
||||
(let [ret (f)]
|
||||
(when-not (nil? ret)
|
||||
(async/>!! c ret)))
|
||||
(finally
|
||||
(async/close! c))))))
|
||||
c))
|
||||
f when completed, then close. workload is a keyword that describes
|
||||
the work performed by f, where:
|
||||
|
||||
:io - may do blocking I/O but must not do extended computation
|
||||
:compute - must not ever block
|
||||
:mixed - anything else (default)
|
||||
|
||||
when workload not supplied, defaults to :mixed"
|
||||
([f] (thread-call f :mixed))
|
||||
([f workload]
|
||||
(let [c (async/chan 1)
|
||||
returning-to-chan (fn [bf]
|
||||
#(try
|
||||
(when-some [ret (bf)]
|
||||
(async/>!! c ret))
|
||||
(finally (async/close! c))))
|
||||
f (vars/binding-conveyor-fn f)]
|
||||
(-> f #_bound-fn* returning-to-chan (dispatch/exec workload))
|
||||
c)))
|
||||
|
||||
(defn -vthread-call
|
||||
"Executes f in another virtual thread, returning immediately to the calling
|
||||
|
|
@ -38,21 +69,23 @@
|
|||
f when completed, then close."
|
||||
[f]
|
||||
(let [c (async/chan 1)]
|
||||
(let [binds (vars/get-thread-binding-frame)]
|
||||
(let [returning-to-chan (fn [bf]
|
||||
#(try
|
||||
(when-some [ret (bf)]
|
||||
(async/>!! c ret))
|
||||
(finally (async/close! c))))
|
||||
f (vars/binding-conveyor-fn f)]
|
||||
(.execute virtual-executor
|
||||
(fn []
|
||||
(vars/reset-thread-binding-frame binds)
|
||||
(try
|
||||
(let [ret (f)]
|
||||
(when-not (nil? ret)
|
||||
(async/>!! c ret)))
|
||||
(finally
|
||||
(async/close! c))))))
|
||||
(-> f returning-to-chan)))
|
||||
c))
|
||||
|
||||
(defn thread
|
||||
[_ _ & body]
|
||||
`(~'clojure.core.async/thread-call (fn [] ~@body)))
|
||||
`(~'clojure.core.async/thread-call (fn [] ~@body) :mixed))
|
||||
|
||||
(defn io-thread
|
||||
[_ _ & body]
|
||||
`(~'clojure.core.async/thread-call (fn [] ~@body) :io))
|
||||
|
||||
(defn -vthread
|
||||
[_ _ & body]
|
||||
|
|
@ -128,6 +161,7 @@
|
|||
'take! (copy-var async/take! core-async-namespace)
|
||||
'tap (copy-var async/tap core-async-namespace)
|
||||
'thread (macrofy 'thread thread core-async-namespace)
|
||||
'io-thread (macrofy 'io-thread io-thread core-async-namespace)
|
||||
'thread-call (copy-var thread-call core-async-namespace)
|
||||
'-vthread-call (copy-var -vthread-call core-async-namespace)
|
||||
'timeout (copy-var timeout core-async-namespace)
|
||||
|
|
|
|||
|
|
@ -118,8 +118,9 @@ by default when a new command-line REPL is started."} repl-requires
|
|||
:file "<repl>"
|
||||
:type :sci/error) e)))))))
|
||||
(catch Throwable e
|
||||
(caught e)
|
||||
(set! *e e))))]
|
||||
(let [e' (ex-cause e)]
|
||||
(caught e)
|
||||
(set! *e e')))))]
|
||||
(with-bindings
|
||||
(try
|
||||
(init)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
{:no-doc true}
|
||||
(:require [clojure.pprint :as pprint]
|
||||
[sci.core :as sci]
|
||||
[sci.pprint]))
|
||||
[sci.pprint]
|
||||
[babashka.impl.clojure.core.async]))
|
||||
|
||||
(defonce patched? (volatile! false))
|
||||
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@
|
|||
edn/read-string)
|
||||
deps (:deps deps)
|
||||
deps (assoc deps
|
||||
'babashka/fs {:mvn/version "0.5.22"}
|
||||
'babashka/fs {:mvn/version "0.5.25"}
|
||||
'babashka/babashka.curl {:mvn/version "0.1.2"}
|
||||
'babashka/babashka.core {:git/url "https://github.com/babashka/babashka.core"
|
||||
:git/sha "52a6037bd4b632bffffb04394fb4efd0cdab6b1e"}
|
||||
'babashka/process {:mvn/version "0.5.22"})
|
||||
'babashka/process {:mvn/version "0.6.23"})
|
||||
deps (dissoc deps
|
||||
'borkdude/sci
|
||||
'org.babashka/sci
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
"Inspired by skip-if-eol from clojure.main."
|
||||
[s]
|
||||
(let [c (r/read-char s)]
|
||||
(when-not (= c \newline)
|
||||
(when-not (= \newline c )
|
||||
(r/unread s c))))
|
||||
|
||||
(defn repl-read [sci-ctx in-stream _request-prompt request-exit]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
[babashka.deps :as bdeps]
|
||||
[babashka.fs :as fs]
|
||||
[babashka.impl.bencode :refer [bencode-namespace]]
|
||||
[babashka.impl.cheshire :refer [cheshire-core-namespace]]
|
||||
[babashka.impl.cheshire :refer [cheshire-core-namespace cheshire-factory-namespace]]
|
||||
[babashka.impl.classes :as classes :refer [classes-namespace]]
|
||||
[babashka.impl.classpath :as cp :refer [classpath-namespace]]
|
||||
[babashka.impl.cli :as cli]
|
||||
|
|
@ -379,6 +379,7 @@ Use bb run --help to show this help output.
|
|||
'babashka.signal signal-ns
|
||||
'clojure.java.io io-namespace
|
||||
'cheshire.core cheshire-core-namespace
|
||||
'cheshire.factory cheshire-factory-namespace
|
||||
'clojure.data data/data-namespace
|
||||
'clojure.instant instant/instant-namespace
|
||||
'clojure.stacktrace stacktrace-namespace
|
||||
|
|
@ -1189,7 +1190,7 @@ Use bb run --help to show this help output.
|
|||
(println "[babashka] WARNING: config file does not exist:" config))
|
||||
nil))
|
||||
jar (let [jar (resolve-symbolic-link jar)]
|
||||
(some-> [jar] cp/new-loader (cp/resource "META-INF/bb.edn") .toString))
|
||||
(some->> [jar] cp/new-loader (cp/resource "META-INF/bb.edn") .toString))
|
||||
:else (if (and file (fs/exists? file))
|
||||
;; file relative to bb.edn
|
||||
(let [file (abs-path file) ;; follow symlink
|
||||
|
|
|
|||
1
test-resources/extended-attributes.txt
Normal file
1
test-resources/extended-attributes.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
42
|
||||
|
|
@ -193,11 +193,28 @@
|
|||
:test-namespaces [plumbing.core-test],
|
||||
:test-paths ["test"]}
|
||||
org.clj-commons/hickory {:git-url "https://github.com/clj-commons/hickory"
|
||||
:git-sha "27ee318928b6748075fa9954740afedf916ff795"
|
||||
:git-sha "9385b6708ef35f161732d8464b3a3aa57dd79f30"
|
||||
:test-paths ["test/cljc"]
|
||||
:test-namespaces [hickory.test.core
|
||||
hickory.test.convert
|
||||
hickory.test.hiccup-utils
|
||||
hickory.test.render
|
||||
hickory.test.select
|
||||
hickory.test.zip]}}
|
||||
hickory.test.zip]}
|
||||
cheshire/cheshire {:git-url "https://github.com/dakrone/cheshire", :test-namespaces [cheshire.test.core], :manually-added true}
|
||||
com.potetm/fusebox {:git-url "https://github.com/potetm/fusebox"
|
||||
:git-sha "ac6d6a0a69510b009b3c1bb2247cd110fd9f7246"
|
||||
:test-paths ["test"]
|
||||
:test-namespaces [#_com.potetm.fusebox.bulkhead-test
|
||||
com.potetm.fusebox.bulwark-test
|
||||
com.potetm.fusebox.circuit-breaker-test
|
||||
com.potetm.fusebox.fallback-test
|
||||
com.potetm.fusebox.memoize-test
|
||||
#_com.potetm.fusebox.rate-limit-test
|
||||
com.potetm.fusebox.registry-test
|
||||
com.potetm.fusebox.retry-test
|
||||
#_com.potetm.fusebox.timeout-test]}
|
||||
net.sekao/odoyle-rules {:git-url "https://github.com/oakes/odoyle-rules"
|
||||
:git-sha "0b1d825ec45a998c4d3481dfb292e08ce6a47f0b"
|
||||
:test-paths ["test"]
|
||||
:test-namespaces [odoyle.rules-test]}}
|
||||
|
|
|
|||
793
test-resources/lib_tests/cheshire/test/core.clj
Normal file
793
test-resources/lib_tests/cheshire/test/core.clj
Normal file
|
|
@ -0,0 +1,793 @@
|
|||
(ns cheshire.test.core
|
||||
(:require [clojure.test :refer [deftest testing is are]]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.string :as str]
|
||||
[cheshire.core :as json]
|
||||
;; BB-TEST-PATCH: bb does not include cheshire.exact
|
||||
#_[cheshire.exact :as json-exact]
|
||||
;; BB-TEST-PATCH: bb does not include cheshire.gen
|
||||
#_[cheshire.generate :as gen]
|
||||
[cheshire.factory :as fact]
|
||||
;; BB-TEST-PATCH: bb does not include cheshire.parse
|
||||
#_[cheshire.parse :as parse])
|
||||
(:import ;; BB-TEST-PATCH: tests adjusted to check for general Exception instead of specific jackson exceptions
|
||||
#_(com.fasterxml.jackson.core JsonGenerationException
|
||||
JsonParseException)
|
||||
#_(com.fasterxml.jackson.core.exc StreamConstraintsException)
|
||||
(java.io StringReader StringWriter
|
||||
BufferedReader BufferedWriter
|
||||
IOException)
|
||||
;; BB-TEST-PATCH: bb does not support creating java.sql.Timestamps
|
||||
#_(java.sql Timestamp)
|
||||
(java.util Date UUID)))
|
||||
|
||||
(defn- str-of-len
|
||||
([len]
|
||||
(str-of-len len "x"))
|
||||
([len val]
|
||||
(apply str (repeat len val))))
|
||||
|
||||
(defn- nested-map [depth]
|
||||
(reduce (fn [acc n] {(str n) acc})
|
||||
{"0" "foo"}
|
||||
(range 1 depth)))
|
||||
|
||||
(defn- encode-stream->str [obj opts]
|
||||
(let [sw (StringWriter.)
|
||||
bw (BufferedWriter. sw)]
|
||||
(json/generate-stream obj bw opts)
|
||||
(.toString sw)))
|
||||
|
||||
(def test-obj {"int" 3 "long" (long -2147483647) "boolean" true
|
||||
"LongObj" (Long/parseLong "2147483647") "double" 1.23
|
||||
"nil" nil "string" "string" "vec" [1 2 3] "map" {"a" "b"}
|
||||
"list" (list "a" "b") "short" (short 21) "byte" (byte 3)})
|
||||
|
||||
(deftest t-ratio
|
||||
(let [n 1/2]
|
||||
(is (= (double n) (:num (json/decode (json/encode {:num n}) true))))))
|
||||
|
||||
(deftest t-long-wrap-around
|
||||
(is (= 2147483648 (json/decode (json/encode 2147483648)))))
|
||||
|
||||
(deftest t-bigint
|
||||
(let [n 9223372036854775808]
|
||||
(is (= n (:num (json/decode (json/encode {:num n}) true))))))
|
||||
|
||||
(deftest t-biginteger
|
||||
(let [n (BigInteger. "42")]
|
||||
(is (= n (:num (json/decode (json/encode {:num n}) true))))))
|
||||
|
||||
(deftest t-bigdecimal
|
||||
(let [n (BigDecimal. "42.5")]
|
||||
(is (= (.doubleValue n) (:num (json/decode (json/encode {:num n}) true))))
|
||||
;; BB-TEST-PATCH:
|
||||
#_(binding [parse/*use-bigdecimals?* true]
|
||||
(is (= n (:num (json/decode (json/encode {:num n}) true)))))))
|
||||
|
||||
(deftest test-string-round-trip
|
||||
(is (= test-obj (json/decode (json/encode test-obj)))))
|
||||
|
||||
(deftest test-generate-accepts-float
|
||||
(is (= "3.14" (json/encode 3.14))))
|
||||
|
||||
(deftest test-keyword-encode
|
||||
(is (= {"key" "val"}
|
||||
(json/decode (json/encode {:key "val"})))))
|
||||
|
||||
(deftest test-generate-set
|
||||
(is (= {"set" ["a" "b"]}
|
||||
(json/decode (json/encode {"set" #{"a" "b"}})))))
|
||||
|
||||
(deftest test-generate-empty-set
|
||||
(is (= {"set" []}
|
||||
(json/decode (json/encode {"set" #{}})))))
|
||||
|
||||
(deftest test-generate-empty-array
|
||||
(is (= {"array" []}
|
||||
(json/decode (json/encode {"array" []})))))
|
||||
|
||||
(deftest test-key-coercion
|
||||
(is (= {"foo" "bar" "1" "bat" "2" "bang" "3" "biz"}
|
||||
(json/decode
|
||||
(json/encode
|
||||
{:foo "bar" 1 "bat" (long 2) "bang" (bigint 3) "biz"})))))
|
||||
|
||||
(deftest test-keywords
|
||||
(is (= {:foo "bar" :bat 1}
|
||||
(json/decode (json/encode {:foo "bar" :bat 1}) true))))
|
||||
|
||||
(deftest test-symbols
|
||||
(is (= {"foo" "clojure.core/map"}
|
||||
(json/decode (json/encode {"foo" 'clojure.core/map})))))
|
||||
|
||||
(deftest test-accepts-java-map
|
||||
(is (= {"foo" 1}
|
||||
(json/decode
|
||||
(json/encode (doto (java.util.HashMap.) (.put "foo" 1)))))))
|
||||
|
||||
(deftest test-accepts-java-list
|
||||
(is (= [1 2 3]
|
||||
(json/decode (json/encode (doto (java.util.ArrayList. 3)
|
||||
(.add 1)
|
||||
(.add 2)
|
||||
(.add 3)))))))
|
||||
|
||||
(deftest test-accepts-java-set
|
||||
(is (= {"set" [1 2 3]}
|
||||
(json/decode (json/encode {"set" (doto (java.util.HashSet. 3)
|
||||
(.add 1)
|
||||
(.add 2)
|
||||
(.add 3))})))))
|
||||
|
||||
(deftest test-accepts-empty-java-set
|
||||
(is (= {"set" []}
|
||||
(json/decode (json/encode {"set" (java.util.HashSet. 3)})))))
|
||||
|
||||
(deftest test-nil
|
||||
(is (nil? (json/decode nil true))))
|
||||
|
||||
(deftest test-parsed-seq
|
||||
(let [br (BufferedReader. (StringReader. "1\n2\n3\n"))]
|
||||
(is (= (list 1 2 3) (json/parsed-seq br)))))
|
||||
|
||||
;; BB-TEST-PATCH: bb does not support smile
|
||||
#_(deftest test-smile-round-trip
|
||||
(is (= test-obj (json/parse-smile (json/generate-smile test-obj)))))
|
||||
|
||||
(def bin-obj {"byte-array" (byte-array (map byte [1 2 3]))})
|
||||
|
||||
;; BB-TEST-PATCH: bb does not support smile/cbor
|
||||
#_(deftest test-round-trip-binary
|
||||
(doseq [[p g] {json/parse-string json/generate-string
|
||||
json/parse-smile json/generate-smile
|
||||
json/parse-cbor json/generate-cbor}]
|
||||
(is (let [roundtripped (p (g bin-obj))]
|
||||
;; test value equality
|
||||
(is (= (->> bin-obj (get "byte-array") seq)
|
||||
(->> roundtripped (get "byte-array") seq)))))))
|
||||
|
||||
;; BB-TEST-PATCH: bb does not support smile
|
||||
#_(deftest test-smile-factory
|
||||
(binding [fact/*smile-factory* (fact/make-smile-factory {})]
|
||||
(is (= {"a" 1} (-> {:a 1}
|
||||
json/generate-smile
|
||||
json/parse-smile)))))
|
||||
|
||||
;; BB-TEST-PATCH: bb does not support smile/cbor
|
||||
#_(deftest test-smile-duplicate-detection
|
||||
(let [smile-data (byte-array [0x3a 0x29 0x0a 0x01 ;; smile header
|
||||
0xFa ;; object start
|
||||
0x80 0x61 ;; key a
|
||||
0xC2 ;; value 1
|
||||
0x80 0x61 ;; key a (again)
|
||||
0xC4 ;; value 2
|
||||
0xFB ;; object end
|
||||
])]
|
||||
(binding [fact/*smile-factory* (fact/make-smile-factory {:strict-duplicate-detection false})]
|
||||
(is (= {"a" 2} (json/parse-smile smile-data))))
|
||||
(binding [fact/*smile-factory* (fact/make-smile-factory {:strict-duplicate-detection true})]
|
||||
(is (thrown? JsonParseException (json/parse-smile smile-data))))))
|
||||
|
||||
;; BB-TEST-PATCH: bb does not support cbor
|
||||
#_(deftest test-cbor-factory
|
||||
(binding [fact/*cbor-factory* (fact/make-cbor-factory {})]
|
||||
(is (= {"a" 1} (-> {:a 1}
|
||||
json/generate-cbor
|
||||
json/parse-cbor)))))
|
||||
|
||||
;; BB-TEST-PATCH: bb does not support cbor
|
||||
#_(deftest test-cbor-duplicate-detection
|
||||
(let [cbor-data (byte-array [0xbf ;; object begin
|
||||
0x61 0x61 ;; key a
|
||||
0x01 ;; value 1
|
||||
0x61 0x61 ;; key a (again)
|
||||
0x02 ;; value 2
|
||||
0xff ;; object end
|
||||
])]
|
||||
(binding [fact/*cbor-factory* (fact/make-cbor-factory {:strict-duplicate-detection false})]
|
||||
(is (= {"a" 2} (json/parse-cbor cbor-data))))
|
||||
(binding [fact/*cbor-factory* (fact/make-cbor-factory {:strict-duplicate-detection true})]
|
||||
(is (thrown? JsonParseException (json/parse-cbor cbor-data))))))
|
||||
|
||||
(deftest test-aliases
|
||||
(is (= {"foo" "bar" "1" "bat" "2" "bang" "3" "biz"}
|
||||
(json/decode
|
||||
(json/encode
|
||||
{:foo "bar" 1 "bat" (long 2) "bang" (bigint 3) "biz"})))))
|
||||
|
||||
(deftest test-date
|
||||
(is (= {"foo" "1970-01-01T00:00:00Z"}
|
||||
(json/decode (json/encode {:foo (Date. (long 0))}))))
|
||||
(is (= {"foo" "1970-01-01"}
|
||||
(json/decode (json/encode {:foo (Date. (long 0))}
|
||||
{:date-format "yyyy-MM-dd"})))
|
||||
"encode with given date format"))
|
||||
|
||||
;; BB-TEST-PATCH: bb does not support creating java.sql.Timestamps
|
||||
#_(deftest test-sql-timestamp
|
||||
(is (= {"foo" "1970-01-01T00:00:00Z"}
|
||||
(json/decode (json/encode {:foo (Timestamp. (long 0))}))))
|
||||
(is (= {"foo" "1970-01-01"}
|
||||
(json/decode (json/encode {:foo (Timestamp. (long 0))}
|
||||
{:date-format "yyyy-MM-dd"})))
|
||||
"encode with given date format"))
|
||||
|
||||
(deftest test-uuid
|
||||
(let [id (UUID/randomUUID)
|
||||
id-str (str id)]
|
||||
(is (= {"foo" id-str} (json/decode (json/encode {:foo id}))))))
|
||||
|
||||
(deftest test-char-literal
|
||||
(is (= "{\"foo\":\"a\"}" (json/encode {:foo \a}))))
|
||||
|
||||
(deftest test-streams
|
||||
(testing "parse-stream"
|
||||
(are [parsed parse parsee] (= parsed
|
||||
(parse (BufferedReader. (StringReader. parsee))))
|
||||
{"foo" "bar"} json/parse-stream "{\"foo\":\"bar\"}\n"
|
||||
{"foo" "bar"} json/parse-stream-strict "{\"foo\":\"bar\"}\n")
|
||||
|
||||
(are [parsed parse parsee] (= parsed
|
||||
(with-open [rdr (StringReader. parsee)]
|
||||
(parse rdr true)))
|
||||
{(keyword "foo baz") "bar"} json/parse-stream "{\"foo baz\":\"bar\"}\n"
|
||||
{(keyword "foo baz") "bar"} json/parse-stream-strict "{\"foo baz\":\"bar\"}\n"))
|
||||
|
||||
(testing "generate-stream"
|
||||
(let [sw (StringWriter.)
|
||||
bw (BufferedWriter. sw)]
|
||||
(json/generate-stream {"foo" "bar"} bw)
|
||||
(is (= "{\"foo\":\"bar\"}" (.toString sw))))))
|
||||
|
||||
;; BB-TEST-PATCH: bb does not include with-writer
|
||||
#_(deftest serial-writing
|
||||
(is (= "[\"foo\",\"bar\"]"
|
||||
(.toString
|
||||
(json/with-writer [(StringWriter.) nil]
|
||||
(json/write [] :start)
|
||||
(json/write "foo")
|
||||
(json/write "bar")
|
||||
(json/write [] :end)))))
|
||||
(is (= "[1,[2,3],4]"
|
||||
(.toString
|
||||
(json/with-writer [(StringWriter.) nil]
|
||||
(json/write [1 [2]] :start-inner)
|
||||
(json/write 3)
|
||||
(json/write [] :end)
|
||||
(json/write 4)
|
||||
(json/write [] :end)))))
|
||||
(is (= "{\"a\":1,\"b\":2,\"c\":3}"
|
||||
(.toString
|
||||
(json/with-writer [(StringWriter.) nil]
|
||||
(json/write {:a 1} :start)
|
||||
(json/write {:b 2} :bare)
|
||||
(json/write {:c 3} :end)))))
|
||||
(is (= (str "[\"start\",\"continue\",[\"implicitly-nested\"],"
|
||||
"[\"explicitly-nested\"],\"flatten\",\"end\"]")
|
||||
(.toString
|
||||
(json/with-writer [(StringWriter.) nil]
|
||||
(json/write ["start"] :start)
|
||||
(json/write "continue")
|
||||
(json/write ["implicitly-nested"])
|
||||
(json/write ["explicitly-nested"] :all)
|
||||
(json/write ["flatten"] :bare)
|
||||
(json/write ["end"] :end)))))
|
||||
(is (= "{\"head\":\"head info\",\"data\":[1,2,3],\"tail\":\"tail info\"}"
|
||||
(.toString
|
||||
(json/with-writer [(StringWriter.) nil]
|
||||
(json/write {:head "head info" :data []} :start-inner)
|
||||
(json/write 1)
|
||||
(json/write 2)
|
||||
(json/write 3)
|
||||
(json/write [] :end)
|
||||
(json/write {:tail "tail info"} :end))))))
|
||||
|
||||
;; BB-TEST-PATCH: modified so that json files could be found
|
||||
(deftest test-multiple-objs-in-file
|
||||
(is (= {"one" 1, "foo" "bar"}
|
||||
(first (json/parsed-seq (io/reader (io/resource "cheshire/test/multi.json"))))))
|
||||
(is (= {"two" 2, "foo" "bar"}
|
||||
(second (json/parsed-seq (io/reader (io/resource "cheshire/test/multi.json"))))))
|
||||
(with-open [r (io/reader (io/resource "cheshire/test/multi.json"))]
|
||||
(is (= [{"one" 1, "foo" "bar"} {"two" 2, "foo" "bar"}]
|
||||
(json/parsed-seq r)))))
|
||||
|
||||
(deftest test-jsondotorg-pass1
|
||||
(let [;; BB-TEST-PATCH: modified so that json files could be found
|
||||
string (slurp (io/resource "cheshire/test/pass1.json"))
|
||||
decoded-json (json/decode string)
|
||||
encoded-json (json/encode decoded-json)
|
||||
re-decoded-json (json/decode encoded-json)]
|
||||
(is (= decoded-json re-decoded-json))))
|
||||
|
||||
(deftest test-namespaced-keywords
|
||||
(is (= "{\"foo\":\"user/bar\"}"
|
||||
(json/encode {:foo :user/bar})))
|
||||
(is (= {:foo/bar "baz/eggplant"}
|
||||
(json/decode (json/encode {:foo/bar :baz/eggplant}) true))))
|
||||
|
||||
(deftest test-array-coerce-fn
|
||||
(is (= {"set" #{"a" "b"} "array" ["a" "b"] "map" {"a" 1}}
|
||||
(json/decode
|
||||
(json/encode {"set" #{"a" "b"} "array" ["a" "b"] "map" {"a" 1}}) false
|
||||
(fn [field-name] (if (= "set" field-name) #{} []))))))
|
||||
|
||||
(deftest t-symbol-encoding-for-non-resolvable-symbols
|
||||
(is (= "{\"bar\":\"clojure.core/pam\",\"foo\":\"clojure.core/map\"}"
|
||||
(json/encode (sorted-map :foo 'clojure.core/map :bar 'clojure.core/pam))))
|
||||
(is (= "{\"bar\":\"clojure.core/pam\",\"foo\":\"foo.bar/baz\"}"
|
||||
(json/encode (sorted-map :foo 'foo.bar/baz :bar 'clojure.core/pam)))))
|
||||
|
||||
(deftest t-bindable-factories-auto-close-source
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:auto-close-source false})]
|
||||
(let [br (BufferedReader. (StringReader. "123"))]
|
||||
(is (= 123 (json/parse-stream br)))
|
||||
(is (= -1 (.read br)))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:auto-close-source true})]
|
||||
(let [br (BufferedReader. (StringReader. "123"))]
|
||||
(is (= 123 (json/parse-stream br)))
|
||||
(is (thrown? IOException (.read br))))))
|
||||
|
||||
(deftest t-bindable-factories-allow-comments
|
||||
(let [s "{\"a\": /* comment */ 1, // comment\n \"b\": 2}"]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-comments true})]
|
||||
(is (= {"a" 1 "b" 2} (json/decode s))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-comments false})]
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
(is (thrown? #_JsonParseException Exception (json/decode s))))))
|
||||
|
||||
(deftest t-bindable-factories-allow-unquoted-field-names
|
||||
(let [s "{a: 1, b: 2}"]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-unquoted-field-names true})]
|
||||
(is (= {"a" 1 "b" 2} (json/decode s))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-unquoted-field-names false})]
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
(is (thrown? #_JsonParseException Exception (json/decode s))))))
|
||||
|
||||
(deftest t-bindable-factories-allow-single-quotes
|
||||
(doseq [s ["{'a': \"one\", 'b': \"two\"}"
|
||||
"{\"a\": 'one', \"b\": 'two'}"
|
||||
"{'a': 'one', 'b': 'two'}"]]
|
||||
(testing s
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-single-quotes true})]
|
||||
(is (= {"a" "one" "b" "two"} (json/decode s))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-single-quotes false})]
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
(is (thrown? #_JsonParseException Exception (json/decode s)))))))
|
||||
|
||||
(deftest t-bindable-factories-allow-unquoted-control-chars
|
||||
(let [s "{\"a\": \"one\ntwo\"}"]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-unquoted-control-chars true})]
|
||||
(is (= {"a" "one\ntwo"} (json/decode s))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-unquoted-control-chars false})]
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
(is (thrown? #_JsonParseException Exception (json/decode s))))))
|
||||
|
||||
(deftest t-bindable-factories-allow-backslash-escaping-any-char
|
||||
(let [s "{\"a\": 00000000001}"]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-numeric-leading-zeros true})]
|
||||
(is (= {"a" 1} (json/decode s))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-numeric-leading-zeros false})]
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
(is (thrown? #_JsonParseException Exception (json/decode s))))))
|
||||
|
||||
(deftest t-bindable-factories-allow-numeric-leading-zeros
|
||||
(let [s "{\"a\": \"\\o\\n\\e\"}"]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-backslash-escaping true})]
|
||||
(is (= {"a" "o\ne"} (json/decode s))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-backslash-escaping false})]
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
(is (thrown? #_JsonParseException Exception (json/decode s))))))
|
||||
|
||||
(deftest t-bindable-factories-non-numeric-numbers
|
||||
(let [s "{\"foo\":NaN}"]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-non-numeric-numbers true})]
|
||||
(is (= (type Double/NaN)
|
||||
(type (:foo (json/decode s true))))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:allow-non-numeric-numbers false})]
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
(is (thrown? #_JsonParseException Exception (json/decode s true))))))
|
||||
|
||||
(deftest t-bindable-factories-optimization-opts
|
||||
(let [s "{\"a\": \"foo\"}"]
|
||||
(doseq [opts [{:intern-field-names true}
|
||||
{:intern-field-names false}
|
||||
{:canonicalize-field-names true}
|
||||
{:canonicalize-field-names false}]]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory opts)]
|
||||
(is (= {"a" "foo"} (json/decode s)))))))
|
||||
|
||||
(deftest t-bindable-factories-escape-non-ascii
|
||||
;; includes testing legacy fn opt of same name can override factory
|
||||
(let [edn {:foo "It costs £100"}
|
||||
expected-esc "{\"foo\":\"It costs \\u00A3100\"}"
|
||||
expected-no-esc "{\"foo\":\"It costs £100\"}"
|
||||
opt-esc {:escape-non-ascii true}
|
||||
opt-no-esc {:escape-non-ascii false}]
|
||||
(testing "default factory"
|
||||
(doseq [[fn-opts expected]
|
||||
[[{} expected-no-esc]
|
||||
[opt-esc expected-esc]
|
||||
[opt-no-esc expected-no-esc]]]
|
||||
(testing fn-opts
|
||||
(is (= expected (json/encode edn fn-opts) (encode-stream->str edn fn-opts))))))
|
||||
(testing (str "factory: " opt-esc)
|
||||
(binding [fact/*json-factory* (fact/make-json-factory opt-esc)]
|
||||
(doseq [[fn-opts expected]
|
||||
[[{} expected-esc]
|
||||
[opt-esc expected-esc]
|
||||
[opt-no-esc expected-no-esc]]]
|
||||
(testing (str "fn: " fn-opts)
|
||||
(is (= expected (json/encode edn fn-opts) (encode-stream->str edn fn-opts)))))))
|
||||
(testing (str "factory: " opt-no-esc)
|
||||
(binding [fact/*json-factory* (fact/make-json-factory opt-no-esc)]
|
||||
(doseq [[fn-opts expected]
|
||||
[[{} expected-no-esc]
|
||||
[opt-esc expected-esc]
|
||||
[opt-no-esc expected-no-esc]]]
|
||||
(testing (str "fn: " fn-opts)
|
||||
(is (= expected (json/encode edn fn-opts) (encode-stream->str edn fn-opts)))))))))
|
||||
|
||||
(deftest t-bindable-factories-quoteless
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:quote-field-names true})]
|
||||
(is (= "{\"a\":\"foo\"}" (json/encode {:a "foo"}))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:quote-field-names false})]
|
||||
(is (= "{a:\"foo\"}" (json/encode {:a "foo"})))))
|
||||
|
||||
(deftest t-bindable-factories-strict-duplicate-detection
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:strict-duplicate-detection true})]
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
(is (thrown? #_ JsonParseException Exception
|
||||
(json/decode "{\"a\": 1, \"b\": 2, \"a\": 3}"))))
|
||||
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:strict-duplicate-detection false})]
|
||||
(is (= {"a" 3 "b" 2}
|
||||
(json/decode "{\"a\": 1, \"b\": 2, \"a\": 3}")))))
|
||||
|
||||
(deftest t-bindable-factories-max-input-document-length
|
||||
(let [edn {"a" (apply str (repeat 10000 "x"))}
|
||||
sample-data (json/encode edn)]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-input-document-length (count sample-data)})]
|
||||
(is (= edn (json/decode sample-data))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
;; as per Jackson docs, limit is inexact, so dividing input length by 2 should do the trick
|
||||
{:max-input-document-length (/ (count sample-data) 2)})]
|
||||
(is (thrown-with-msg?
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
#_StreamConstraintsException Exception #"(?i)document length .* exceeds"
|
||||
(json/decode sample-data))))))
|
||||
|
||||
(deftest t-bindable-factories-max-input-token-count
|
||||
;; A token is a single unit of input, such as a number, a string, an object start or end, or an array start or end.
|
||||
(let [edn {"1" 2 "3" 4}
|
||||
sample-data (json/encode edn)]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-input-token-count 6})]
|
||||
(is (= edn (json/decode sample-data))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-input-token-count 5})]
|
||||
(is (thrown-with-msg?
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
#_StreamConstraintsException Exception #"(?i)token count .* exceeds"
|
||||
(json/decode sample-data))))))
|
||||
|
||||
(deftest t-bindable-factories-max-input-name-length
|
||||
(let [k "somekey"
|
||||
edn {k 1}
|
||||
sample-data (json/encode edn)]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-input-name-length (count k)})]
|
||||
(is (= edn (json/decode sample-data))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-input-name-length (dec (count k))})]
|
||||
(is (thrown-with-msg?
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
#_StreamConstraintsException Exception #"(?i)name .* exceeds"
|
||||
(json/decode sample-data)))))
|
||||
(let [default-limit (:max-input-name-length fact/default-factory-options)]
|
||||
(let [k (str-of-len default-limit)
|
||||
edn {k 1}
|
||||
sample-data (json/encode edn)]
|
||||
(is (= edn (json/decode sample-data))))
|
||||
(let [k (str-of-len (inc default-limit))
|
||||
sample-data (json/encode {k 1})]
|
||||
(is (thrown-with-msg?
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
#_StreamConstraintsException Exception #"(?i)name .* exceeds"
|
||||
(json/decode sample-data))))))
|
||||
|
||||
(deftest t-bindable-factories-input-nesting-depth
|
||||
(let [edn (nested-map 100)
|
||||
sample-data (json/encode edn)]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-input-nesting-depth 100})]
|
||||
(is (= edn (json/decode sample-data))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-input-nesting-depth 99})]
|
||||
(is (thrown-with-msg?
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
#_StreamConstraintsException Exception #"(?i)nesting depth .* exceeds"
|
||||
(json/decode sample-data))))))
|
||||
|
||||
(deftest t-bindable-factories-max-input-number-length
|
||||
(let [num 123456789
|
||||
edn {"foo" num}
|
||||
sample-data (json/encode edn)]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-input-number-length (-> num str count)})]
|
||||
(is (= edn (json/decode sample-data))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-input-number-length (-> num str count dec)})]
|
||||
(is (thrown-with-msg?
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
#_StreamConstraintsException Exception #"(?i)number value length .* exceeds"
|
||||
(json/decode sample-data)))))
|
||||
(let [default-limit (:max-input-number-length fact/default-factory-options)]
|
||||
(let [num (bigint (str-of-len default-limit 2))
|
||||
edn {"foo" num}
|
||||
sample-data (json/encode edn)]
|
||||
(is (= edn (json/decode sample-data))))
|
||||
(let [num (bigint (str-of-len (inc default-limit) 2))
|
||||
sample-data (json/encode {"foo" num})]
|
||||
(is (thrown-with-msg?
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
#_StreamConstraintsException Exception #"(?i)number value length .* exceeds"
|
||||
(json/decode sample-data))))))
|
||||
|
||||
(deftest t-bindable-factories-max-input-string-length
|
||||
(let [big-string (str-of-len 40000000)
|
||||
edn {"big-string" big-string}
|
||||
sample-data (json/encode edn)]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-input-string-length (count big-string)})]
|
||||
(is (= edn (json/decode sample-data))))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-input-string-length (dec (count big-string))})]
|
||||
(is (thrown-with-msg?
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
#_StreamConstraintsException Exception #"(?i)string value length .* exceeds"
|
||||
(json/decode sample-data)))))
|
||||
(let [default-limit (:max-input-string-length fact/default-factory-options)]
|
||||
(let [big-string (str-of-len default-limit)
|
||||
edn {"big-string" big-string}
|
||||
sample-data (json/encode edn)]
|
||||
(is (= edn (json/decode sample-data))))
|
||||
(let [big-string (str-of-len (inc default-limit))
|
||||
sample-data (json/encode {"big-string" big-string})]
|
||||
(is (thrown-with-msg?
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
#_StreamConstraintsException Exception #"(?i)string value length .* exceeds"
|
||||
(json/decode sample-data))))))
|
||||
|
||||
(deftest t-bindable-factories-max-output-nesting-depth
|
||||
(let [edn (nested-map 100)]
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-output-nesting-depth 100})]
|
||||
(is (.contains (json/encode edn) "\"99\"")))
|
||||
(binding [fact/*json-factory* (fact/make-json-factory
|
||||
{:max-output-nesting-depth 99})]
|
||||
(is (thrown-with-msg?
|
||||
;; BB-TEST-PATCH: Generalized exception check
|
||||
#_StreamConstraintsException Exception #"(?i)nesting depth .* exceeds"
|
||||
(json/encode edn))))))
|
||||
|
||||
(deftest t-persistent-queue
|
||||
(let [q (conj clojure.lang.PersistentQueue/EMPTY 1 2 3)]
|
||||
(is (= q (json/decode (json/encode q))))))
|
||||
|
||||
(deftest t-pretty-print
|
||||
(is (= (str/join (System/lineSeparator)
|
||||
["{"
|
||||
" \"bar\" : [ {"
|
||||
" \"baz\" : 2"
|
||||
" }, \"quux\", [ 1, 2, 3 ] ],"
|
||||
" \"foo\" : 1"
|
||||
"}"])
|
||||
(json/encode (sorted-map :foo 1 :bar [{:baz 2} :quux [1 2 3]])
|
||||
{:pretty true}))))
|
||||
|
||||
(deftest t-pretty-print-custom-linebreak
|
||||
(is (= (str/join "foo"
|
||||
["{"
|
||||
" \"bar\" : [ {"
|
||||
" \"baz\" : 2"
|
||||
" }, \"quux\", [ 1, 2, 3 ] ],"
|
||||
" \"foo\" : 1"
|
||||
"}"])
|
||||
(json/encode (sorted-map :foo 1 :bar [{:baz 2} :quux [1 2 3]])
|
||||
{:pretty {:line-break "foo"}}))))
|
||||
|
||||
(deftest t-pretty-print-illegal-argument
|
||||
; just expecting this not to throw
|
||||
(json/encode {:foo "bar"}
|
||||
{:pretty []})
|
||||
(json/encode {:foo "bar"}
|
||||
{:pretty nil}))
|
||||
|
||||
(deftest t-custom-pretty-print-with-defaults
|
||||
(let [test-obj (sorted-map :foo 1 :bar {:baz [{:ulu "mulu"} {:moot "foo"} 3]} :quux :blub)
|
||||
pretty-str-default (json/encode test-obj {:pretty true})
|
||||
pretty-str-custom (json/encode test-obj {:pretty {}})]
|
||||
(is (= pretty-str-default pretty-str-custom))
|
||||
(when-not (= pretty-str-default pretty-str-custom)
|
||||
; print for easy comparison
|
||||
(println "; default pretty print")
|
||||
(println pretty-str-default)
|
||||
(println "; custom pretty print with default options")
|
||||
(println pretty-str-custom))))
|
||||
|
||||
(deftest t-custom-pretty-print-with-non-defaults
|
||||
(let [test-obj (sorted-map :foo 1 :bar {:baz [{:ulu "mulu"} {:moot "foo"} 3]} :quux :blub)
|
||||
test-opts {:pretty {:indentation 4
|
||||
:indent-arrays? false
|
||||
:before-array-values ""
|
||||
:after-array-values ""
|
||||
:object-field-value-separator ": "}}
|
||||
expected (str/join (System/lineSeparator)
|
||||
["{"
|
||||
" \"bar\": {"
|
||||
" \"baz\": [{"
|
||||
" \"ulu\": \"mulu\""
|
||||
" }, {"
|
||||
" \"moot\": \"foo\""
|
||||
" }, 3]"
|
||||
" },"
|
||||
" \"foo\": 1,"
|
||||
" \"quux\": \"blub\""
|
||||
"}"])
|
||||
pretty-str (json/encode test-obj test-opts)]
|
||||
|
||||
; just to be easy on the eyes in case of error
|
||||
(when-not (= expected pretty-str)
|
||||
(println "; pretty print with options - actual")
|
||||
(println pretty-str)
|
||||
(println "; pretty print with options - expected")
|
||||
(println expected))
|
||||
(is (= expected pretty-str))))
|
||||
|
||||
(deftest t-custom-pretty-print-with-noident-objects
|
||||
(let [test-obj [{:foo 1 :bar 2} {:foo 3 :bar 4}]
|
||||
test-opts {:pretty {:indent-objects? false}}
|
||||
expected (str "[ { \"foo\" : 1, \"bar\" : 2 }, "
|
||||
"{ \"foo\" : 3, \"bar\" : 4 } ]")
|
||||
pretty-str (json/encode test-obj test-opts)]
|
||||
; just to be easy on the eyes in case of error
|
||||
(when-not (= expected pretty-str)
|
||||
(println "; pretty print with options - actual")
|
||||
(println pretty-str)
|
||||
(println "; pretty print with options - expected")
|
||||
(println expected))
|
||||
(is (= expected pretty-str))))
|
||||
|
||||
(deftest t-custom-keyword-fn
|
||||
(is (= {:FOO "bar"} (json/decode "{\"foo\": \"bar\"}"
|
||||
(fn [k] (keyword (.toUpperCase k))))))
|
||||
(is (= {"foo" "bar"} (json/decode "{\"foo\": \"bar\"}" nil)))
|
||||
(is (= {"foo" "bar"} (json/decode "{\"foo\": \"bar\"}" false)))
|
||||
(is (= {:foo "bar"} (json/decode "{\"foo\": \"bar\"}" true))))
|
||||
|
||||
(deftest t-custom-encode-key-fn
|
||||
(is (= "{\"FOO\":\"bar\"}"
|
||||
(json/encode {:foo :bar}
|
||||
{:key-fn (fn [k] (.toUpperCase (name k)))}))))
|
||||
|
||||
;; BB-TEST-PATCH: bb does nto include cheshire.generate ns
|
||||
#_(deftest test-add-remove-encoder
|
||||
(gen/remove-encoder java.net.URL)
|
||||
(gen/add-encoder java.net.URL gen/encode-str)
|
||||
(is (= "\"http://foo.com\""
|
||||
(json/encode (java.net.URL. "http://foo.com"))))
|
||||
(gen/remove-encoder java.net.URL)
|
||||
(is (thrown? JsonGenerationException
|
||||
(json/encode (java.net.URL. "http://foo.com")))))
|
||||
|
||||
#_(defprotocol TestP
|
||||
(foo [this] "foo method"))
|
||||
|
||||
#_(defrecord TestR [state])
|
||||
|
||||
#_(extend TestR
|
||||
TestP
|
||||
{:foo (constantly "bar")})
|
||||
|
||||
#_(deftest t-custom-protocol-encoder
|
||||
(let [rec (TestR. :quux)]
|
||||
(is (= {:state "quux"} (json/decode (json/encode rec) true)))
|
||||
(gen/add-encoder cheshire.test.core.TestR
|
||||
(fn [obj jg]
|
||||
(.writeString jg (foo obj))))
|
||||
(is (= "bar" (json/decode (json/encode rec))))
|
||||
(gen/remove-encoder cheshire.test.core.TestR)
|
||||
(is (= {:state "quux"} (json/decode (json/encode rec) true)))))
|
||||
|
||||
#_(defprotocol CTestP
|
||||
(thing [this] "thing method"))
|
||||
#_(defrecord CTestR [state])
|
||||
#_(extend CTestR
|
||||
CTestP
|
||||
{:thing (constantly "thing")})
|
||||
|
||||
#_(deftest t-custom-helpers
|
||||
(let [thing (CTestR. :state)
|
||||
remove #(gen/remove-encoder CTestR)]
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-nil nil jg)))
|
||||
(is (= nil (json/decode (json/encode thing) true)))
|
||||
(remove)
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-str "foo" jg)))
|
||||
(is (= "foo" (json/decode (json/encode thing) true)))
|
||||
(remove)
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-number 5 jg)))
|
||||
(is (= 5 (json/decode (json/encode thing) true)))
|
||||
(remove)
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-long 4 jg)))
|
||||
(is (= 4 (json/decode (json/encode thing) true)))
|
||||
(remove)
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-int 3 jg)))
|
||||
(is (= 3 (json/decode (json/encode thing) true)))
|
||||
(remove)
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-ratio 1/2 jg)))
|
||||
(is (= 0.5 (json/decode (json/encode thing) true)))
|
||||
(remove)
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-seq [:foo :bar] jg)))
|
||||
(is (= ["foo" "bar"] (json/decode (json/encode thing) true)))
|
||||
(remove)
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-date (Date. (long 0)) jg)))
|
||||
(binding [gen/*date-format* "yyyy-MM-dd'T'HH:mm:ss'Z'"]
|
||||
(is (= "1970-01-01T00:00:00Z" (json/decode (json/encode thing) true))))
|
||||
(remove)
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-bool true jg)))
|
||||
(is (= true (json/decode (json/encode thing) true)))
|
||||
(remove)
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-named :foo jg)))
|
||||
(is (= "foo" (json/decode (json/encode thing) true)))
|
||||
(remove)
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-map {:foo "bar"} jg)))
|
||||
(is (= {:foo "bar"} (json/decode (json/encode thing) true)))
|
||||
(remove)
|
||||
(gen/add-encoder CTestR (fn [_obj jg] (gen/encode-symbol 'foo jg)))
|
||||
(is (= "foo" (json/decode (json/encode thing) true)))
|
||||
(remove)))
|
||||
|
||||
(deftest t-float-encoding
|
||||
(is (= "{\"foo\":0.01}" (json/encode {:foo (float 0.01)}))))
|
||||
|
||||
(deftest t-non-const-bools
|
||||
(is (= {:a 1} (json/decode "{\"a\": 1}" (Boolean. true)))))
|
||||
|
||||
;; BB-TEST-PATCH: bb does not include cheshire.exact ns
|
||||
#_(deftest t-invalid-json
|
||||
(let [invalid-json-message "Invalid JSON, expected exactly one parseable object but multiple objects were found"]
|
||||
(are [x y] (= x (try
|
||||
y
|
||||
(catch Exception e
|
||||
(.getMessage e))))
|
||||
invalid-json-message (json-exact/decode "{\"foo\": 1}asdf")
|
||||
invalid-json-message (json-exact/decode "{\"foo\": 123}null")
|
||||
invalid-json-message (json-exact/decode "\"hello\" : 123}")
|
||||
{"foo" 1} (json/decode "{\"foo\": 1}")
|
||||
invalid-json-message (json-exact/decode-strict "{\"foo\": 1}asdf")
|
||||
invalid-json-message (json-exact/decode-strict "{\"foo\": 123}null")
|
||||
invalid-json-message (json-exact/decode-strict "\"hello\" : 123}")
|
||||
{"foo" 1} (json/decode-strict "{\"foo\": 1}"))))
|
||||
2
test-resources/lib_tests/cheshire/test/multi.json
Normal file
2
test-resources/lib_tests/cheshire/test/multi.json
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
{"one":1,"foo":"bar"}
|
||||
{"two":2,"foo":"bar"}
|
||||
58
test-resources/lib_tests/cheshire/test/pass1.json
Normal file
58
test-resources/lib_tests/cheshire/test/pass1.json
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
[
|
||||
"JSON Test Pattern pass1",
|
||||
{"object with 1 member":["array with 1 element"]},
|
||||
{},
|
||||
[],
|
||||
-42,
|
||||
true,
|
||||
false,
|
||||
null,
|
||||
{
|
||||
"integer": 1234567890,
|
||||
"real": -9876.543210,
|
||||
"e": 0.123456789e-12,
|
||||
"E": 1.234567890E+34,
|
||||
"": 23456789012E66,
|
||||
"zero": 0,
|
||||
"one": 1,
|
||||
"space": " ",
|
||||
"quote": "\"",
|
||||
"backslash": "\\",
|
||||
"controls": "\b\f\n\r\t",
|
||||
"slash": "/ & \/",
|
||||
"alpha": "abcdefghijklmnopqrstuvwyz",
|
||||
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
|
||||
"digit": "0123456789",
|
||||
"0123456789": "digit",
|
||||
"special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
|
||||
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
|
||||
"true": true,
|
||||
"false": false,
|
||||
"null": null,
|
||||
"array":[ ],
|
||||
"object":{ },
|
||||
"address": "50 St. James Street",
|
||||
"url": "http://www.JSON.org/",
|
||||
"comment": "// /* <!-- --",
|
||||
"# -- --> */": " ",
|
||||
" s p a c e d " :[1,2 , 3
|
||||
|
||||
,
|
||||
|
||||
4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
|
||||
"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
|
||||
"quotes": "" \u0022 %22 0x22 034 "",
|
||||
"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
|
||||
: "A key can be any string"
|
||||
},
|
||||
0.5 ,98.6
|
||||
,
|
||||
99.44
|
||||
,
|
||||
|
||||
1066,
|
||||
1e1,
|
||||
0.1e1,
|
||||
1e-1,
|
||||
1e00,2e+00,2e-00
|
||||
,"rosebud"]
|
||||
|
|
@ -341,7 +341,7 @@
|
|||
(is (= ::response r))))
|
||||
|
||||
(try (get "https://httpbin.org/gzip" {:timeout 1000})
|
||||
(catch java.net.http.HttpTimeoutException _
|
||||
(catch Exception _
|
||||
(doseq [v (vals (ns-publics *ns*))]
|
||||
(when (:integration (meta v))
|
||||
(println "Removing test from" v "because httpbin is slow.")
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
1
test-resources/posix-file-attributes.txt
Normal file
1
test-resources/posix-file-attributes.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
42
|
||||
|
|
@ -26,15 +26,15 @@
|
|||
(sci/with-in-str (str expr "\n:repl/quit")
|
||||
(repl!)))) expected)))
|
||||
|
||||
(defn assert-repl-error [expr expected]
|
||||
(is (str/includes?
|
||||
(tu/normalize
|
||||
(let [sw (java.io.StringWriter.)]
|
||||
(sci/binding [sci/out (java.io.StringWriter.)
|
||||
sci/err sw]
|
||||
(sci/with-in-str (str expr "\n:repl/quit")
|
||||
(repl!)))
|
||||
(str sw))) expected)))
|
||||
(defmacro assert-repl-error [expr expected]
|
||||
`(is (str/includes?
|
||||
(tu/normalize
|
||||
(let [sw# (java.io.StringWriter.)]
|
||||
(sci/binding [sci/out (java.io.StringWriter.)
|
||||
sci/err sw#]
|
||||
(sci/with-in-str (str ~expr "\n:repl/quit")
|
||||
(repl!)))
|
||||
(str sw#))) ~expected)))
|
||||
|
||||
(deftest repl-test
|
||||
(assert-repl "1" "1")
|
||||
|
|
@ -52,7 +52,9 @@
|
|||
(assert-repl-error "(+ 1 nil)" "NullPointerException")
|
||||
(assert-repl-error "(/ 1 0) (pst 1)" "Divide by zero\n\tclojure.lang.Numbers")
|
||||
(assert-repl-error "(partition (range 5) 3)"
|
||||
"Don't know how to create ISeq from: java.lang.Long"))
|
||||
"Don't know how to create ISeq from: java.lang.Long")
|
||||
(assert-repl "(throw (ex-info \"foo\" {:a (+ 1 2 3)})) (ex-data *e)"
|
||||
"{:a 6}"))
|
||||
|
||||
;;;; Scratch
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,10 @@
|
|||
(bb nil (pr-str '(do
|
||||
(def t (Thread. (fn [])))
|
||||
(def vt (Thread/startVirtualThread (fn [])))
|
||||
[(.isVirtual t) (.isVirtual vt)]))))))
|
||||
[(.isVirtual t) (.isVirtual vt)])))))
|
||||
(is (bb nil (pr-str '(instance?
|
||||
java.util.concurrent.Executor
|
||||
(java.util.concurrent.Executors/newThreadPerTaskExecutor (-> (Thread/ofVirtual) (.name "fusebox-thread-" 1) (.factory))))))))
|
||||
|
||||
(deftest domain-sockets-test
|
||||
(is (= :success (bb nil (slurp "test-resources/domain_sockets.bb")))))
|
||||
|
|
@ -48,6 +51,49 @@
|
|||
(some? (.getSubjectX500Principal cert))
|
||||
"))))
|
||||
|
||||
(deftest ECDH-test
|
||||
(is (true? (bb nil "
|
||||
(import
|
||||
'[java.security KeyPairGenerator MessageDigest]
|
||||
'[java.security.spec ECGenParameterSpec]
|
||||
'[javax.crypto KeyAgreement]
|
||||
'[javax.crypto.spec SecretKeySpec])
|
||||
|
||||
(def keypair-algo \"EC\")
|
||||
(def keypair-curve \"secp256r1\")
|
||||
(def key-agreement-algo \"ECDH\") ; Elliptic Curve Diffie-Hellman
|
||||
(def key-digest-algo \"SHA-256\")
|
||||
(def key-encryption-algo \"AES\")
|
||||
|
||||
(defn keypair
|
||||
\"Generates a new key pair with the given alias, using the keypair-algo and keypair-curve\"
|
||||
[]
|
||||
(let [keygen (KeyPairGenerator/getInstance keypair-algo)]
|
||||
(.initialize keygen (ECGenParameterSpec. keypair-curve))
|
||||
(.generateKeyPair keygen)))
|
||||
|
||||
(defn symmetric-key
|
||||
\"Generates a symmetric key using Elliptic Curve Diffie-Hellman based on a given local private and a remote public key\"
|
||||
[private-key public-key]
|
||||
; Derive shared secret
|
||||
(let [shared-secret
|
||||
(let [key-agreement (KeyAgreement/getInstance key-agreement-algo)]
|
||||
(.init key-agreement private-key)
|
||||
(.doPhase key-agreement public-key true)
|
||||
(.generateSecret key-agreement))
|
||||
symmetric-key
|
||||
(let [message-digest (MessageDigest/getInstance key-digest-algo)
|
||||
hash-bytes (.digest message-digest shared-secret)
|
||||
key-bytes (byte-array (subvec (vec hash-bytes) 0 32))] ; extracts the first 256 bits for AES key
|
||||
(SecretKeySpec. key-bytes key-encryption-algo))]
|
||||
symmetric-key))
|
||||
|
||||
(let [[kp1 kp2] [(keypair) (keypair)]
|
||||
[private public] [(.getPrivate kp1) (.getPublic kp2)]
|
||||
symmetric (symmetric-key private public)]
|
||||
(some? (.getAlgorithm symmetric)))
|
||||
"))))
|
||||
|
||||
(deftest IntStream-test
|
||||
(is (pos? (bb nil "(.count (.codePoints \"woof🐕\"))"))))
|
||||
|
||||
|
|
@ -88,3 +134,135 @@
|
|||
|
||||
(deftest clojure-1_12-array-test
|
||||
(is (true? (bb nil "(instance? Class long/1)"))))
|
||||
|
||||
(deftest keygen-test
|
||||
(is (true?
|
||||
(bb nil
|
||||
'(do (ns keygen
|
||||
(:import [java.security KeyPairGenerator Signature]))
|
||||
|
||||
(defn generate-key-pair
|
||||
"Generates a public/private key pair."
|
||||
[]
|
||||
(let [keygen (KeyPairGenerator/getInstance "RSA")]
|
||||
(.initialize keygen 2048)
|
||||
(.generateKeyPair keygen)))
|
||||
|
||||
(defn create-signature
|
||||
"Signs the given message using the private key."
|
||||
[private-key message]
|
||||
(let [signature (Signature/getInstance "SHA256withRSA")]
|
||||
(.initSign signature private-key)
|
||||
(.update signature (.getBytes message "UTF-8"))
|
||||
(.sign signature)))
|
||||
|
||||
(defn verify-signature
|
||||
"Verifies the given signed data using the public key."
|
||||
[public-key message signed-data]
|
||||
(let [signature (Signature/getInstance "SHA256withRSA")]
|
||||
(.initVerify signature public-key)
|
||||
(.update signature (.getBytes message "UTF-8"))
|
||||
(.verify signature signed-data)))
|
||||
|
||||
(let [key-pair (generate-key-pair)
|
||||
private-key (.getPrivate key-pair)
|
||||
public-key (.getPublic key-pair)
|
||||
message "This is a secret message"
|
||||
signed-data (create-signature private-key message)]
|
||||
(verify-signature public-key message signed-data))))))
|
||||
|
||||
(is (true?
|
||||
(bb nil '(do (import
|
||||
'[java.security KeyPairGenerator]
|
||||
'[java.security.spec ECGenParameterSpec])
|
||||
|
||||
(def keypair-algo "EC")
|
||||
(def keypair-curve "secp256r1")
|
||||
|
||||
(defn keypair
|
||||
"Generates a new key pair with the given alias, using the keypair-algo and keypair-curve"
|
||||
[]
|
||||
(let [keygen (KeyPairGenerator/getInstance keypair-algo)]
|
||||
(.initialize keygen (ECGenParameterSpec. keypair-curve))
|
||||
(.generateKeyPair keygen)))
|
||||
|
||||
(let [kp (keypair)
|
||||
pk (.getPublic kp)]
|
||||
(bytes? (.getEncoded pk))))))))
|
||||
|
||||
;; RT iter test
|
||||
(deftest clojure-RT-iter-test
|
||||
(is (= (iterator-seq (.iterator [1 2 3]))
|
||||
(bb nil '(do (ns test
|
||||
(:import [clojure.lang RT]))
|
||||
(iterator-seq (clojure.lang.RT/iter [1 2 3])))))))
|
||||
|
||||
(deftest posix-file-attributes
|
||||
(when-not test-utils/windows?
|
||||
(is (= 'java.util.HashSet
|
||||
(bb nil
|
||||
'(do
|
||||
(import
|
||||
[java.nio.file Files LinkOption Path]
|
||||
[java.nio.file.attribute PosixFileAttributes])
|
||||
(-> (Files/readAttributes (Path/of "test-resources/posix-file-attributes.txt"
|
||||
(into-array String []))
|
||||
PosixFileAttributes
|
||||
^"[Ljava.nio.file.LinkOption;"
|
||||
(into-array LinkOption []))
|
||||
.permissions
|
||||
type)))))))
|
||||
|
||||
(deftest extended-attributes
|
||||
(is (true?
|
||||
(bb nil
|
||||
'(do
|
||||
(import
|
||||
[java.nio.file Files LinkOption Path]
|
||||
[java.nio.file.attribute UserDefinedFileAttributeView])
|
||||
(instance? UserDefinedFileAttributeView
|
||||
(Files/getFileAttributeView (Path/of "test-resources/extended-attributes.txt"
|
||||
(into-array String []))
|
||||
UserDefinedFileAttributeView
|
||||
^"[Ljava.nio.file.LinkOption;"
|
||||
(into-array LinkOption []))))))))
|
||||
|
||||
;; exercise a sampling of the superclass resolutions from the :public-class fn in
|
||||
;; babashka.impl.classes/gen-class-map
|
||||
(deftest public-class-resolutions
|
||||
(testing "Charset"
|
||||
(is (= "UTF-8" (bb nil "(.displayName (java.nio.charset.Charset/forName \"UTF-8\"))"))))
|
||||
(testing "InputStream"
|
||||
(is (zero? (bb nil "(with-open [is (java.io.InputStream/nullInputStream)]
|
||||
(.available is))"))))
|
||||
(testing "Throwable"
|
||||
; compare output from ex-message to calling .getMessage
|
||||
(let [return-throwable "(try (yaml/parse-string \"abc: def: ghi\") (catch Exception e e))"]
|
||||
(is (= (bb nil (str "(ex-message " return-throwable ")"))
|
||||
(bb nil (str "(.getMessage " return-throwable ")"))))))
|
||||
(testing "jsoup Element"
|
||||
(is (= "form" (bb nil "(.tagName (first (.getElementsByTag (org.jsoup.Jsoup/parseBodyFragment \"<form></form>\") \"form\")))")))))
|
||||
|
||||
(deftest cached-thread-pool
|
||||
(is (= 3 (bb nil "(import '(java.util.concurrent Executors ExecutorService))
|
||||
(let [fut (.submit ^ExecutorService (Executors/newCachedThreadPool) ^Callable (fn [] 3))]
|
||||
(.get fut))")))
|
||||
(is (nil? (bb nil "(import '(java.util.concurrent Executors ExecutorService))
|
||||
(let [fut (.submit ^ExecutorService (Executors/newCachedThreadPool) ^Runnable (fn [] 3))]
|
||||
(.get fut))"))))
|
||||
|
||||
(deftest break-iterator-test
|
||||
(is (= 1 (bb nil "(ns dude
|
||||
(:import [java.text BreakIterator]))
|
||||
|
||||
(defn count-characters
|
||||
[^String text]
|
||||
(let [it (BreakIterator/getCharacterInstance)]
|
||||
(.setText it text)
|
||||
(loop [count 0]
|
||||
(if (= (.next it) BreakIterator/DONE)
|
||||
count
|
||||
(recur (inc count))))))
|
||||
|
||||
(prn
|
||||
(count-characters \"🇨🇦\"))"))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue