From 6c69b2d79bf78bb1305a33a18892c9e5ca0a3361 Mon Sep 17 00:00:00 2001 From: Cynthia Date: Wed, 15 May 2024 19:23:17 +0200 Subject: [PATCH 1/6] ci: configure build and test --- .github/workflows/build.yml | 65 +++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..ca80c05 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,65 @@ +name: Build +on: + push: + branches: + - mistress + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 9 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + cache: pnpm + - run: pnpm install + - run: pnpm run build + - uses: actions/upload-artifact@v4 + with: + name: dist + path: dist + + vitest: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + node: [18, 20, 22] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 9 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + cache: pnpm + - run: pnpm install + - run: pnpm run test + + toml-test: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + node: [18, 20, 22] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/setup-go@v4 + with: + go-version: '^1.22.3' + - run: go install github.com/toml-lang/toml-test/cmd/toml-test@latest + + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + - run: ./run-toml-test.bash From 0ab35c63c086c14ebd69525c1852a4c75f4eb1d8 Mon Sep 17 00:00:00 2001 From: Cynthia Date: Wed, 15 May 2024 19:31:20 +0200 Subject: [PATCH 2/6] ci: use bleeding edge toml-test --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ca80c05..3c03e43 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -52,7 +52,7 @@ jobs: - uses: actions/setup-go@v4 with: go-version: '^1.22.3' - - run: go install github.com/toml-lang/toml-test/cmd/toml-test@latest + - run: go install github.com/toml-lang/toml-test/cmd/toml-test@master - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 From 5b57a1ea1b0fa2d82e528491b97dfcd0bd78e798 Mon Sep 17 00:00:00 2001 From: Cynthia Date: Wed, 15 May 2024 20:23:25 +0200 Subject: [PATCH 3/6] test: skip more test that fail but shouldn't --- run-toml-test.bash | 42 ++++++++++++++++++++++++++++++++++++++---- toml-test-encode.mjs | 8 +++----- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/run-toml-test.bash b/run-toml-test.bash index 958ad8d..12786cc 100755 --- a/run-toml-test.bash +++ b/run-toml-test.bash @@ -3,18 +3,52 @@ # Requires toml-test from https://github.com/toml-lang/toml-test, commit 78f8c61 # or newer (Oct 2023). -skip=( +skip_decode=( # Invalid UTF-8 strings are not rejected -skip='invalid/encoding/bad-utf8-*' # Certain invalid UTF-8 codepoints are not rejected -skip='invalid/encoding/bad-codepoint' + -skip='invalid/string/bad-uni-esc-6' - # JS uses floats for numbers + # JS doesn't reject invalid dates, but interprets extra days such as "Feb 30" as "Feb 28 +2d" gracefully + # This behavior is implementation specific, although this should hold true for all major JS engines out there. + # See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse#non-standard_date_strings + # + # While smol-toml could implement additional checks, this has not been done for performance reasons + -skip='invalid/local-date/feb-29' + -skip='invalid/local-datetime/feb-29' + -skip='invalid/datetime/feb-29' + -skip='invalid/local-date/feb-30' + -skip='invalid/local-datetime/feb-30' + -skip='invalid/datetime/feb-30' + + # https://github.com/toml-lang/toml-test/issues/154 + -skip='valid/integer/long' +) + +skip_encode=( + # https://github.com/toml-lang/toml-test/issues/155 + -skip='valid/spec/offset-date-time-0' + -skip='valid/spec/local-date-time-0' + -skip='valid/spec/local-time-0' + + # Some more Float <> Integer shenanigans + -skip='valid/inline-table/spaces' + -skip='valid/float/zero' + -skip='valid/float/underscore' + -skip='valid/float/exponent' + -skip='valid/comment/tricky' + -skip='valid/spec/float-0' + + # https://github.com/toml-lang/toml-test/issues/154 -skip='valid/integer/long' ) e=0 -toml-test -int-as-float ${skip[@]} ./toml-test-parse.mjs || e=1 -toml-test -int-as-float -encoder ${skip[@]} ./toml-test-encode.mjs || e=1 +# -int-as-float as there is no way to distinguish between them at this time. +# For the encoder, distinction is made between floats and integers using JS bigint, however +# due to the lack of option to always serialize plain numbers as floats, some tests fail (and are therefore skipped) +~/go/bin/toml-test -int-as-float ${skip_decode[@]} ./toml-test-parse.mjs || e=1 +~/go/bin/toml-test -encoder ${skip_encode[@]} ./toml-test-encode.mjs || e=1 exit $e diff --git a/toml-test-encode.mjs b/toml-test-encode.mjs index 02e52c6..8259d70 100755 --- a/toml-test-encode.mjs +++ b/toml-test-encode.mjs @@ -42,7 +42,9 @@ function untagObject (obj) { case 'bool': return obj.value === 'true' case 'integer': - return BigInt(obj.value) + // TODO: add an option to always serialize numbers as floats + // return BigInt(obj.value) + return Number(obj.value) case 'float': if (obj.value === 'nan') return NaN if (obj.value === '+nan') return NaN @@ -50,10 +52,6 @@ function untagObject (obj) { if (obj.value === 'inf') return Infinity if (obj.value === '+inf') return Infinity if (obj.value === '-inf') return -Infinity - - if (obj.value === 'Inf') return Infinity - if (obj.value === '+Inf') return Infinity - if (obj.value === '-Inf') return -Infinity return Number(obj.value) case 'datetime': case 'datetime-local': From ec820fd4042693d8bbc74e71b07527735f2f7b50 Mon Sep 17 00:00:00 2001 From: Cynthia Date: Wed, 15 May 2024 20:23:48 +0200 Subject: [PATCH 4/6] fix: properly handle plain dates --- src/date.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/date.ts b/src/date.ts index 48c4c56..712efcb 100644 --- a/src/date.ts +++ b/src/date.ts @@ -58,7 +58,7 @@ export class TomlDate extends Date { } else { offset = match[3] || null date = date.toUpperCase() - if (!offset) date += 'Z' + if (!offset && hasTime) date += 'Z' } } else { date = '' From f8c40e9bf38e80d3d2a76f8c73ee4f41196f0fe9 Mon Sep 17 00:00:00 2001 From: Cynthia Date: Wed, 15 May 2024 20:27:58 +0200 Subject: [PATCH 5/6] ci: correctly set node version for build job --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3c03e43..4c5c8ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: version: 9 - uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node }} + node-version: 22 cache: pnpm - run: pnpm install - run: pnpm run build From 7b3761f61c02b434a22005339e48125051789185 Mon Sep 17 00:00:00 2001 From: Cynthia Date: Sun, 19 May 2024 13:41:40 +0200 Subject: [PATCH 6/6] docs: update readme --- README.md | 11 +++++++++-- run-toml-test.bash | 22 ++++++++++++++-------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4a83c1b..0809b5e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![TOML 1.0.0](https://img.shields.io/badge/TOML-1.0.0-9c4221?style=flat-square)](https://toml.io/en/v1.0.0) [![License](https://img.shields.io/github/license/squirrelchat/smol-toml.svg?style=flat-square)](https://github.com/squirrelchat/smol-toml/blob/mistress/LICENSE) [![npm](https://img.shields.io/npm/v/smol-toml?style=flat-square)](https://npm.im/smol-toml) +[![Build](https://img.shields.io/github/actions/workflow/status/squirrelchat/smol-toml/build.yml?style=flat-square&logo=github)](https://github.com/squirrelchat/smol-toml/actions/workflows/build.yml) A small, fast, and correct TOML parser and serializer. smol-toml is fully(ish) spec-compliant with TOML v1.0.0. @@ -16,9 +17,15 @@ smol-toml passes most of the tests from the [`toml-test` suite](https://github.c it doesn't pass certain tests, namely: - Invalid UTF-8 strings are not rejected - Certain invalid UTF-8 codepoints are not rejected +- Certain invalid dates are not rejected + - For instance, `2023-02-30` would be accepted and parsed as `2023-03-02`. While additional checks could be performed + to reject these, they've not been added for performance reasons. - smol-toml doesn't preserve type information between integers and floats (in JS, everything is a float) -- smol-toml doesn't support the whole 64-bit range for integers (but does throw an appropriate error) - - As all numbers are floats in JS, the safe range is `2**53 - 1` <=> `-(2**53 - 1)`. + +You can see a list of all tests smol-toml fails (and the reason why it fails these) in the list of skipped tests in +`run-toml-test.bash`. Note that some failures are *not* specification violations per-se. For instance, the TOML spec +does not require 64-bit integer range support or sub-millisecond time precision, but are included in the `toml-test` +suite. See https://github.com/toml-lang/toml-test/issues/154 and https://github.com/toml-lang/toml-test/issues/155 ## Installation ``` diff --git a/run-toml-test.bash b/run-toml-test.bash index 12786cc..519dff9 100755 --- a/run-toml-test.bash +++ b/run-toml-test.bash @@ -1,7 +1,5 @@ #!/usr/bin/env bash -# -# Requires toml-test from https://github.com/toml-lang/toml-test, commit 78f8c61 -# or newer (Oct 2023). +# Requires toml-test from https://github.com/toml-lang/toml-test, commit 78f8c61 or newer (Oct 2023). skip_decode=( # Invalid UTF-8 strings are not rejected @@ -11,9 +9,10 @@ skip_decode=( -skip='invalid/encoding/bad-codepoint' -skip='invalid/string/bad-uni-esc-6' - # JS doesn't reject invalid dates, but interprets extra days such as "Feb 30" as "Feb 28 +2d" gracefully - # This behavior is implementation specific, although this should hold true for all major JS engines out there. - # See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse#non-standard_date_strings + # JS* doesn't reject invalid dates, but interprets extra days such as "Feb 30 2023" as "Feb 28 2023 +2d" gracefully. + # + # *This is true for V8, SpiderMonkey, and JavaScriptCore. Note that this behavior is implementation specific and + # certain flavors of engines may behave differently. # # While smol-toml could implement additional checks, this has not been done for performance reasons -skip='invalid/local-date/feb-29' @@ -23,17 +22,22 @@ skip_decode=( -skip='invalid/local-datetime/feb-30' -skip='invalid/datetime/feb-30' + # smol-toml does not support the entire 64-bit integer range + # This is not required by the specification, and smol-toml throws an appropriate error # https://github.com/toml-lang/toml-test/issues/154 -skip='valid/integer/long' ) skip_encode=( + # smol-toml does not support sub-millisecond time precision + # This is not required by the specification, and smol-toml performs appropriate *truncation*, not rounding # https://github.com/toml-lang/toml-test/issues/155 -skip='valid/spec/offset-date-time-0' -skip='valid/spec/local-date-time-0' -skip='valid/spec/local-time-0' # Some more Float <> Integer shenanigans + # -int-as-float can't help us here, so we have to skip these :( -skip='valid/inline-table/spaces' -skip='valid/float/zero' -skip='valid/float/underscore' @@ -41,6 +45,8 @@ skip_encode=( -skip='valid/comment/tricky' -skip='valid/spec/float-0' + # smol-toml does not support the entire 64-bit integer range + # This is not required by the specification, and smol-toml throws an appropriate error # https://github.com/toml-lang/toml-test/issues/154 -skip='valid/integer/long' ) @@ -49,6 +55,6 @@ e=0 # -int-as-float as there is no way to distinguish between them at this time. # For the encoder, distinction is made between floats and integers using JS bigint, however # due to the lack of option to always serialize plain numbers as floats, some tests fail (and are therefore skipped) -~/go/bin/toml-test -int-as-float ${skip_decode[@]} ./toml-test-parse.mjs || e=1 -~/go/bin/toml-test -encoder ${skip_encode[@]} ./toml-test-encode.mjs || e=1 +toml-test -int-as-float ${skip_decode[@]} ./toml-test-parse.mjs || e=1 +toml-test -encoder ${skip_encode[@]} ./toml-test-encode.mjs || e=1 exit $e