diff --git a/src/index.ts b/src/index.ts index a8d2873..19a9802 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ import { HTML } from './languages/html'; import { Java } from './languages/java'; import { Javascript } from './languages/javascript'; import { Julia } from './languages/julia'; +import { JSON } from './languages/json'; import { Kotlin } from './languages/kotlin'; import { Lua } from './languages/lua'; import { Markdown } from './languages/markdown'; @@ -37,6 +38,7 @@ const languages: Record = { Java, Javascript, Julia, + JSON, Kotlin, Lua, Markdown, diff --git a/src/languages/json.ts b/src/languages/json.ts new file mode 100644 index 0000000..0e42f5e --- /dev/null +++ b/src/languages/json.ts @@ -0,0 +1,16 @@ +import type { LanguagePattern } from '../types'; + +export const JSON: LanguagePattern[] = [ + // object declaration on top + { pattern: /^\{$/, type: 'meta.module', nearTop: true }, + // normal data type + { pattern: /^\s*".+":\s*(".+"|[0-9]+|null|true|false)(,)?$/, type: 'keyword' }, + // object and array + { pattern: /^\s*".+":\s*(\{|\[)$/, type: 'keyword' }, + // inline key/value pair in object + // e.g { "id": 1, "body": "some comment", "postId": 1 } + { pattern: /^\s*".+":\s*\{(\s*".+":\s*(".+"|[0-9]+|null|true|false)(,)?\s*){1,}\}(,)?$/, type: 'keyword' }, + // inline value in array + // e.g "middlewares": ["./fixtures/middlewares/en", "./fixtures/middlewares/jp"] + { pattern: /\s*".+"\s*\[\s*((".+"|[0-9]+|null|true|false)(,)?\s*){1,}\](,)?$/, type: 'keyword' }, +]; diff --git a/tests/cpp.test.ts b/tests/cpp.test.ts index d9ac51b..31cb480 100644 --- a/tests/cpp.test.ts +++ b/tests/cpp.test.ts @@ -21,6 +21,7 @@ test('hello world', () => { Java: 0, Javascript: 0, Julia: 2, + JSON: 0, Kotlin: 0, Lua: 2, Markdown: 0, diff --git a/tests/cs.test.ts b/tests/cs.test.ts index 9dc2217..1df4873 100644 --- a/tests/cs.test.ts +++ b/tests/cs.test.ts @@ -22,6 +22,7 @@ test('hello world', () => { Java: -40, Javascript: -40, Julia: 5, + JSON: 0, Kotlin: 0, Lua: -20, Markdown: 0, diff --git a/tests/json.test.ts b/tests/json.test.ts new file mode 100644 index 0000000..2ab3a7e --- /dev/null +++ b/tests/json.test.ts @@ -0,0 +1,123 @@ +import { test } from 'uvu'; +import * as assert from 'uvu/assert'; +import detectLang from '../src/index'; + +test('1', () => { + const code = detectLang(`{ + "key": "value", + + "keys": "must always be enclosed in double quotes", + "numbers": 0, + "strings": "Hellø, wørld. All unicode is allowed, along with \\"escaping\\".", + "has bools?": true, + "nothingness": null, + + "big number": 1.2e+100, + + "objects": { + "comment": "Most of your structure will come from objects.", + + "array": [0, 1, 2, 3, "Arrays can have anything in them.", 5], + + "another object": { + "comment": "These things can be nested, very useful." + } + }, + + "silliness": [ + { + "sources of potassium": ["bananas"] + }, + [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, "neo"], + [0, 0, 0, 1] + ] + ], + + "alternative style": { + "comment": "check this out!" + , "comma position": "doesn't matter, if it's before the next key, it's valid" + , "another comment": "how nice" + }, + + + + "whitespace": "Does not matter.", + + + + "that was short": "And done. You now know everything JSON has to offer." +}`); + assert.equal(code.language, 'JSON'); +}); + +test('2', () => { + const code = detectLang(`{ + "name": "John Doe", + "age": 43, + "address": { + "street": "10 Downing Street", + "city": "London" + }, + "phones": [ + "+44 1234567", + "+44 2345678" + ] +}`); + assert.equal(code.language, 'JSON'); +}); + +test('3', () => { + const code = detectLang(`{ + "keywords": [ + "JSON", + "server", + "fake", + "REST", + "API", + "prototyping", + "mock", + "mocking", + "test", + "testing", + "rest", + "data", + "dummy", + "sandbox" + ] +}`); + assert.equal(code.language, 'JSON'); +}); + +test('4', () => { + const code = detectLang(`{ + "/api/": "/", + "/blog/:resource/:id/show": "/:resource/:id", + "/blog/:category": "/posts?category=:category" + }`); + assert.equal(code.language, 'JSON'); +}); + +test('5', () => { + const code = detectLang(`{ + "posts": [ + { "id": 1, "title": "json-server", "author": "typicode" } + ], + "comments": [ + { "id": 1, "body": "some comment", "postId": 1 } + ], + "profile": { "name": "typicode" } + }`); + assert.equal(code.language, 'JSON'); +}); + +test('6', () => { + const code = detectLang(`{ + "middlewares": ["./fixtures/middlewares/en", "./fixtures/middlewares/jp"] + }`); + assert.equal(code.language, 'JSON'); +}); + +test.run(); diff --git a/tests/large.test.ts b/tests/large.test.ts index 8acb3d5..4d6b47e 100644 --- a/tests/large.test.ts +++ b/tests/large.test.ts @@ -670,6 +670,7 @@ test('large input', () => { Java: -832, Javascript: -452, Julia: 24, + JSON: 0, Kotlin: 0, Lua: -1820, Markdown: 0,