mirror of
https://github.com/tauri-apps/tauri-toml.git
synced 2026-02-04 02:11:18 +01:00
chore(tests): Extern spec tests and normalize test suite running
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ node_modules
|
||||
coverage
|
||||
benchmark-results.json
|
||||
test/burntsushi-toml-test/
|
||||
test/spec-test/
|
||||
|
||||
@@ -4,7 +4,7 @@ BurntSushi tests are for TOML 0.4.0 and are from <a href="https://github.com/Bur
|
||||
iarna tests are for TOML 0.5.0 and are from <a href="https://github.com/iarna/iarna-toml/tree/cmc/test/spec-test">here</a>.<br>
|
||||
<br>
|
||||
<table>
|
||||
<tr><th>Test</th><th>@iarna/toml @2.1.0</th><th>toml @2.3.3</th><th>toml-j0.4 @1.1.1</th><th>@sgarciac/bombadil @2.0.0-0</th></tr>
|
||||
<tr><th>Test</th><th>@iarna/toml @2.1.1</th><th>toml @2.3.3</th><th>toml-j0.4 @1.1.1</th><th>@sgarciac/bombadil @2.0.0-0</th></tr>
|
||||
|
||||
<tr><td>BurntSushi 0.4.0: array-empty</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
@@ -63,6 +63,9 @@ iarna tests are for TOML 0.5.0 and are from <a href="https://github.com/iarna/ia
|
||||
<tr><td>BurntSushi 0.4.0: example</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: exponent-part-float</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: float-exponent</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
@@ -81,6 +84,9 @@ iarna tests are for TOML 0.5.0 and are from <a href="https://github.com/iarna/ia
|
||||
<tr><td>BurntSushi 0.4.0: implicit-groups</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: inline-table-array</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: inline-table</td>
|
||||
<td class="pass">pass</td><td class="fail"><b>FAIL</b></td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
@@ -114,6 +120,12 @@ iarna tests are for TOML 0.5.0 and are from <a href="https://github.com/iarna/ia
|
||||
<tr><td>BurntSushi 0.4.0: multiline-string</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: newline-crlf</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: newline-lf</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: raw-multiline-string</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
@@ -171,6 +183,12 @@ iarna tests are for TOML 0.5.0 and are from <a href="https://github.com/iarna/ia
|
||||
<tr><td>BurntSushi 0.4.0: table-with-single-quotes</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td><td class="pass">pass</td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: underscored-float</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: underscored-integer</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: unicode-escape</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
</tr>
|
||||
@@ -297,15 +315,24 @@ iarna tests are for TOML 0.5.0 and are from <a href="https://github.com/iarna/ia
|
||||
<tr><td>BurntSushi 0.4.0: should throw: llbrace</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: should throw: multi-line-inline-table</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: should throw: rrbrace</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: should throw: string-bad-byte-escape</td>
|
||||
<td class="pass">pass</td><td class="fail"><b>FAIL</b></td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: should throw: string-bad-codepoint</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: should throw: string-bad-escape</td>
|
||||
<td class="pass">pass</td><td class="fail"><b>FAIL</b></td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: should throw: string-bad-slash-escape</td>
|
||||
<td class="pass">pass</td><td class="fail"><b>FAIL</b></td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>BurntSushi 0.4.0: should throw: string-bad-uni-esc</td>
|
||||
<td class="pass">pass</td><td class="fail"><b>FAIL</b></td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
@@ -697,7 +724,7 @@ iarna tests are for TOML 0.5.0 and are from <a href="https://github.com/iarna/ia
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>iarna 0.5.0: should throw: multiple-dot-key</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>iarna 0.5.0: should throw: multiple-key</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
@@ -730,19 +757,19 @@ iarna tests are for TOML 0.5.0 and are from <a href="https://github.com/iarna/ia
|
||||
<td class="pass">pass</td><td class="fail"><b>FAIL</b></td><td class="fail"><b>FAIL</b></td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>iarna 0.5.0: should throw: string-basic-multiline-out-of-range-unicode-escape-1</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>iarna 0.5.0: should throw: string-basic-multiline-out-of-range-unicode-escape-2</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>iarna 0.5.0: should throw: string-basic-multiline-unknown-escape</td>
|
||||
<td class="pass">pass</td><td class="fail"><b>FAIL</b></td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>iarna 0.5.0: should throw: string-basic-out-of-range-unicode-escape-1</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>iarna 0.5.0: should throw: string-basic-out-of-range-unicode-escape-2</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td>
|
||||
<td class="pass">pass</td><td class="pass">pass</td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
</tr>
|
||||
<tr><td>iarna 0.5.0: should throw: string-basic-unknown-escape</td>
|
||||
<td class="pass">pass</td><td class="fail"><b>FAIL</b></td><td class="pass">pass</td><td class="fail"><b>FAIL</b></td>
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
"pretest": "standard",
|
||||
"update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'",
|
||||
"update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'",
|
||||
"setup-optional-toml-suite": "[ -d test/burntsushi-toml-test ] || (git clone https://github.com/BurntSushi/toml-test test/burntsushi-toml-test; rimraf test/burntsushi-toml-test/.git/hooks/*); cd test/burntsushi-toml-test; git pull",
|
||||
"prepare": "npm run setup-optional-toml-suite"
|
||||
"setup-burntsushi-toml-suite": "[ -d test/burntsushi-toml-test ] || (git clone https://github.com/BurntSushi/toml-test test/burntsushi-toml-test; rimraf test/burntsushi-toml-test/.git/hooks/*); cd test/burntsushi-toml-test; git pull",
|
||||
"setup-iarna-toml-suite": "[ -d test/spec-test ] || (git clone https://github.com/iarna/toml-spec-tests -b 0.5.0 test/spec-test; rimraf test/spec-test/.git/hooks/*); cd test/spec-test; git pull",
|
||||
"prepare": "npm run setup-burntsushi-toml-suite && npm run setup-iarna-toml-suite"
|
||||
},
|
||||
"keywords": [
|
||||
"toml",
|
||||
|
||||
@@ -1,126 +1,43 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const t = require('tap')
|
||||
const glob = require('glob').sync
|
||||
const fs = require('fs')
|
||||
const tests = glob(`${__dirname}/../test/burntsushi-toml-test/tests/valid/*toml`)
|
||||
const errorAsserts = glob(`${__dirname}/../test/burntsushi-toml-test/tests/invalid/*toml`)
|
||||
const createDatetime = require('../lib/create-datetime.js')
|
||||
const TomlError = require('../lib/toml-parser.js').TomlError
|
||||
const testParser = require('../test/lib/test-parser.js')
|
||||
|
||||
const iarnaToml = require('../parse-string.js')
|
||||
const TomlSyntaxError = require('toml').SyntaxError
|
||||
const parseToml = require('toml').parse
|
||||
const Tomlj04SyntaxError = require('toml-j0.4').SyntaxError
|
||||
const parseTomlj04 = require('toml-j0.4').parse
|
||||
const bombadil = require('@sgarciac/bombadil')
|
||||
function parseBombadil (str) {
|
||||
const reader = new bombadil.TomlReader()
|
||||
reader.readToml(str)
|
||||
if (reader.result === null) throw reader.errors
|
||||
return reader.result
|
||||
}
|
||||
|
||||
const parsers = {
|
||||
'@iarna/toml@2.1.0': iarnaToml,
|
||||
'toml@2.3.3': parseToml,
|
||||
'toml-j0.4@1.1.1': parseTomlj04,
|
||||
'@sgarciac/bombadil@2.0.0-0': parseBombadil
|
||||
}
|
||||
class BombadilError extends Error {}
|
||||
|
||||
function isObjectDeeply (aa, bb) {
|
||||
if (typeof aa !== typeof bb) return false
|
||||
if (aa == null || bb == null || typeof aa !== 'object') return Object.is(aa, bb)
|
||||
if (Array.isArray(aa) && Array.isArray(bb)) return isArrayDeeply(aa, bb)
|
||||
if (Array.isArray(aa) || Array.isArray(bb)) return false
|
||||
if (aa instanceof Date && bb instanceof Date) return aa.toISOString() === bb.toISOString()
|
||||
let aaKeys = Object.keys(aa)
|
||||
let bbKeys = Object.keys(bb)
|
||||
if (aaKeys.length !== bbKeys.length) return false
|
||||
for (let key of aaKeys) {
|
||||
if (bbKeys.indexOf(key) === -1) return false
|
||||
if (!isObjectDeeply(aa[key], bb[key])) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function isArrayDeeply (aa, bb) {
|
||||
if (aa.length !== bb.length) return false
|
||||
for (let ii = 0; ii < aa.length; ++ii) {
|
||||
if (!isObjectDeeply(aa[ii], bb[ii])) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
t.Test.prototype.addAssert('deeplyObjectIs', 2, function (found, wanted, message, extra) {
|
||||
return this.ok(isObjectDeeply(found, wanted), message, extra)
|
||||
})
|
||||
|
||||
function expand (obj) {
|
||||
const result = {}
|
||||
Object.keys(obj).forEach(key => {
|
||||
result[key] = expandValue(obj[key])
|
||||
})
|
||||
return result
|
||||
}
|
||||
function expandValue (val) {
|
||||
if (Array.isArray(val)) {
|
||||
return val.map(_ => expandValue(_))
|
||||
} else if (val.type === 'array') {
|
||||
return val.value.map(_ => expandValue(_))
|
||||
} else if (val.type === 'datetime') {
|
||||
return createDatetime(val.value)
|
||||
} else if (val.type === 'string') {
|
||||
return val.value
|
||||
} else if (val.type === 'float') {
|
||||
return Number(val.value)
|
||||
} else if (val.type === 'integer') {
|
||||
if (global.BigInt && !Number.isSafeInteger(Number(val.value))) {
|
||||
return global.BigInt(val.value)
|
||||
} else {
|
||||
return Number(val.value)
|
||||
const toTest = [
|
||||
{
|
||||
name: '@iarna/toml@2.1.1',
|
||||
parse: iarnaToml,
|
||||
ErrorClass: TomlError
|
||||
},
|
||||
{
|
||||
name: 'toml@2.3.3',
|
||||
ErrorClass: TomlSyntaxError,
|
||||
parse: parseToml
|
||||
},
|
||||
{
|
||||
name: 'toml-j0.4@1.1.1',
|
||||
ErrorClass: Tomlj04SyntaxError,
|
||||
parse: parseTomlj04
|
||||
},
|
||||
{
|
||||
name: '@sgarciac/bombadil@2.0.0-0',
|
||||
ErrorClass: BombadilError,
|
||||
parse: str => {
|
||||
// this is assuming that readToml should never throw
|
||||
const reader = new bombadil.TomlReader()
|
||||
reader.readToml(str)
|
||||
if (reader.result === null) throw new BombadilError(reader.errors)
|
||||
return reader.result
|
||||
}
|
||||
} else if (val.type === 'bool') {
|
||||
return val.value === 'true'
|
||||
} else if (!('type' in val)) {
|
||||
return expand(val)
|
||||
} else {
|
||||
throw new Error('Unknown type: ' + val.type)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
function getExpected (spec) {
|
||||
const jsonName = spec.replace(/[.]toml$/, '.json')
|
||||
if (fs.existsSync(jsonName)) {
|
||||
const expected = JSON.parse(fs.readFileSync(jsonName))
|
||||
return expand(expected)
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(parsers).forEach(name => {
|
||||
const parse = parsers[name]
|
||||
|
||||
t.test(name, t => {
|
||||
t.test('burnt-sushi-toml-tests-valid', t => {
|
||||
t.plan(tests.length)
|
||||
for (let spec of tests) {
|
||||
const rawToml = fs.readFileSync(spec, 'utf8')
|
||||
const expected = getExpected(spec)
|
||||
const name = path.basename(spec, '.toml')
|
||||
try {
|
||||
t.deeplyObjectIs(parse(rawToml), expected, name)
|
||||
} catch (ex) {
|
||||
t.error(ex, name)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.test('burnt-sushi-toml-tests-invalid', t => {
|
||||
t.plan(errorAsserts.length)
|
||||
for (let spec of errorAsserts) {
|
||||
const rawToml = fs.readFileSync(spec, 'utf8')
|
||||
const name = 'should throw: ' + path.basename(spec, '.toml')
|
||||
t.throws(() => t.comment(parse(rawToml)), name)
|
||||
}
|
||||
})
|
||||
t.done()
|
||||
})
|
||||
})
|
||||
testParser(toTest, `${__dirname}/../test/burntsushi-toml-test/tests/valid`, `${__dirname}/../test/burntsushi-toml-test/tests/invalid`)
|
||||
|
||||
@@ -1,99 +1,39 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const t = require('tap')
|
||||
const glob = require('glob').sync
|
||||
const fs = require('fs')
|
||||
const tests = glob(`${__dirname}/../test/spec-test/*toml`)
|
||||
const errorAsserts = glob(`${__dirname}/../test/spec-test/errors/*toml`)
|
||||
const YAML = require('js-yaml')
|
||||
const TomlError = require('../lib/toml-parser.js').TomlError
|
||||
const testParser = require('../test/lib/test-parser.js')
|
||||
|
||||
const iarnaToml = require('../parse-string.js')
|
||||
const parseToml = require('toml').parse
|
||||
const parseTomlj04 = require('toml-j0.4').parse
|
||||
const bombadil = require('@sgarciac/bombadil')
|
||||
function parseBombadil (str) {
|
||||
const reader = new bombadil.TomlReader()
|
||||
reader.readToml(str)
|
||||
if (reader.result === null) throw reader.errors
|
||||
return reader.result
|
||||
}
|
||||
|
||||
const parsers = {
|
||||
'@iarna/toml@2.1.0': iarnaToml,
|
||||
'toml@2.3.3': parseToml,
|
||||
'toml-j0.4@1.1.1': parseTomlj04,
|
||||
'@sgarciac/bombadil@2.0.0-0': parseBombadil
|
||||
}
|
||||
class BombadilError extends Error {}
|
||||
|
||||
function isObjectDeeply (aa, bb) {
|
||||
if (typeof aa !== typeof bb) return false
|
||||
if (aa == null || bb == null || typeof aa !== 'object') return Object.is(aa, bb)
|
||||
if (Array.isArray(aa) && Array.isArray(bb)) return isArrayDeeply(aa, bb)
|
||||
if (Array.isArray(aa) || Array.isArray(bb)) return false
|
||||
if (aa instanceof Date && bb instanceof Date) return aa.toISOString() === bb.toISOString()
|
||||
let aaKeys = Object.keys(aa)
|
||||
let bbKeys = Object.keys(bb)
|
||||
if (aaKeys.length !== bbKeys.length) return false
|
||||
for (let key of aaKeys) {
|
||||
if (bbKeys.indexOf(key) === -1) return false
|
||||
if (!isObjectDeeply(aa[key], bb[key])) return false
|
||||
const toTest = [
|
||||
{
|
||||
name: '@iarna/toml@2.1.1',
|
||||
parse: iarnaToml,
|
||||
ErrorClass: TomlError
|
||||
},
|
||||
{
|
||||
name: 'toml@2.3.3',
|
||||
parse: parseToml
|
||||
},
|
||||
{
|
||||
name: 'toml-j0.4@1.1.1',
|
||||
parse: parseTomlj04
|
||||
},
|
||||
{
|
||||
name: '@sgarciac/bombadil@2.0.0-0',
|
||||
ErrorClass: BombadilError,
|
||||
parse: str => {
|
||||
// this is assuming that readToml should never throw
|
||||
const reader = new bombadil.TomlReader()
|
||||
reader.readToml(str)
|
||||
if (reader.result === null) throw new BombadilError(reader.errors)
|
||||
return reader.result
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
]
|
||||
|
||||
function isArrayDeeply (aa, bb) {
|
||||
if (aa.length !== bb.length) return false
|
||||
for (let ii = 0; ii < aa.length; ++ii) {
|
||||
if (!isObjectDeeply(aa[ii], bb[ii])) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
t.Test.prototype.addAssert('deeplyObjectIs', 2, function (found, wanted, message, extra) {
|
||||
return this.ok(isObjectDeeply(found, wanted), message, extra)
|
||||
})
|
||||
|
||||
function getExpected (spec) {
|
||||
const yamlName = spec.replace(/[.]toml$/, '.yaml')
|
||||
const jsName = spec.replace(/[.]toml$/, '.js')
|
||||
if (fs.existsSync(yamlName)) {
|
||||
return YAML.safeLoad(fs.readFileSync(yamlName))
|
||||
} else if (fs.existsSync(jsName)) {
|
||||
return require(jsName)
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(parsers).forEach(name => {
|
||||
const parse = parsers[name]
|
||||
|
||||
t.test(name, t => {
|
||||
t.test('spec-asserts', t => {
|
||||
t.plan(tests.length)
|
||||
for (let spec of tests) {
|
||||
const rawToml = fs.readFileSync(spec, 'utf8')
|
||||
const expected = getExpected(spec)
|
||||
const name = path.basename(spec, '.toml')
|
||||
try {
|
||||
if (expected.type === 'date-time') {
|
||||
t.is(parse(rawToml)[expected.property].toISOString(), expected.value, name)
|
||||
} else {
|
||||
t.deeplyObjectIs(parse(rawToml), expected, name)
|
||||
}
|
||||
} catch (ex) {
|
||||
t.error(ex, name)
|
||||
}
|
||||
}
|
||||
})
|
||||
t.test('spec-error-asserts', t => {
|
||||
t.plan(errorAsserts.length)
|
||||
for (let spec of errorAsserts) {
|
||||
const rawToml = fs.readFileSync(spec, 'utf8')
|
||||
const name = 'should throw: ' + path.basename(spec, '.toml')
|
||||
t.throws(() => t.comment(parse(rawToml)), name)
|
||||
}
|
||||
})
|
||||
t.done()
|
||||
})
|
||||
})
|
||||
testParser(toTest, `${__dirname}/../test/spec-test/values`, `${__dirname}/../test/spec-test/errors`)
|
||||
|
||||
@@ -2,16 +2,16 @@ const qx = require('@perl/qx').sync
|
||||
const data = JSON.parse(qx`npx tap ${__dirname}/burntsushi-toml-test.js ${__dirname}/local-spec-test.js -R json`)
|
||||
|
||||
const labels = {
|
||||
'spec-asserts': 'iarna 0.5.0',
|
||||
'spec-error-asserts': 'iarna 0.5.0',
|
||||
'burnt-sushi-toml-tests-valid': 'BurntSushi 0.4.0',
|
||||
'burnt-sushi-toml-tests-invalid': 'BurntSushi 0.4.0'
|
||||
'local-spec-test spec-asserts': 'iarna 0.5.0',
|
||||
'local-spec-test spec-error-asserts': 'iarna 0.5.0',
|
||||
'burntsushi-toml-test spec-asserts': 'BurntSushi 0.4.0',
|
||||
'burntsushi-toml-test spec-error-asserts': 'BurntSushi 0.4.0'
|
||||
}
|
||||
const result = {}
|
||||
|
||||
data.tests.forEach(t => {
|
||||
const [, parser, suite] = /^\S+ (\S+) (\S+)/.exec(t.fullTitle)
|
||||
const title = labels[suite] + ': ' + t.title
|
||||
const [, suitea, parser, suiteb] = /^.*?[/]([^/]+)[.]js (\S+) (\S+)/.exec(t.fullTitle)
|
||||
const title = labels[suitea + ' ' + suiteb] + ': ' + t.title
|
||||
if (!result[title]) result[title] = {}
|
||||
result[title][parser] = !t.err.message
|
||||
})
|
||||
|
||||
@@ -1,108 +1,15 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const t = require('tap')
|
||||
const glob = require('glob').sync
|
||||
const fs = require('fs')
|
||||
const tests = glob(`${__dirname}/burntsushi-toml-test/tests/valid/*toml`)
|
||||
const errorAsserts = glob(`${__dirname}/burntsushi-toml-test/tests/invalid/*toml`)
|
||||
const TOML = require('..')
|
||||
const TomlError = require('../lib/toml-parser.js').TomlError
|
||||
const createDatetime = require('../lib/create-datetime.js')
|
||||
const testParser = require('./lib/test-parser.js')
|
||||
const testStringifier = require('./lib/test-stringifier.js')
|
||||
|
||||
function isObjectDeeply (aa, bb) {
|
||||
if (typeof aa !== typeof bb) return false
|
||||
if (aa == null || bb == null || typeof aa !== 'object') return Object.is(aa, bb)
|
||||
if (Array.isArray(aa) && Array.isArray(bb)) return isArrayDeeply(aa, bb)
|
||||
if (Array.isArray(aa) || Array.isArray(bb)) return false
|
||||
if (aa instanceof Date && bb instanceof Date) return aa.toISOString() === bb.toISOString()
|
||||
let aaKeys = Object.keys(aa)
|
||||
let bbKeys = Object.keys(bb)
|
||||
if (aaKeys.length !== bbKeys.length) return false
|
||||
for (let key of aaKeys) {
|
||||
if (bbKeys.indexOf(key) === -1) return false
|
||||
if (!isObjectDeeply(aa[key], bb[key])) return false
|
||||
}
|
||||
return true
|
||||
const toTest = {
|
||||
name: '@iarna/toml',
|
||||
parse: TOML.parse,
|
||||
stringify: TOML.stringify,
|
||||
ErrorClass: TomlError
|
||||
}
|
||||
|
||||
function isArrayDeeply (aa, bb) {
|
||||
if (aa.length !== bb.length) return false
|
||||
for (let ii = 0; ii < aa.length; ++ii) {
|
||||
if (!isObjectDeeply(aa[ii], bb[ii])) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
t.Test.prototype.addAssert('deeplyObjectIs', 2, function (found, wanted, message, extra) {
|
||||
return this.ok(isObjectDeeply(found, wanted), message, extra)
|
||||
})
|
||||
|
||||
function expand (obj) {
|
||||
const result = {}
|
||||
Object.keys(obj).forEach(key => {
|
||||
result[key] = expandValue(obj[key])
|
||||
})
|
||||
return result
|
||||
}
|
||||
function expandValue (val) {
|
||||
if (Array.isArray(val)) {
|
||||
return val.map(_ => expandValue(_))
|
||||
} else if (val.type === 'array') {
|
||||
return val.value.map(_ => expandValue(_))
|
||||
} else if (val.type === 'datetime') {
|
||||
return createDatetime(val.value)
|
||||
} else if (val.type === 'string') {
|
||||
return val.value
|
||||
} else if (val.type === 'float') {
|
||||
return Number(val.value)
|
||||
} else if (val.type === 'integer') {
|
||||
if (global.BigInt && !Number.isSafeInteger(Number(val.value))) {
|
||||
return global.BigInt(val.value)
|
||||
} else {
|
||||
return Number(val.value)
|
||||
}
|
||||
} else if (val.type === 'bool') {
|
||||
return val.value === 'true'
|
||||
} else if (!('type' in val)) {
|
||||
return expand(val)
|
||||
} else {
|
||||
throw new Error('Unknown type: ' + val.type)
|
||||
}
|
||||
}
|
||||
|
||||
function getExpected (spec) {
|
||||
const jsonName = spec.replace(/[.]toml$/, '.json')
|
||||
if (fs.existsSync(jsonName)) {
|
||||
const expected = JSON.parse(fs.readFileSync(jsonName))
|
||||
return expand(expected)
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
t.test('@iarna/toml', t => {
|
||||
t.test('burnt-sushi-toml-tests-valid', t => {
|
||||
t.plan(tests.length * 2)
|
||||
for (let spec of tests) {
|
||||
const rawToml = fs.readFileSync(spec)
|
||||
const expected = getExpected(spec)
|
||||
const name = path.basename(spec, '.toml')
|
||||
try {
|
||||
t.deeplyObjectIs(TOML.parse(rawToml), expected, name + ' parsed')
|
||||
t.deeplyObjectIs(TOML.parse(TOML.stringify(expected)), expected, name + ' stringify')
|
||||
} catch (ex) {
|
||||
t.error(ex, name)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.test('burnt-sushi-toml-tests-invalid', t => {
|
||||
t.plan(errorAsserts.length)
|
||||
for (let spec of errorAsserts) {
|
||||
const rawToml = fs.readFileSync(spec)
|
||||
const name = 'should throw: ' + path.basename(spec, '.toml')
|
||||
t.throws(() => t.comment(TOML.parse(rawToml)), TomlError, name)
|
||||
}
|
||||
})
|
||||
t.done()
|
||||
})
|
||||
testParser([toTest], `${__dirname}/burntsushi-toml-test/tests/valid`, `${__dirname}/burntsushi-toml-test/tests/invalid`)
|
||||
testStringifier([toTest], `${__dirname}/burntsushi-toml-test/tests/valid`)
|
||||
|
||||
46
test/lib/expand-json.js
Normal file
46
test/lib/expand-json.js
Normal file
@@ -0,0 +1,46 @@
|
||||
'use strict'
|
||||
module.exports = expand
|
||||
const createDatetime = require('../../lib/create-datetime.js')
|
||||
const createDatetimeFloat = require('../../lib/create-datetime-float.js')
|
||||
const createDate = require('../../lib/create-date.js')
|
||||
const createTime = require('../../lib/create-time.js')
|
||||
|
||||
function expand (obj) {
|
||||
const result = {}
|
||||
Object.keys(obj).forEach(key => {
|
||||
result[key] = expandValue(obj[key])
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
function expandValue (val) {
|
||||
if (Array.isArray(val)) {
|
||||
return val.map(_ => expandValue(_))
|
||||
} else if (val.type === 'array') {
|
||||
return val.value.map(_ => expandValue(_))
|
||||
} else if (val.type === 'datetime') {
|
||||
return createDatetime(val.value)
|
||||
} else if (val.type === 'datetime-local') {
|
||||
return createDatetimeFloat(val.value)
|
||||
} else if (val.type === 'date') {
|
||||
return createDate(val.value)
|
||||
} else if (val.type === 'time') {
|
||||
return createTime(val.value)
|
||||
} else if (val.type === 'string') {
|
||||
return val.value
|
||||
} else if (val.type === 'float') {
|
||||
return Number(val.value)
|
||||
} else if (val.type === 'integer') {
|
||||
if (global.BigInt && !Number.isSafeInteger(Number(val.value))) {
|
||||
return global.BigInt(val.value)
|
||||
} else {
|
||||
return Number(val.value)
|
||||
}
|
||||
} else if (val.type === 'bool') {
|
||||
return val.value === 'true'
|
||||
} else if (!('type' in val)) {
|
||||
return expand(val)
|
||||
} else {
|
||||
throw new Error('Unknown type: ' + val.type)
|
||||
}
|
||||
}
|
||||
18
test/lib/get-expected.js
Normal file
18
test/lib/get-expected.js
Normal file
@@ -0,0 +1,18 @@
|
||||
'use strict'
|
||||
module.exports = getExpected
|
||||
const fs = require('fs')
|
||||
const YAML = require('js-yaml')
|
||||
const expand = require('./expand-json.js')
|
||||
|
||||
function getExpected (spec) {
|
||||
const yamlName = spec.replace(/[.]toml$/, '.yaml')
|
||||
const jsonName = spec.replace(/[.]toml$/, '.json')
|
||||
if (fs.existsSync(yamlName)) {
|
||||
return YAML.safeLoad(fs.readFileSync(yamlName))
|
||||
} else if (fs.existsSync(jsonName)) {
|
||||
const expected = JSON.parse(fs.readFileSync(jsonName))
|
||||
return expand(expected)
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
35
test/lib/tap-is-deeply.js
Normal file
35
test/lib/tap-is-deeply.js
Normal file
@@ -0,0 +1,35 @@
|
||||
'use strict'
|
||||
const tap = require('tap')
|
||||
module.exports = tap
|
||||
|
||||
if (!tap.deeplyObjectIs) {
|
||||
tap.Test.prototype.addAssert('deeplyObjectIs', 2, function (found, wanted, message, extra) {
|
||||
const isDeeply = isObjectDeeply(found, wanted)
|
||||
if (!isDeeply) tap.comment(found, wanted)
|
||||
return this.ok(isDeeply, message, extra)
|
||||
})
|
||||
}
|
||||
|
||||
function isObjectDeeply (aa, bb) {
|
||||
if (typeof aa !== typeof bb) return false
|
||||
if (aa == null || bb == null || typeof aa !== 'object') return Object.is(aa, bb)
|
||||
if (Array.isArray(aa) && Array.isArray(bb)) return isArrayDeeply(aa, bb)
|
||||
if (Array.isArray(aa) || Array.isArray(bb)) return false
|
||||
if (aa instanceof Date && bb instanceof Date) return aa.toISOString() === bb.toISOString()
|
||||
let aaKeys = Object.keys(aa)
|
||||
let bbKeys = Object.keys(bb)
|
||||
if (aaKeys.length !== bbKeys.length) return false
|
||||
for (let key of aaKeys) {
|
||||
if (bbKeys.indexOf(key) === -1) return false
|
||||
if (!isObjectDeeply(aa[key], bb[key])) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function isArrayDeeply (aa, bb) {
|
||||
if (aa.length !== bb.length) return false
|
||||
for (let ii = 0; ii < aa.length; ++ii) {
|
||||
if (!isObjectDeeply(aa[ii], bb[ii])) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
39
test/lib/test-parser.js
Normal file
39
test/lib/test-parser.js
Normal file
@@ -0,0 +1,39 @@
|
||||
'use strict'
|
||||
module.exports = runTests
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const t = require('./tap-is-deeply.js')
|
||||
const glob = require('glob').sync
|
||||
const getExpected = require('./get-expected.js')
|
||||
|
||||
function runTests (parsers, valid, error) {
|
||||
const tests = glob(`${valid}/*toml`)
|
||||
const errorAsserts = glob(`${error}/*toml`)
|
||||
parsers.forEach(parser => {
|
||||
t.test(parser.name, t => {
|
||||
t.test('spec-asserts', t => {
|
||||
t.plan(tests.length)
|
||||
for (let spec of tests) {
|
||||
const rawToml = fs.readFileSync(spec, 'utf8')
|
||||
const expected = getExpected(spec)
|
||||
const name = path.basename(spec, '.toml')
|
||||
try {
|
||||
t.deeplyObjectIs(parser.parse(rawToml), expected, name)
|
||||
} catch (ex) {
|
||||
t.error(ex, name)
|
||||
}
|
||||
}
|
||||
})
|
||||
t.test('spec-error-asserts', t => {
|
||||
t.plan(errorAsserts.length)
|
||||
for (let spec of errorAsserts) {
|
||||
const rawToml = fs.readFileSync(spec, 'utf8')
|
||||
const name = 'should throw: ' + path.basename(spec, '.toml')
|
||||
t.throws(() => t.comment(parser.parse(rawToml)), parser.ErrorClass, name)
|
||||
}
|
||||
})
|
||||
t.done()
|
||||
})
|
||||
})
|
||||
}
|
||||
30
test/lib/test-stringifier.js
Normal file
30
test/lib/test-stringifier.js
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict'
|
||||
module.exports = runTests
|
||||
|
||||
const path = require('path')
|
||||
const t = require('./tap-is-deeply.js')
|
||||
const glob = require('glob').sync
|
||||
const TOML = require('../..')
|
||||
const getExpected = require('./get-expected.js')
|
||||
|
||||
function runTests (parsers, valid) {
|
||||
const tests = glob(`${valid}/*toml`)
|
||||
|
||||
parsers.forEach(parser => {
|
||||
t.test(parser.name, t => {
|
||||
t.test('stringify-asserts', t => {
|
||||
t.plan(tests.length)
|
||||
for (let spec of tests) {
|
||||
const expected = getExpected(spec)
|
||||
const name = path.basename(spec, '.toml')
|
||||
try {
|
||||
t.deeplyObjectIs(TOML.parse(parser.stringify(expected)), expected, name)
|
||||
} catch (ex) {
|
||||
t.error(ex, name)
|
||||
}
|
||||
}
|
||||
})
|
||||
t.done()
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = "<22>(" #invalid two octet sequence
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = "<22><>" # invalid sequence identifier
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = "<22>(<28>" # invalid 3 octet sequence (in 2nd octet)
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = "<22><>(" # invalid 3 octet sequence (in 3rd octet)
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = """<22>(""" #invalid two octet sequence
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = """<22><>""" # invalid sequence identifier
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = """<22>(<28>""" # invalid 3 octet sequence (in 2nd octet)
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = """<22><>(""" # invalid 3 octet sequence (in 3rd octet)
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = '<27>(' #invalid two octet sequence
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = '<27><>' # invalid sequence identifier
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = '<27>(<28>' # invalid 3 octet sequence (in 2nd octet)
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = '<27><>(' # invalid 3 octet sequence (in 3rd octet)
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = '''<27>(''' #invalid two octet sequence
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = '''<27><>''' # invalid sequence identifier
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = '''<27>(<28>''' # invalid 3 octet sequence (in 2nd octet)
|
||||
@@ -1,2 +0,0 @@
|
||||
# A TOML file must be a valid UTF-8 encoded Unicode document.
|
||||
a = '''<27><>(''' # invalid 3 octet sequence (in 3rd octet)
|
||||
@@ -1,79 +1,15 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const t = require('tap')
|
||||
const glob = require('glob').sync
|
||||
const fs = require('fs')
|
||||
const tests = glob(`${__dirname}/spec-test/*toml`)
|
||||
const errorAsserts = glob(`${__dirname}/spec-test/errors/*toml`)
|
||||
const YAML = require('js-yaml')
|
||||
const TOML = require('..')
|
||||
const TomlError = require('../lib/toml-parser.js').TomlError
|
||||
const testParser = require('./lib/test-parser.js')
|
||||
const testStringifier = require('./lib/test-stringifier.js')
|
||||
|
||||
function isObjectDeeply (aa, bb) {
|
||||
if (typeof aa !== typeof bb) return false
|
||||
if (aa == null || bb == null || typeof aa !== 'object') return Object.is(aa, bb)
|
||||
if (Array.isArray(aa) && Array.isArray(bb)) return isArrayDeeply(aa, bb)
|
||||
if (Array.isArray(aa) || Array.isArray(bb)) return false
|
||||
if (aa instanceof Date && bb instanceof Date) return aa.toISOString() === bb.toISOString()
|
||||
let aaKeys = Object.keys(aa)
|
||||
let bbKeys = Object.keys(bb)
|
||||
if (aaKeys.length !== bbKeys.length) return false
|
||||
for (let key of aaKeys) {
|
||||
if (bbKeys.indexOf(key) === -1) return false
|
||||
if (!isObjectDeeply(aa[key], bb[key])) return false
|
||||
}
|
||||
return true
|
||||
const toTest = {
|
||||
name: '@iarna/toml',
|
||||
parse: TOML.parse,
|
||||
stringify: TOML.stringify,
|
||||
ErrorClass: TomlError
|
||||
}
|
||||
|
||||
function isArrayDeeply (aa, bb) {
|
||||
if (aa.length !== bb.length) return false
|
||||
for (let ii = 0; ii < aa.length; ++ii) {
|
||||
if (!isObjectDeeply(aa[ii], bb[ii])) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
t.Test.prototype.addAssert('deeplyObjectIs', 2, function (found, wanted, message, extra) {
|
||||
return this.ok(isObjectDeeply(found, wanted), message, extra)
|
||||
})
|
||||
|
||||
function getExpected (spec) {
|
||||
const yamlName = spec.replace(/[.]toml$/, '.yaml')
|
||||
const jsName = spec.replace(/[.]toml$/, '.js')
|
||||
if (fs.existsSync(yamlName)) {
|
||||
return YAML.safeLoad(fs.readFileSync(yamlName))
|
||||
} else if (fs.existsSync(jsName)) {
|
||||
return require(jsName)
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
t.test('@iarna/toml', t => {
|
||||
t.test('spec-asserts', t => {
|
||||
t.plan(tests.length)
|
||||
for (let spec of tests) {
|
||||
const rawToml = fs.readFileSync(spec)
|
||||
const expected = getExpected(spec)
|
||||
const name = path.basename(spec, '.toml')
|
||||
try {
|
||||
if (expected.type === 'date-time') {
|
||||
t.is(TOML.parse(rawToml)[expected.property].toISOString(), expected.value, name)
|
||||
} else {
|
||||
t.deeplyObjectIs(TOML.parse(rawToml), expected, name)
|
||||
}
|
||||
} catch (ex) {
|
||||
t.error(ex, name)
|
||||
}
|
||||
}
|
||||
})
|
||||
t.test('spec-error-asserts', t => {
|
||||
t.plan(errorAsserts.length)
|
||||
for (let spec of errorAsserts) {
|
||||
const rawToml = fs.readFileSync(spec)
|
||||
const name = 'should throw: ' + path.basename(spec, '.toml')
|
||||
t.throws(() => t.comment(TOML.parse(rawToml)), TomlError, name)
|
||||
}
|
||||
})
|
||||
t.done()
|
||||
})
|
||||
testParser([toTest], `${__dirname}/spec-test/values`, `${__dirname}/spec-test/errors`)
|
||||
testStringifier([toTest], `${__dirname}/spec-test/values`)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
arr1 = [ 1, 2, 3 ]
|
||||
@@ -1 +0,0 @@
|
||||
arr1: [ 1, 2, 3 ]
|
||||
@@ -1 +0,0 @@
|
||||
arr2 = [ "red", "yellow", "green" ]
|
||||
@@ -1 +0,0 @@
|
||||
arr2: [ "red", "yellow", "green" ]
|
||||
@@ -1 +0,0 @@
|
||||
arr3 = [ [ 1, 2 ], [3, 4, 5] ]
|
||||
@@ -1 +0,0 @@
|
||||
arr3: [ [ 1, 2 ], [3, 4, 5] ]
|
||||
@@ -1 +0,0 @@
|
||||
arr4 = [ "all", 'strings', """are the same""", '''type''']
|
||||
@@ -1 +0,0 @@
|
||||
arr4: [ "all", "strings", "are the same", "type" ]
|
||||
@@ -1 +0,0 @@
|
||||
arr5 = [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||
@@ -1 +0,0 @@
|
||||
arr5: [ [ 1, 2 ], ["a", "b", "c"] ]
|
||||
@@ -1,3 +0,0 @@
|
||||
arr7 = [
|
||||
1, 2, 3
|
||||
]
|
||||
@@ -1,3 +0,0 @@
|
||||
arr7: [
|
||||
1, 2, 3
|
||||
]
|
||||
@@ -1,4 +0,0 @@
|
||||
arr8 = [
|
||||
1,
|
||||
2, # this is ok
|
||||
]
|
||||
@@ -1,4 +0,0 @@
|
||||
arr8: [
|
||||
1,
|
||||
2, # this is ok
|
||||
]
|
||||
@@ -1,10 +0,0 @@
|
||||
[[products]]
|
||||
name = "Hammer"
|
||||
sku = 738594937
|
||||
|
||||
[[products]]
|
||||
|
||||
[[products]]
|
||||
name = "Nail"
|
||||
sku = 284758393
|
||||
color = "gray"
|
||||
@@ -1,5 +0,0 @@
|
||||
products: [
|
||||
{name: "Hammer", sku: 738594937},
|
||||
{},
|
||||
{name: "Nail", sku: 284758393, color: "gray" }
|
||||
]
|
||||
@@ -1,18 +0,0 @@
|
||||
[[fruit]]
|
||||
name = "apple"
|
||||
|
||||
[fruit.physical]
|
||||
color = "red"
|
||||
shape = "round"
|
||||
|
||||
[[fruit.variety]]
|
||||
name = "red delicious"
|
||||
|
||||
[[fruit.variety]]
|
||||
name = "granny smith"
|
||||
|
||||
[[fruit]]
|
||||
name = "banana"
|
||||
|
||||
[[fruit.variety]]
|
||||
name = "plantain"
|
||||
@@ -1,19 +0,0 @@
|
||||
fruit: [
|
||||
{
|
||||
name: "apple",
|
||||
physical: {
|
||||
color: "red",
|
||||
shape: "round"
|
||||
},
|
||||
variety: [
|
||||
{ name: "red delicious" },
|
||||
{ name: "granny smith" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "banana",
|
||||
variety: [
|
||||
{ name: "plantain" }
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,3 +0,0 @@
|
||||
points = [ { x = 1, y = 2, z = 3 },
|
||||
{ x = 7, y = 8, z = 9 },
|
||||
{ x = 2, y = 4, z = 8 } ]
|
||||
@@ -1,3 +0,0 @@
|
||||
points: [ { x: 1, y: 2, z: 3 },
|
||||
{ x: 7, y: 8, z: 9 },
|
||||
{ x: 2, y: 4, z: 8 } ]
|
||||
@@ -1 +0,0 @@
|
||||
bool1 = true
|
||||
@@ -1 +0,0 @@
|
||||
bool1: true
|
||||
@@ -1 +0,0 @@
|
||||
bool1 = false
|
||||
@@ -1 +0,0 @@
|
||||
bool1: false
|
||||
@@ -1,3 +0,0 @@
|
||||
# TOML is case sensitive.
|
||||
abc = 123
|
||||
ABC = 456
|
||||
@@ -1,2 +0,0 @@
|
||||
abc: 123
|
||||
ABC: 456
|
||||
@@ -1,6 +0,0 @@
|
||||
# eol commetns can go anywhere
|
||||
abc = [ # this is valid
|
||||
123,#as is this
|
||||
456 #so is this
|
||||
]# and this
|
||||
# here too
|
||||
@@ -1,6 +0,0 @@
|
||||
# eol commetns can go anywhere
|
||||
abc: [ # this is valid
|
||||
123,#as is this
|
||||
456 #so is this
|
||||
]# and this
|
||||
# here too
|
||||
@@ -1,2 +0,0 @@
|
||||
# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
@@ -1,2 +0,0 @@
|
||||
# This is a full-line comment
|
||||
key: "value" # This is a comment at the end of a line
|
||||
@@ -1 +0,0 @@
|
||||
ld1 = 1979-05-27
|
||||
@@ -1,3 +0,0 @@
|
||||
type: 'date-time'
|
||||
property: 'ld1'
|
||||
value: '1979-05-27'
|
||||
@@ -1 +0,0 @@
|
||||
odt1 = 1979-05-27T07:32:00Z
|
||||
@@ -1 +0,0 @@
|
||||
odt1: 1979-05-27T07:32:00Z
|
||||
@@ -1 +0,0 @@
|
||||
odt2 = 1979-05-27T00:32:00-07:00
|
||||
@@ -1 +0,0 @@
|
||||
odt2: 1979-05-27T00:32:00-07:00
|
||||
@@ -1 +0,0 @@
|
||||
odt3 = 1979-05-27T00:32:00.999999-07:00
|
||||
@@ -1 +0,0 @@
|
||||
odt3: 1979-05-27T00:32:00.999999-07:00
|
||||
@@ -1 +0,0 @@
|
||||
odt4 = 1979-05-27 07:32:00Z
|
||||
@@ -1 +0,0 @@
|
||||
odt4: 1979-05-27 07:32:00Z
|
||||
@@ -1 +0,0 @@
|
||||
odt5 = 1979-05-27T07:32:00.123Z
|
||||
@@ -1 +0,0 @@
|
||||
odt5: 1979-05-27T07:32:00.123Z
|
||||
@@ -1 +0,0 @@
|
||||
odt6 = 1979-05-27T07:32:00.1239Z
|
||||
@@ -1 +0,0 @@
|
||||
odt6: 1979-05-27T07:32:00.123Z
|
||||
@@ -1 +0,0 @@
|
||||
ldt1 = 1979-05-27T07:32:00
|
||||
@@ -1,3 +0,0 @@
|
||||
type: 'date-time'
|
||||
property: 'ldt1'
|
||||
value: '1979-05-27T07:32:00.000'
|
||||
@@ -1 +0,0 @@
|
||||
ldt2 = 1979-05-27T00:32:00.999999
|
||||
@@ -1,3 +0,0 @@
|
||||
type: 'date-time'
|
||||
property: 'ldt2'
|
||||
value: '1979-05-27T00:32:00.999'
|
||||
@@ -1,4 +0,0 @@
|
||||
name = "Orange"
|
||||
physical.color = "orange"
|
||||
physical.shape = "round"
|
||||
site."google.com" = true
|
||||
@@ -1,6 +0,0 @@
|
||||
name: "Orange"
|
||||
physical:
|
||||
color: "orange"
|
||||
shape: "round"
|
||||
site:
|
||||
"google.com": true
|
||||
@@ -1 +0,0 @@
|
||||
a . b = 23
|
||||
@@ -1,2 +0,0 @@
|
||||
a:
|
||||
b: 23
|
||||
@@ -1 +0,0 @@
|
||||
a . b = 23
|
||||
@@ -1,2 +0,0 @@
|
||||
a:
|
||||
b: 23
|
||||
@@ -1 +0,0 @@
|
||||
"" = "blank" # VALID but discouraged
|
||||
@@ -1 +0,0 @@
|
||||
"": "blank"
|
||||
@@ -1 +0,0 @@
|
||||
'' = "blank" # VALID but discouraged
|
||||
@@ -1 +0,0 @@
|
||||
"": "blank"
|
||||
@@ -1 +0,0 @@
|
||||
arr6 = [ 1, 2.0 ] # INVALID
|
||||
@@ -1,4 +0,0 @@
|
||||
# INVALID TOML DOC
|
||||
fruit = []
|
||||
|
||||
[[fruit]] # Not allowed
|
||||
@@ -1,10 +0,0 @@
|
||||
# INVALID TOML DOC
|
||||
[[fruit]]
|
||||
name = "apple"
|
||||
|
||||
[[fruit.variety]]
|
||||
name = "red delicious"
|
||||
|
||||
# This table conflicts with the previous table
|
||||
[fruit.variety]
|
||||
name = "granny smith"
|
||||
@@ -1 +0,0 @@
|
||||
bare!key = 123
|
||||
@@ -1,2 +0,0 @@
|
||||
barekey
|
||||
= 123
|
||||
@@ -1 +0,0 @@
|
||||
barekey =
|
||||
@@ -1 +0,0 @@
|
||||
int = 0123
|
||||
@@ -1 +0,0 @@
|
||||
key = # INVALID
|
||||
@@ -1,3 +0,0 @@
|
||||
# THIS IS INVALID
|
||||
a.b = 1
|
||||
a.b.c = 2
|
||||
@@ -1,3 +0,0 @@
|
||||
# DO NOT DO THIS
|
||||
name = "Tom"
|
||||
name = "Pradyun"
|
||||
@@ -1 +0,0 @@
|
||||
= "no key name" # INVALID
|
||||
Binary file not shown.
@@ -1 +0,0 @@
|
||||
a = "null"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user