# JSON Validation Test Cases [![Validate JSON test cases](https://github.com/UtilHatch/json-validation-test-cases/actions/workflows/validate.yml/badge.svg)](https://github.com/UtilHatch/json-validation-test-cases/actions/workflows/validate.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) A focused collection of valid, invalid, and edge-case JSON test cases for parsers, validators, editors, APIs, syntax highlighting, and error handling. ## Why this exists Happy-path JSON samples do not exercise diagnostics, strictness, numeric limits, Unicode handling, or interoperability hazards. This repository keeps those inputs small, named, documented, and machine-indexed so they can be reused in unit tests, compatibility suites, editor demos, and regression tests. The suite tests selected syntax and implementation boundaries. It is not a certification suite and does not claim exhaustive RFC coverage. ## Contents ```text valid/ Strict JSON inputs expected to parse invalid/ Deliberately malformed inputs expected to fail edge-cases/ Valid inputs with implementation or interoperability concerns scripts/ Dependency-free validation and test-case generation tools test-cases.json Machine-readable test-case manifest ``` Invalid subdirectories include short notes explaining the grammar error, common causes, and included files. ## Quick start Node.js 22 or newer is required for the repository scripts. The test cases themselves have no runtime dependency. ```sh git clone https://github.com/UtilHatch/json-validation-test-cases.git cd json-validation-test-cases npm test ``` The validator resolves paths from its own location, so `node /path/to/repository/scripts/validate.js` also works from another working directory. It confirms that the manifest and filesystem agree, accepted cases parse, and rejected cases throw in `JSON.parse`. ## Test-case categories - **Valid** test cases are JSON texts a strict parser should accept, including primitive root values. Their manifest expectation is `accept`. - **Invalid** test cases intentionally violate JSON grammar. Their expectation is `reject`; do not run a formatter over them. - **Edge cases** are generally syntactically valid JSON but may lose precision, exceed numeric ranges, trigger depth limits, normalize differently, or produce surprising downstream behavior. Their expectation is `implementation-dependent` so the validator reports them separately. Duplicate names in an object are an important example: many parsers accept them and retain one value, but RFC 8259 describes behavior as unpredictable when names are not unique. Likewise, `9007199254740993` is valid JSON, but JavaScript's binary `Number` type cannot represent that integer exactly because it exceeds `Number.MAX_SAFE_INTEGER`. ## Manifest [`test-cases.json`](test-cases.json) lists every test case exactly once. Each entry has a stable ID, relative path, category, subcategory, title, description, expectation, standards context, and notes. Entries are sorted by path, making diffs predictable. ### Node.js example ```js const fs = require('node:fs'); const path = require('node:path'); const root = process.cwd(); const cases = JSON.parse(fs.readFileSync(path.join(root, 'test-cases.json'), 'utf8')); for (const testCase of cases.filter((item) => item.expected === 'accept')) { const source = fs.readFileSync(path.join(root, testCase.path), 'utf8'); JSON.parse(source); console.log(`accepted ${testCase.id}`); } ``` ### Go example ```go package main import ( "encoding/json" "fmt" "os" ) func main() { data, err := os.ReadFile("valid/objects/simple-object.json") if err != nil { panic(err) } var value any if err := json.Unmarshal(data, &value); err != nil { panic(err) } fmt.Printf("%#v\n", value) } ``` Use the manifest rather than relying on directory names when a test runner needs expected outcomes or metadata. ## Deep-nesting generator Regenerate the tracked 100-level test case: ```sh npm run generate:deep ``` Pass a depth from 1 through 10,000 after `--`: ```sh npm run generate:deep -- 250 ``` Non-default depths create `edge-cases/nesting/deep-.json`; add a matching manifest entry before committing. The upper bound prevents accidentally allocating an unreasonably large test case. ## Standards and behavior The syntax expectations are based on [RFC 8259](https://www.rfc-editor.org/rfc/rfc8259) and [ECMA-404](https://ecma-international.org/publications-and-standards/standards/ecma-404/). Syntax validity does not guarantee identical in-memory values across languages. Number range and precision, duplicate-member handling, Unicode comparison, maximum nesting, resource limits, and mapping into native objects are implementation concerns. Some ecosystems support JSON-derived formats such as JSON5 or JSONC. Accepting comments, trailing commas, or single quotes in such a mode does not make those inputs valid JSON. ## Contributing Read [CONTRIBUTING.md](CONTRIBUTING.md) before adding a test case. A contribution should cover a distinct behavior, use a descriptive filename, update the manifest, document parser-specific results when relevant, and pass `npm test`. ## Try interactively For manual inspection, paste a test case into UtilHatch's [JSON Array Validator](https://utilhatch.com/json-array-validator/). These browser tools are convenient for exploring diagnostics; automated assertions should still use the parser and configuration relevant to your application. ## License Released under the [MIT License](LICENSE).