diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index d9fcb92..467ba1f 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -91,20 +91,17 @@ jobs: os: windows-latest shell: cmd node-version: - - 18.17.0 - - 18.x - - 20.5.0 + - 20.17.0 - 20.x + - 22.9.0 - 22.x exclude: - platform: { name: macOS, os: macos-13, shell: bash } - node-version: 18.17.0 - - platform: { name: macOS, os: macos-13, shell: bash } - node-version: 18.x - - platform: { name: macOS, os: macos-13, shell: bash } - node-version: 20.5.0 + node-version: 20.17.0 - platform: { name: macOS, os: macos-13, shell: bash } node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 - platform: { name: macOS, os: macos-13, shell: bash } node-version: 22.x runs-on: ${{ matrix.platform.os }} @@ -140,9 +137,11 @@ jobs: node: ${{ steps.node.outputs.node-version }} - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - - name: Add Problem Matcher - run: echo "::add-matcher::.github/matchers/tap.json" - - name: Test + - name: Test (with coverage on Node >= 24) + if: ${{ startsWith(matrix.node-version, '24') }} + run: npm run test:cover --ignore-scripts + - name: Test (without coverage on Node < 24) + if: ${{ !startsWith(matrix.node-version, '24') }} run: npm test --ignore-scripts - name: Conclude Check uses: LouisBrunner/checks-action@v1.6.0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b991984..09eb0f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,20 +67,17 @@ jobs: os: windows-latest shell: cmd node-version: - - 18.17.0 - - 18.x - - 20.5.0 + - 20.17.0 - 20.x + - 22.9.0 - 22.x exclude: - platform: { name: macOS, os: macos-13, shell: bash } - node-version: 18.17.0 - - platform: { name: macOS, os: macos-13, shell: bash } - node-version: 18.x - - platform: { name: macOS, os: macos-13, shell: bash } - node-version: 20.5.0 + node-version: 20.17.0 - platform: { name: macOS, os: macos-13, shell: bash } node-version: 20.x + - platform: { name: macOS, os: macos-13, shell: bash } + node-version: 22.9.0 - platform: { name: macOS, os: macos-13, shell: bash } node-version: 22.x runs-on: ${{ matrix.platform.os }} @@ -106,7 +103,9 @@ jobs: node: ${{ steps.node.outputs.node-version }} - name: Install Dependencies run: npm i --ignore-scripts --no-audit --no-fund - - name: Add Problem Matcher - run: echo "::add-matcher::.github/matchers/tap.json" - - name: Test + - name: Test (with coverage on Node >= 24) + if: ${{ startsWith(matrix.node-version, '24') }} + run: npm run test:cover --ignore-scripts + - name: Test (without coverage on Node < 24) + if: ${{ !startsWith(matrix.node-version, '24') }} run: npm test --ignore-scripts diff --git a/package.json b/package.json index 5455aae..7ca5c5c 100644 --- a/package.json +++ b/package.json @@ -12,16 +12,16 @@ "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"", "lint": "npm run eslint", "lintfix": "npm run eslint -- --fix", - "test": "tap", - "snap": "tap", + "test": "node --test './test/**/*.js'", + "snap": "node --test --test-update-snapshots './test/**/*.js'", "posttest": "npm run lint", "postlint": "template-oss-check", - "template-oss-apply": "template-oss-apply --force" + "template-oss-apply": "template-oss-apply --force", + "test:cover": "node --test --experimental-test-coverage --test-timeout=3000 --test-coverage-lines=100 --test-coverage-functions=100 --test-coverage-branches=100 './test/**/*.js'" }, "devDependencies": { "@npmcli/eslint-config": "^5.0.0", - "@npmcli/template-oss": "4.26.0", - "tap": "^16.0.1" + "@npmcli/template-oss": "4.27.1" }, "license": "ISC", "files": [ @@ -29,17 +29,12 @@ "lib/" ], "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" }, "templateOSS": { "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", - "version": "4.26.0", - "publish": "true" - }, - "tap": { - "nyc-arg": [ - "--exclude", - "tap-snapshots/**" - ] + "version": "4.27.1", + "publish": "true", + "testRunner": "node:test" } } diff --git a/tap-snapshots/test/duplicate-properties.js.test.cjs b/tap-snapshots/test/duplicate-properties.js.test.cjs deleted file mode 100644 index 7feb707..0000000 --- a/tap-snapshots/test/duplicate-properties.js.test.cjs +++ /dev/null @@ -1,57 +0,0 @@ -/* IMPORTANT - * This snapshot file is auto-generated, but designed for humans. - * It should be checked into source control and tracked carefully. - * Re-generate by setting TAP_SNAPSHOT=1 and running tests. - * Make sure to inspect the output below. Do not ignore changes! - */ -'use strict' -exports[`test/duplicate-properties.js TAP decode duplicate properties with bracketedArray=false > must match snapshot 1`] = ` -Null Object { - "ar": Array [ - "three", - ], - "ar[]": "one", - "brr": Array [ - "1", - "2", - "3", - "3", - ], - "str": "3", - "zr": "123", - "zr[]": "deedee", -} -` - -exports[`test/duplicate-properties.js TAP decode with duplicate properties > must match snapshot 1`] = ` -Null Object { - "ar": Array [ - "one", - "three", - ], - "brr": "3", - "str": "3", - "zr": Array [ - "deedee", - "123", - ], -} -` - -exports[`test/duplicate-properties.js TAP encode duplicate properties with bracketedArray=false > must match snapshot 1`] = ` -ar=1 -ar=2 -ar=3 -br=1 -br=2 - -` - -exports[`test/duplicate-properties.js TAP encode with duplicate properties > must match snapshot 1`] = ` -ar[]=1 -ar[]=2 -ar[]=3 -br[]=1 -br[]=2 - -` diff --git a/tap-snapshots/test/foo.js.test.cjs b/tap-snapshots/test/foo.js.test.cjs deleted file mode 100644 index 2646323..0000000 --- a/tap-snapshots/test/foo.js.test.cjs +++ /dev/null @@ -1,304 +0,0 @@ -/* IMPORTANT - * This snapshot file is auto-generated, but designed for humans. - * It should be checked into source control and tracked carefully. - * Re-generate by setting TAP_SNAPSHOT=1 and running tests. - * Make sure to inspect the output below. Do not ignore changes! - */ -'use strict' -exports[`test/foo.js TAP decode from file > must match snapshot 1`] = ` -Null Object { - " xa n p ": String( - "\\r - yoyoyo\\r\\r - - ), - "[disturbing]": "hey you never know", - "a": Null Object { - "[]": "a square?", - "av": "a val", - "b": Null Object { - "c": Null Object { - "e": "1", - "j": "2", - }, - }, - "cr": Array [ - "four", - "eight", - ], - "e": "{ o: p, a: { av: a val, b: { c: { e: \\"this [value]\\" } } } }", - "j": "\\"{ o: \\"p\\", a: { av: \\"a val\\", b: { c: { e: \\"this [value]\\" } } } }\\"", - }, - "a with spaces": "b c", - "ar": Array [ - "one", - "three", - "this is included", - ], - "b": Null Object {}, - "br": "warm", - "eq": "eq=eq", - "false": false, - "null": null, - "o": "p", - "s": "something", - "s1": "\\"something'", - "s2": "something else", - "s3": "", - "s4": "", - "s5": " ", - "s6": " a ", - "s7": true, - "true": true, - "undefined": "undefined", - "x.y.z": Null Object { - "a.b.c": Null Object { - "a.b.c": "abc", - "nocomment": "this; this is not a comment", - "noHashComment": "this# this is not a comment", - }, - "x.y.z": "xyz", - }, - "zr": Array [ - "deedee", - ], -} -` - -exports[`test/foo.js TAP encode from data > must match snapshot 1`] = ` -o=p -a with spaces=b c -" xa n p "="\\"\\r\\nyoyoyo\\r\\r\\n" -"[disturbing]"=hey you never know -s=something -s1="something' -s2=something else -s3= -s4= -s5=" " -s6=" a " -s7=true -true=true -false=false -null=null -undefined=undefined -zr[]=deedee -ar[]=one -ar[]=three -ar[]=this is included -br=warm -eq="eq=eq" - -[a] -av=a val -e={ o: p, a: { av: a val, b: { c: { e: "this [value]" } } } } -j="\\"{ o: \\"p\\", a: { av: \\"a val\\", b: { c: { e: \\"this [value]\\" } } } }\\"" -"[]"=a square? -cr[]=four -cr[]=eight - -[a.b.c] -e=1 -j=2 - -[x\\.y\\.z] -x.y.z=xyz - -[x\\.y\\.z.a\\.b\\.c] -a.b.c=abc -nocomment=this\\; this is not a comment -noHashComment=this\\# this is not a comment - -` - -exports[`test/foo.js TAP encode with align > must match snapshot 1`] = ` -o = p -a with spaces = b c -" xa n p " = "\\"\\r\\nyoyoyo\\r\\r\\n" -"[disturbing]" = hey you never know -s = something -s1 = "something' -s2 = something else -s3 = -s4 = -s5 = " " -s6 = " a " -s7 = true -true = true -false = false -null = null -undefined = undefined -zr[] = deedee -ar[] = one -ar[] = three -ar[] = this is included -br = warm -eq = "eq=eq" - -[a] -av = a val -e = { o: p, a: { av: a val, b: { c: { e: "this [value]" } } } } -j = "\\"{ o: \\"p\\", a: { av: \\"a val\\", b: { c: { e: \\"this [value]\\" } } } }\\"" -"[]" = a square? -cr[] = four -cr[] = eight - -[a.b.c] -e = 1 -j = 2 - -[x\\.y\\.z] -x.y.z = xyz - -[x\\.y\\.z.a\\.b\\.c] -a.b.c = abc -nocomment = this\\; this is not a comment -noHashComment = this\\# this is not a comment - -` - -exports[`test/foo.js TAP encode with align and sort > must match snapshot 1`] = ` -" xa n p " = "\\"\\r\\nyoyoyo\\r\\r\\n" -"[disturbing]" = hey you never know -a with spaces = b c -ar[] = one -ar[] = three -ar[] = this is included -br = warm -eq = "eq=eq" -false = false -null = null -o = p -s = something -s1 = "something' -s2 = something else -s3 = -s4 = -s5 = " " -s6 = " a " -s7 = true -true = true -undefined = undefined -zr[] = deedee - -[a] -"[]" = a square? -av = a val -cr[] = four -cr[] = eight -e = { o: p, a: { av: a val, b: { c: { e: "this [value]" } } } } -j = "\\"{ o: \\"p\\", a: { av: \\"a val\\", b: { c: { e: \\"this [value]\\" } } } }\\"" - -[a.b.c] -e = 1 -j = 2 - -[x\\.y\\.z] -x.y.z = xyz - -[x\\.y\\.z.a\\.b\\.c] -a.b.c = abc -noHashComment = this\\# this is not a comment -nocomment = this\\; this is not a comment - -` - -exports[`test/foo.js TAP encode with newline > must match snapshot 1`] = ` -[log] - -type=file - -[log.level] - -label=debug -value=10 - -` - -exports[`test/foo.js TAP encode with option > must match snapshot 1`] = ` -[prefix.log] -type=file - -[prefix.log.level] -label=debug -value=10 - -` - -exports[`test/foo.js TAP encode with platform=win32 > must match snapshot 1`] = ` -Array [ - "[log]", - "type=file", - "", - "[log.level]", - "label=debug", - "value=10", - "", -] -` - -exports[`test/foo.js TAP encode with sort > must match snapshot 1`] = ` -" xa n p "="\\"\\r\\nyoyoyo\\r\\r\\n" -"[disturbing]"=hey you never know -a with spaces=b c -ar[]=one -ar[]=three -ar[]=this is included -br=warm -eq="eq=eq" -false=false -null=null -o=p -s=something -s1="something' -s2=something else -s3= -s4= -s5=" " -s6=" a " -s7=true -true=true -undefined=undefined -zr[]=deedee - -[a] -"[]"=a square? -av=a val -cr[]=four -cr[]=eight -e={ o: p, a: { av: a val, b: { c: { e: "this [value]" } } } } -j="\\"{ o: \\"p\\", a: { av: \\"a val\\", b: { c: { e: \\"this [value]\\" } } } }\\"" - -[a.b.c] -e=1 -j=2 - -[x\\.y\\.z] -x.y.z=xyz - -[x\\.y\\.z.a\\.b\\.c] -a.b.c=abc -noHashComment=this\\# this is not a comment -nocomment=this\\; this is not a comment - -` - -exports[`test/foo.js TAP encode with whitespace > must match snapshot 1`] = ` -[log] -type = file - -[log.level] -label = debug -value = 10 - -` - -exports[`test/foo.js TAP encode within browser context > must match snapshot 1`] = ` -[log] -type=file - -[log.level] -label=debug -value=10 - -` diff --git a/test/bar.js b/test/bar.js index 8f7eb23..c335a69 100644 --- a/test/bar.js +++ b/test/bar.js @@ -1,21 +1,19 @@ -// test that parse(stringify(obj) +const ini = require('../') +const t = require('node:test') +const a = require('node:assert') -var ini = require('../') -var test = require('tap').test - -var data = { +const data = { number: { count: 10 }, string: { drink: 'white russian' }, boolean: { isTrue: true }, 'nested boolean': { theDude: { abides: true, rugCount: 1 } }, } -test('parse(stringify(x)) is same as x', function (t) { - for (var k in data) { - var s = ini.stringify(data[k]) - t.comment(s, data[k]) - t.same(ini.parse(s), data[k]) +t.suite('parse(stringify(x)) is same as x', () => { + for (const k in data) { + const s = ini.stringify(data[k]) + t.test(k, () => { + a.deepEqual(ini.parse(s), data[k]) + }) } - - t.end() }) diff --git a/test/duplicate-properties.js b/test/duplicate-properties.js index 6f47c91..1e2669e 100644 --- a/test/duplicate-properties.js +++ b/test/duplicate-properties.js @@ -1,40 +1,40 @@ const i = require('../') -const tap = require('tap') -const test = tap.test -const fs = require('fs') -const path = require('path') +const t = require('node:test') +const fs = require('node:fs') +const path = require('node:path') const fixture = path.resolve(__dirname, './fixtures/duplicate.ini') const data = fs.readFileSync(fixture, 'utf8') -tap.cleanSnapshot = s => s.replace(/\r\n/g, '\n') +t.snapshot.setDefaultSnapshotSerializers([ + JSON.stringify, + s => s.replace(/\r\n/g, '\n'), +]) -test('decode with duplicate properties', function (t) { - const d = i.decode(data) - t.matchSnapshot(d) - t.end() -}) +t.test('duplicate properties', (t) => { + t.test('decode with duplicate properties', (t) => { + const d = i.decode(data) + t.assert.snapshot(d) + }) -test('encode with duplicate properties', function (t) { - const e = i.encode({ - ar: ['1', '2', '3'], - br: ['1', '2'], + t.test('encode with duplicate properties', (t) => { + const e = i.encode({ + ar: ['1', '2', '3'], + br: ['1', '2'], + }) + t.assert.snapshot(e) }) - t.matchSnapshot(e) - t.end() -}) -test('decode duplicate properties with bracketedArray=false', function (t) { - const d = i.decode(data, { bracketedArray: false }) - t.matchSnapshot(d) - t.end() -}) + t.test('decode duplicate properties with bracketedArray=false', (t) => { + const d = i.decode(data, { bracketedArray: false }) + t.assert.snapshot(d) + }) -test('encode duplicate properties with bracketedArray=false', function (t) { - const e = i.encode({ - ar: ['1', '2', '3'], - br: ['1', '2'], - }, { bracketedArray: false }) - t.matchSnapshot(e) - t.end() + t.test('encode duplicate properties with bracketedArray=false', (t) => { + const e = i.encode({ + ar: ['1', '2', '3'], + br: ['1', '2'], + }, { bracketedArray: false }) + t.assert.snapshot(e) + }) }) diff --git a/test/duplicate-properties.js.snapshot b/test/duplicate-properties.js.snapshot new file mode 100644 index 0000000..ef3532e --- /dev/null +++ b/test/duplicate-properties.js.snapshot @@ -0,0 +1,15 @@ +exports[`duplicate properties > decode duplicate properties with bracketedArray=false 1`] = ` +{"zr[]":"deedee","zr":"123","ar[]":"one","ar":["three"],"str":"3","brr":["1","2","3","3"]} +`; + +exports[`duplicate properties > decode with duplicate properties 1`] = ` +{"zr":["deedee","123"],"ar":["one","three"],"str":"3","brr":"3"} +`; + +exports[`duplicate properties > encode duplicate properties with bracketedArray=false 1`] = ` +"ar=1\\nar=2\\nar=3\\nbr=1\\nbr=2\\n" +`; + +exports[`duplicate properties > encode with duplicate properties 1`] = ` +"ar[]=1\\nar[]=2\\nar[]=3\\nbr[]=1\\nbr[]=2\\n" +`; diff --git a/test/foo.js b/test/foo.js index fe92435..2fc2958 100644 --- a/test/foo.js +++ b/test/foo.js @@ -1,96 +1,85 @@ const i = require('../') -const tap = require('tap') -const test = tap.test -const fs = require('fs') -const path = require('path') +const fs = require('node:fs') +const t = require('node:test') +const a = require('node:assert') +const path = require('node:path') const fixture = path.resolve(__dirname, './fixtures/foo.ini') const data = fs.readFileSync(fixture, 'utf8') -tap.cleanSnapshot = s => s.replace(/\r\n/g, '\n') - -test('decode from file', function (t) { - const d = i.decode(data) - t.matchSnapshot(d) - t.end() -}) - -test('encode from data', function (t) { - const d = i.decode(data) - const e = i.encode(d) - t.matchSnapshot(e) - t.end() -}) - -test('never a blank first or last line', function (t) { - const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } - const e = i.encode(obj) - t.not(e.slice(0, 1), '\n', 'Never a blank first line') - t.not(e.slice(-2), '\n\n', 'Never a blank final line') - t.end() -}) - -test('encode with option', function (t) { - const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } - const e = i.encode(obj, { section: 'prefix' }) - - t.matchSnapshot(e) - t.end() -}) - -test('encode with whitespace', function (t) { - const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } - const e = i.encode(obj, { whitespace: true }) - - t.matchSnapshot(e) - t.end() -}) - -test('encode with newline', function (t) { - const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } - const e = i.encode(obj, { newline: true }) - - t.matchSnapshot(e) - t.end() -}) - -test('encode with platform=win32', function (t) { - const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } - const e = i.encode(obj, { platform: 'win32' }) - - t.matchSnapshot(e.split('\r\n')) - t.end() -}) - -test('encode with align', function (t) { - const d = i.decode(data) - const e = i.encode(d, { align: true }) - - t.matchSnapshot(e) - t.end() -}) - -test('encode with sort', function (t) { - const d = i.decode(data) - const e = i.encode(d, { sort: true }) - - t.matchSnapshot(e) - t.end() -}) - -test('encode with align and sort', function (t) { - const d = i.decode(data) - const e = i.encode(d, { align: true, sort: true }) - - t.matchSnapshot(e) - t.end() -}) - -test('encode within browser context', function (t) { - Object.defineProperty(process, 'platform', { value: undefined }) - - const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } - const e = i.encode(obj) - - t.matchSnapshot(e) - t.end() +t.snapshot.setDefaultSnapshotSerializers([ + JSON.stringify, + s => s.replace(/\r\n/g, '\n'), +]) + +t.suite('foo.ini', () => { + t.test('decode from file', (t) => { + const d = i.decode(data) + t.assert.snapshot(d) + }) + + t.test('encode from data', (t) => { + const d = i.decode(data) + const e = i.encode(d) + t.assert.snapshot(e) + }) + + t.test('never a blank first or last line', () => { + const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } + const e = i.encode(obj) + a.notEqual(e.slice(0, 1), '\n', 'Never a blank first line') + a.notEqual(e.slice(-2), '\n\n', 'Never a blank final line') + }) + + t.test('encode with option', (t) => { + const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } + const e = i.encode(obj, { section: 'prefix' }) + t.assert.snapshot(e) + }) + + t.test('encode with whitespace', (t) => { + const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } + const e = i.encode(obj, { whitespace: true }) + + t.assert.snapshot(e) + }) + + t.test('encode with newline', (t) => { + const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } + const e = i.encode(obj, { newline: true }) + + t.assert.snapshot(e) + }) + + t.test('encode with platform=win32', (t) => { + const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } + const e = i.encode(obj, { platform: 'win32' }) + t.assert.snapshot(e.split('\r\n')) + }) + + t.test('encode with align', (t) => { + const d = i.decode(data) + const e = i.encode(d, { align: true }) + t.assert.snapshot(e) + }) + + t.test('encode with sort', (t) => { + const d = i.decode(data) + const e = i.encode(d, { sort: true }) + t.assert.snapshot(e) + }) + + t.test('encode with align and sort', (t) => { + const d = i.decode(data) + const e = i.encode(d, { align: true, sort: true }) + t.assert.snapshot(e) + }) + + t.test('encode within browser context', (t) => { + Object.defineProperty(process, 'platform', { value: undefined }) + + const obj = { log: { type: 'file', level: { label: 'debug', value: 10 } } } + const e = i.encode(obj) + + t.assert.snapshot(e) + }) }) diff --git a/test/foo.js.snapshot b/test/foo.js.snapshot new file mode 100644 index 0000000..4a96ddc --- /dev/null +++ b/test/foo.js.snapshot @@ -0,0 +1,39 @@ +exports[`foo.ini > decode from file 1`] = ` +{"o":"p","a with spaces":"b c"," xa n p ":"\\"\\r\\nyoyoyo\\r\\r\\n","[disturbing]":"hey you never know","s":"something","s1":"\\"something'","s2":"something else","s3":"","s4":"","s5":" ","s6":" a ","s7":true,"true":true,"false":false,"null":null,"undefined":"undefined","zr":["deedee"],"ar":["one","three","this is included"],"br":"warm","eq":"eq=eq","a":{"av":"a val","e":"{ o: p, a: { av: a val, b: { c: { e: \\"this [value]\\" } } } }","j":"\\"{ o: \\"p\\", a: { av: \\"a val\\", b: { c: { e: \\"this [value]\\" } } } }\\"","[]":"a square?","cr":["four","eight"],"b":{"c":{"e":"1","j":"2"}}},"b":{},"x.y.z":{"x.y.z":"xyz","a.b.c":{"a.b.c":"abc","nocomment":"this; this is not a comment","noHashComment":"this# this is not a comment"}}} +`; + +exports[`foo.ini > encode from data 1`] = ` +"o=p\\na with spaces=b c\\n\\" xa n p \\"=\\"\\\\\\"\\\\r\\\\nyoyoyo\\\\r\\\\r\\\\n\\"\\n\\"[disturbing]\\"=hey you never know\\ns=something\\ns1=\\"something'\\ns2=something else\\ns3=\\ns4=\\ns5=\\" \\"\\ns6=\\" a \\"\\ns7=true\\ntrue=true\\nfalse=false\\nnull=null\\nundefined=undefined\\nzr[]=deedee\\nar[]=one\\nar[]=three\\nar[]=this is included\\nbr=warm\\neq=\\"eq=eq\\"\\n\\n[a]\\nav=a val\\ne={ o: p, a: { av: a val, b: { c: { e: \\"this [value]\\" } } } }\\nj=\\"\\\\\\"{ o: \\\\\\"p\\\\\\", a: { av: \\\\\\"a val\\\\\\", b: { c: { e: \\\\\\"this [value]\\\\\\" } } } }\\\\\\"\\"\\n\\"[]\\"=a square?\\ncr[]=four\\ncr[]=eight\\n\\n[a.b.c]\\ne=1\\nj=2\\n\\n[x\\\\.y\\\\.z]\\nx.y.z=xyz\\n\\n[x\\\\.y\\\\.z.a\\\\.b\\\\.c]\\na.b.c=abc\\nnocomment=this\\\\; this is not a comment\\nnoHashComment=this\\\\# this is not a comment\\n" +`; + +exports[`foo.ini > encode with align 1`] = ` +"o = p\\na with spaces = b c\\n\\" xa n p \\" = \\"\\\\\\"\\\\r\\\\nyoyoyo\\\\r\\\\r\\\\n\\"\\n\\"[disturbing]\\" = hey you never know\\ns = something\\ns1 = \\"something'\\ns2 = something else\\ns3 = \\ns4 = \\ns5 = \\" \\"\\ns6 = \\" a \\"\\ns7 = true\\ntrue = true\\nfalse = false\\nnull = null\\nundefined = undefined\\nzr[] = deedee\\nar[] = one\\nar[] = three\\nar[] = this is included\\nbr = warm\\neq = \\"eq=eq\\"\\n\\n[a]\\nav = a val\\ne = { o: p, a: { av: a val, b: { c: { e: \\"this [value]\\" } } } }\\nj = \\"\\\\\\"{ o: \\\\\\"p\\\\\\", a: { av: \\\\\\"a val\\\\\\", b: { c: { e: \\\\\\"this [value]\\\\\\" } } } }\\\\\\"\\"\\n\\"[]\\" = a square?\\ncr[] = four\\ncr[] = eight\\n\\n[a.b.c]\\ne = 1\\nj = 2\\n\\n[x\\\\.y\\\\.z]\\nx.y.z = xyz\\n\\n[x\\\\.y\\\\.z.a\\\\.b\\\\.c]\\na.b.c = abc\\nnocomment = this\\\\; this is not a comment\\nnoHashComment = this\\\\# this is not a comment\\n" +`; + +exports[`foo.ini > encode with align and sort 1`] = ` +"\\" xa n p \\" = \\"\\\\\\"\\\\r\\\\nyoyoyo\\\\r\\\\r\\\\n\\"\\n\\"[disturbing]\\" = hey you never know\\na with spaces = b c\\nar[] = one\\nar[] = three\\nar[] = this is included\\nbr = warm\\neq = \\"eq=eq\\"\\nfalse = false\\nnull = null\\no = p\\ns = something\\ns1 = \\"something'\\ns2 = something else\\ns3 = \\ns4 = \\ns5 = \\" \\"\\ns6 = \\" a \\"\\ns7 = true\\ntrue = true\\nundefined = undefined\\nzr[] = deedee\\n\\n[a]\\n\\"[]\\" = a square?\\nav = a val\\ncr[] = four\\ncr[] = eight\\ne = { o: p, a: { av: a val, b: { c: { e: \\"this [value]\\" } } } }\\nj = \\"\\\\\\"{ o: \\\\\\"p\\\\\\", a: { av: \\\\\\"a val\\\\\\", b: { c: { e: \\\\\\"this [value]\\\\\\" } } } }\\\\\\"\\"\\n\\n[a.b.c]\\ne = 1\\nj = 2\\n\\n[x\\\\.y\\\\.z]\\nx.y.z = xyz\\n\\n[x\\\\.y\\\\.z.a\\\\.b\\\\.c]\\na.b.c = abc\\nnoHashComment = this\\\\# this is not a comment\\nnocomment = this\\\\; this is not a comment\\n" +`; + +exports[`foo.ini > encode with newline 1`] = ` +"[log]\\n\\ntype=file\\n\\n[log.level]\\n\\nlabel=debug\\nvalue=10\\n" +`; + +exports[`foo.ini > encode with option 1`] = ` +"[prefix.log]\\ntype=file\\n\\n[prefix.log.level]\\nlabel=debug\\nvalue=10\\n" +`; + +exports[`foo.ini > encode with platform=win32 1`] = ` +["[log]","type=file","","[log.level]","label=debug","value=10",""] +`; + +exports[`foo.ini > encode with sort 1`] = ` +"\\" xa n p \\"=\\"\\\\\\"\\\\r\\\\nyoyoyo\\\\r\\\\r\\\\n\\"\\n\\"[disturbing]\\"=hey you never know\\na with spaces=b c\\nar[]=one\\nar[]=three\\nar[]=this is included\\nbr=warm\\neq=\\"eq=eq\\"\\nfalse=false\\nnull=null\\no=p\\ns=something\\ns1=\\"something'\\ns2=something else\\ns3=\\ns4=\\ns5=\\" \\"\\ns6=\\" a \\"\\ns7=true\\ntrue=true\\nundefined=undefined\\nzr[]=deedee\\n\\n[a]\\n\\"[]\\"=a square?\\nav=a val\\ncr[]=four\\ncr[]=eight\\ne={ o: p, a: { av: a val, b: { c: { e: \\"this [value]\\" } } } }\\nj=\\"\\\\\\"{ o: \\\\\\"p\\\\\\", a: { av: \\\\\\"a val\\\\\\", b: { c: { e: \\\\\\"this [value]\\\\\\" } } } }\\\\\\"\\"\\n\\n[a.b.c]\\ne=1\\nj=2\\n\\n[x\\\\.y\\\\.z]\\nx.y.z=xyz\\n\\n[x\\\\.y\\\\.z.a\\\\.b\\\\.c]\\na.b.c=abc\\nnoHashComment=this\\\\# this is not a comment\\nnocomment=this\\\\; this is not a comment\\n" +`; + +exports[`foo.ini > encode with whitespace 1`] = ` +"[log]\\ntype = file\\n\\n[log.level]\\nlabel = debug\\nvalue = 10\\n" +`; + +exports[`foo.ini > encode within browser context 1`] = ` +"[log]\\ntype=file\\n\\n[log.level]\\nlabel=debug\\nvalue=10\\n" +`; diff --git a/test/proto.js b/test/proto.js index a70a4ee..33cd8a5 100644 --- a/test/proto.js +++ b/test/proto.js @@ -1,8 +1,9 @@ /* eslint no-proto: "off" */ -var ini = require('../') -var t = require('tap') +const t = require('node:test') +const a = require('node:assert') +const ini = require('../') -var data = ` +const data = ` __proto__ = quux constructor.prototype.foo = asdfasdf foo = baz @@ -21,39 +22,41 @@ thanks = true foo = asdfasdf ` -var res = ini.parse(data) +const res = ini.parse(data) -t.same(res, Object.assign(Object.create(null), { - 'constructor.prototype.foo': 'asdfasdf', - foo: 'baz', - other: Object.assign(Object.create(null), { - foo: 'asdf', - }), - kid: Object.assign(Object.create(null), { - foo: Object.assign(Object.create(null), { - foo: 'kid', +t.test('proto', () => { + a.deepEqual(res, Object.assign(Object.create(null), { + 'constructor.prototype.foo': 'asdfasdf', + foo: 'baz', + other: Object.assign(Object.create(null), { + foo: 'asdf', }), - }), - arrproto: Object.assign(Object.create(null), { - hello: 'snyk', - thanks: true, - }), - ctor: Object.assign(Object.create(null), { - constructor: Object.assign(Object.create(null), { - prototype: Object.assign(Object.create(null), { - foo: 'asdfasdf', + kid: Object.assign(Object.create(null), { + foo: Object.assign(Object.create(null), { + foo: 'kid', }), }), - }), -})) -t.equal(res.__proto__, undefined) -t.equal(res.kid.__proto__, undefined) -t.equal(res.kid.foo.__proto__, undefined) -t.equal(res.arrproto.__proto__, undefined) -t.equal(Object.prototype.foo, undefined) -t.equal(Object.prototype[0], undefined) -t.equal(Object.prototype['0'], undefined) -t.equal(Object.prototype[1], undefined) -t.equal(Object.prototype['1'], undefined) -t.equal(Array.prototype[0], undefined) -t.equal(Array.prototype[1], undefined) + arrproto: Object.assign(Object.create(null), { + hello: 'snyk', + thanks: true, + }), + ctor: Object.assign(Object.create(null), { + constructor: Object.assign(Object.create(null), { + prototype: Object.assign(Object.create(null), { + foo: 'asdfasdf', + }), + }), + }), + })) + a.equal(res.__proto__, undefined) + a.equal(res.kid.__proto__, undefined) + a.equal(res.kid.foo.__proto__, undefined) + a.equal(res.arrproto.__proto__, undefined) + a.equal(Object.prototype.foo, undefined) + a.equal(Object.prototype[0], undefined) + a.equal(Object.prototype['0'], undefined) + a.equal(Object.prototype[1], undefined) + a.equal(Object.prototype['1'], undefined) + a.equal(Array.prototype[0], undefined) + a.equal(Array.prototype[1], undefined) +}) diff --git a/test/win32.js b/test/win32.js index 2564396..409073c 100644 --- a/test/win32.js +++ b/test/win32.js @@ -1,22 +1,25 @@ -var t = require('tap') +const t = require('node:test') +const a = require('node:assert') Object.defineProperty(process, 'platform', { value: 'win32' }) const ini = require('..') -const res = ini.encode({ foo: { bar: 'baz' } }) -t.equal(res, '[foo]\r\nbar=baz\r\n') +t.test('win32', () => { + const res = ini.encode({ foo: { bar: 'baz' } }) + a.equal(res, '[foo]\r\nbar=baz\r\n') -t.equal(ini.encode({ bar: 'baz' }, 'foo'), '[foo]\r\nbar=baz\r\n') + a.equal(ini.encode({ bar: 'baz' }, 'foo'), '[foo]\r\nbar=baz\r\n') -t.same(ini.decode('=just junk!\r\n[foo]\r\nbar\r\n'), - { foo: { bar: true } }) + a.deepEqual(ini.decode('=just junk!\r\n[foo]\r\nbar\r\n'), + { foo: { bar: true } }) -t.same(ini.decode('[x]\r\ny=1\r\ny[]=2\r\n'), { - x: { - y: [1, 2], - }, -}) + a.deepEqual(ini.decode('[x]\r\ny=1\r\ny[]=2\r\n'), { + x: { + y: [1, 2], + }, + }) -t.equal(ini.unsafe(''), '') -t.equal(ini.unsafe('x;y'), 'x') -t.equal(ini.unsafe('x # y'), 'x') -t.equal(ini.unsafe('x "\\'), 'x "\\') + a.equal(ini.unsafe(''), '') + a.equal(ini.unsafe('x;y'), 'x') + a.equal(ini.unsafe('x # y'), 'x') + a.equal(ini.unsafe('x "\\'), 'x "\\') +})