diff --git a/grammars/julia.cson b/grammars/julia.cson index 7ec55cd..b2ca978 100644 --- a/grammars/julia.cson +++ b/grammars/julia.cson @@ -36,6 +36,9 @@ patterns: [ { include: '#for_block' } + { + include: '#testitem_block' + } { include: '#keyword' } @@ -263,6 +266,28 @@ repository: ] } ] + testitem_block: + patterns: [ + { + name: 'keyword.other.testitem.julia' + begin: '^@testitem\\b' + beginCaptures: + '0': + name: 'keyword.other.testitem.begin.julia' + '1': + name: 'keyword.control.begin.julia' + end: '^end\\b' + endCaptures: + '0': + name: 'keyword.other.testitem.end.julia' + comment: '@testitem block for unit-testing. MUST begin with `@testitem` on a new line, and end with `end` on a new line.' + patterns: [ + { + include: '$self' + } + ] + } + ] keyword: patterns: [ { @@ -302,7 +327,7 @@ repository: name: 'keyword.control.as.julia' } { - match: '(@(\\.|(?:[[:alpha:]_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{So}←-⇿])(?:[[:word:]_!\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{Mn}\u0001-¡]|[^\\P{Mc}\u0001-¡]|[^\\P{Nd}\u0001-¡]|[^\\P{Pc}\u0001-¡]|[^\\P{Sk}\u0001-¡]|[^\\P{Me}\u0001-¡]|[^\\P{No}\u0001-¡]|[′-‷⁗]|[^\\P{So}←-⇿])*))' + match: '@(?!testitem\\b)(\\.|(?:[[:alpha:]_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{So}←-⇿])(?:[[:word:]_!\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{Mn}\u0001-¡]|[^\\P{Mc}\u0001-¡]|[^\\P{Nd}\u0001-¡]|[^\\P{Pc}\u0001-¡]|[^\\P{Sk}\u0001-¡]|[^\\P{Me}\u0001-¡]|[^\\P{No}\u0001-¡]|[′-‷⁗]|[^\\P{So}←-⇿])*)' name: 'support.function.macro.julia' } ] diff --git a/grammars/julia.json b/grammars/julia.json index 2a21c2f..150a585 100644 --- a/grammars/julia.json +++ b/grammars/julia.json @@ -30,6 +30,9 @@ { "include": "#for_block" }, + { + "include": "#testitem_block" + }, { "include": "#keyword" }, @@ -295,6 +298,34 @@ } ] }, + "testitem_block": { + "patterns": [ + { + "name": "keyword.other.testitem.julia", + "begin": "^@testitem\\b", + "beginCaptures": { + "0": { + "name": "keyword.other.testitem.begin.julia" + }, + "1": { + "name": "keyword.control.begin.julia" + } + }, + "end": "^end\\b", + "endCaptures": { + "0": { + "name": "keyword.other.testitem.end.julia" + } + }, + "comment": "@testitem block for unit-testing. MUST begin with `@testitem` on a new line, and end with `end` on a new line.", + "patterns": [ + { + "include": "$self" + } + ] + } + ] + }, "keyword": { "patterns": [ { @@ -334,7 +365,7 @@ "name": "keyword.control.as.julia" }, { - "match": "(@(\\.|(?:[[:alpha:]_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{So}←-⇿])(?:[[:word:]_!\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{Mn}\u0001-¡]|[^\\P{Mc}\u0001-¡]|[^\\P{Nd}\u0001-¡]|[^\\P{Pc}\u0001-¡]|[^\\P{Sk}\u0001-¡]|[^\\P{Me}\u0001-¡]|[^\\P{No}\u0001-¡]|[′-‷⁗]|[^\\P{So}←-⇿])*))", + "match": "@(?!testitem\\b)(\\.|(?:[[:alpha:]_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{So}←-⇿])(?:[[:word:]_!\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{Mn}\u0001-¡]|[^\\P{Mc}\u0001-¡]|[^\\P{Nd}\u0001-¡]|[^\\P{Pc}\u0001-¡]|[^\\P{Sk}\u0001-¡]|[^\\P{Me}\u0001-¡]|[^\\P{No}\u0001-¡]|[′-‷⁗]|[^\\P{So}←-⇿])*)", "name": "support.function.macro.julia" } ] diff --git a/grammars/julia.template.json b/grammars/julia.template.json index 1cafafd..9f8cb77 100644 --- a/grammars/julia.template.json +++ b/grammars/julia.template.json @@ -30,6 +30,9 @@ { "include": "#for_block" }, + { + "include": "#testitem_block" + }, { "include": "#keyword" }, @@ -295,6 +298,34 @@ } ] }, + "testitem_block" : { + "patterns": [ + { + "name": "keyword.other.testitem.julia", + "begin": "^@testitem\\b", + "beginCaptures": { + "0": { + "name": "keyword.other.testitem.begin.julia" + }, + "1": { + "name": "keyword.control.begin.julia" + } + }, + "end": "^end\\b", + "endCaptures": { + "0": { + "name": "keyword.other.testitem.end.julia" + } + }, + "comment": "@testitem block for unit-testing. MUST begin with `@testitem` on a new line, and end with `end` on a new line.", + "patterns": [ + { + "include": "$self" + } + ] + } + ] + }, "keyword": { "patterns": [ { @@ -334,7 +365,7 @@ "name": "keyword.control.as.julia" }, { - "match": "(@(\\.|{{id}}))", + "match": "@(?!testitem\\b)(\\.|{{id}})", "name": "support.function.macro.julia" } ] diff --git a/grammars/julia_vscode.json b/grammars/julia_vscode.json index fb75e8d..c106215 100644 --- a/grammars/julia_vscode.json +++ b/grammars/julia_vscode.json @@ -30,6 +30,9 @@ { "include": "#for_block" }, + { + "include": "#testitem_block" + }, { "include": "#keyword" }, @@ -295,6 +298,34 @@ } ] }, + "testitem_block": { + "patterns": [ + { + "name": "keyword.other.testitem.julia", + "begin": "^@testitem\\b", + "beginCaptures": { + "0": { + "name": "keyword.other.testitem.begin.julia" + }, + "1": { + "name": "keyword.control.begin.julia" + } + }, + "end": "^end\\b", + "endCaptures": { + "0": { + "name": "keyword.other.testitem.end.julia" + } + }, + "comment": "@testitem block for unit-testing. MUST begin with `@testitem` on a new line, and end with `end` on a new line.", + "patterns": [ + { + "include": "$self" + } + ] + } + ] + }, "keyword": { "patterns": [ { @@ -334,7 +365,7 @@ "name": "keyword.control.as.julia" }, { - "match": "(@(\\.|(?:[[:alpha:]_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{So}←-⇿])(?:[[:word:]_!\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{Mn}\u0001-¡]|[^\\P{Mc}\u0001-¡]|[^\\P{Nd}\u0001-¡]|[^\\P{Pc}\u0001-¡]|[^\\P{Sk}\u0001-¡]|[^\\P{Me}\u0001-¡]|[^\\P{No}\u0001-¡]|[′-‷⁗]|[^\\P{So}←-⇿])*))", + "match": "@(?!testitem\\b)(\\.|(?:[[:alpha:]_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{So}←-⇿])(?:[[:word:]_!\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{Mn}\u0001-¡]|[^\\P{Mc}\u0001-¡]|[^\\P{Nd}\u0001-¡]|[^\\P{Pc}\u0001-¡]|[^\\P{Sk}\u0001-¡]|[^\\P{Me}\u0001-¡]|[^\\P{No}\u0001-¡]|[′-‷⁗]|[^\\P{So}←-⇿])*)", "name": "support.function.macro.julia" } ] diff --git a/package-lock.json b/package-lock.json index e629725..06f419b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,16 @@ { "name": "language-julia", - "version": "0.22.1", + "version": "0.23.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "language-julia", - "version": "0.22.1", + "version": "0.23.0", "license": "MIT", + "dependencies": { + "dedent": "^1.5.3" + }, "devDependencies": { "chai": "^4.3.7", "cson": "^7.20.0", @@ -372,6 +375,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, "node_modules/deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", @@ -518,9 +534,9 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" @@ -1566,6 +1582,12 @@ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, + "dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "requires": {} + }, "deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", @@ -1663,9 +1685,9 @@ "dev": true }, "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, "glob": { diff --git a/package.json b/package.json index 5968100..9b17b07 100644 --- a/package.json +++ b/package.json @@ -27,5 +27,8 @@ }, "pre-commit": [ "generate" - ] + ], + "dependencies": { + "dedent": "^1.5.3" + } } diff --git a/test/test.js b/test/test.js index 3bf464c..b9a9dd1 100644 --- a/test/test.js +++ b/test/test.js @@ -2,6 +2,7 @@ const fs = require('fs') const path = require('path') const vsctm = require('vscode-textmate') const oniguruma = require('vscode-oniguruma') +const dedent = require('dedent') const { expect } = require('chai') const GRAMMAR_PATH = path.join(__dirname, '../grammars/julia_vscode.json') @@ -3680,4 +3681,359 @@ describe('Julia grammar', function () { }, ]) }) + it("tokenizes @testitem with simple content", function () { + const tokens = tokenize(grammar, '@testitem "foo" begin x = 1\nend\ny=2') + const true_tokens = [ + { + value: '@testitem', + scopes: ['keyword.other.testitem.julia', 'keyword.other.testitem.begin.julia'] + }, + { + value: ' ', + scopes: ['keyword.other.testitem.julia'] + }, + { + value: '\"', + scopes: ['keyword.other.testitem.julia', 'string.quoted.double.julia', 'punctuation.definition.string.begin.julia'] + }, + { + value: 'foo', + scopes: ['keyword.other.testitem.julia', 'string.quoted.double.julia'] + }, + { + value: '\"', + scopes: ['keyword.other.testitem.julia', 'string.quoted.double.julia', 'punctuation.definition.string.end.julia'] + }, + { + value: ' ', + scopes: ['keyword.other.testitem.julia'] + }, + { + value: 'begin', + scopes: ['keyword.other.testitem.julia', 'keyword.control.julia'] + }, + { + value: ' x ', + scopes: ['keyword.other.testitem.julia'] + }, + { + value: '=', + scopes: ['keyword.other.testitem.julia', 'keyword.operator.update.julia'] + }, + { + value: ' ', + scopes: ['keyword.other.testitem.julia'] + }, + { + value: '1', + scopes: ['keyword.other.testitem.julia', 'constant.numeric.julia'] + }, + { + value: '\n', + scopes: ['keyword.other.testitem.julia'] + }, + { + value: 'end', + scopes: ['keyword.other.testitem.julia', 'keyword.other.testitem.end.julia'] + }, + // Goes back after: + { + value: '\ny', + scopes: [] + }, + { + value: '=', + scopes: ['keyword.operator.update.julia'] + }, + { + value: '2', + scopes: ['constant.numeric.julia'] + }, + ] + compareTokens(tokens, true_tokens) + }) + it("tokenizes @testitem with nested content", function () { + const tokens = tokenize(grammar, + dedent(` + f(x) = x + @testitem "bar" begin + using MyPkg: f + for i in 1:10 + @test f(i) == i + end + end + `) + ) + const true_tokens = [ + { + 'value': 'f', + 'scopes': ['entity.name.function.julia'] + }, + { + 'value': '(', + 'scopes': ['meta.bracket.julia'] + }, + { + 'value': 'x', + 'scopes': [] + }, + { + 'value': ')', + 'scopes': ['meta.bracket.julia'] + }, + { + 'value': ' ', + 'scopes': [] + }, + { + 'value': '=', + 'scopes': ['keyword.operator.update.julia'] + }, + { + 'value': ' x\n', + 'scopes': [] + }, + { + 'value': '@testitem', + 'scopes': ['keyword.other.testitem.julia', 'keyword.other.testitem.begin.julia'] + }, + { + 'value': ' ', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': '"', + 'scopes': ['keyword.other.testitem.julia', 'string.quoted.double.julia', 'punctuation.definition.string.begin.julia'] + }, + { + 'value': 'bar', + 'scopes': ['keyword.other.testitem.julia', 'string.quoted.double.julia'] + }, + { + 'value': '"', + 'scopes': ['keyword.other.testitem.julia', 'string.quoted.double.julia', 'punctuation.definition.string.end.julia'] + }, + { + 'value': ' ', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': 'begin', + 'scopes': ['keyword.other.testitem.julia', 'keyword.control.julia'] + }, + { + 'value': '\n ', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': 'using', + 'scopes': ['keyword.other.testitem.julia', 'keyword.control.using.julia'] + }, + { + 'value': ' MyPkg', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': ':', + 'scopes': ['keyword.other.testitem.julia', 'keyword.operator.range.julia'] + }, + { + 'value': ' f\n ', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': 'for', + 'scopes': ['keyword.other.testitem.julia', 'keyword.control.julia'] + }, + { + 'value': ' i ', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': 'in', + 'scopes': ['keyword.other.testitem.julia', 'keyword.operator.relation.in.julia'] + }, + { + 'value': ' ', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': '1', + 'scopes': ['keyword.other.testitem.julia', 'constant.numeric.julia'] + }, + { + 'value': ':', + 'scopes': ['keyword.other.testitem.julia', 'keyword.operator.range.julia'] + }, + { + 'value': '10', + 'scopes': ['keyword.other.testitem.julia', 'constant.numeric.julia'] + }, + { + 'value': '\n', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': ' ', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': '@test', + 'scopes': ['keyword.other.testitem.julia', 'support.function.macro.julia'] + }, + { + 'value': ' ', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': 'f', + 'scopes': ['keyword.other.testitem.julia', 'support.function.julia'] + }, + { + 'value': '(', + 'scopes': ['keyword.other.testitem.julia', 'meta.bracket.julia'] + }, + { + 'value': 'i', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': ')', + 'scopes': ['keyword.other.testitem.julia', 'meta.bracket.julia'] + }, + { + 'value': ' ', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': '==', + 'scopes': ['keyword.other.testitem.julia', 'keyword.operator.relation.julia'] + }, + { + 'value': ' i\n ', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': 'end', + 'scopes': ['keyword.other.testitem.julia', 'keyword.control.end.julia'] + }, + // Still within the testitem, even though we encountered an end: + { + 'value': '\n', + 'scopes': ['keyword.other.testitem.julia'] + }, + { + 'value': 'end', + 'scopes': ['keyword.other.testitem.julia', 'keyword.other.testitem.end.julia'] + } + ] + compareTokens(tokens, true_tokens) + }) + it("fails to tokenize @testitem unless newline pattern", function () { + const tokens = tokenize(grammar, 'x = 1; @testitem "foo" begin x = 1 end') + // Purposefully fails to match, as might be within scope: + const true_tokens = [ + { scopes: [], value: 'x ' }, + { scopes: [ 'keyword.operator.update.julia' ], value: '=' }, + { scopes: [], value: ' ' }, + { scopes: [ 'constant.numeric.julia' ], value: '1' }, + { scopes: [ 'punctuation.separator.semicolon.julia' ], value: ';' }, + { scopes: [], value: ' @testitem ' }, + { + scopes: [ + 'string.quoted.double.julia', + 'punctuation.definition.string.begin.julia' + ], + value: '"' + }, + { scopes: [ 'string.quoted.double.julia' ], value: 'foo' }, + { + scopes: [ + 'string.quoted.double.julia', + 'punctuation.definition.string.end.julia' + ], + value: '"' + }, + { scopes: [], value: ' ' }, + { scopes: [ 'keyword.control.julia' ], value: 'begin' }, + { scopes: [], value: ' x ' }, + { scopes: [ 'keyword.operator.update.julia' ], value: '=' }, + { scopes: [], value: ' ' }, + { scopes: [ 'constant.numeric.julia' ], value: '1' }, + { scopes: [], value: ' ' }, + { scopes: [ 'keyword.control.end.julia' ], value: 'end' } + ] + compareTokens(tokens, true_tokens) + }) + it("fails to tokenize @testitem unless newline on end", function () { + const tokens = tokenize(grammar, '@testitem "foo" begin x = 1 end; y=2') + const true_tokens = [ + { + scopes: [ + 'keyword.other.testitem.julia', + 'keyword.other.testitem.begin.julia' + ], + value: '@testitem' + }, + { scopes: [ 'keyword.other.testitem.julia' ], value: ' ' }, + { + scopes: [ + 'keyword.other.testitem.julia', + 'string.quoted.double.julia', + 'punctuation.definition.string.begin.julia' + ], + value: '"' + }, + { + scopes: [ 'keyword.other.testitem.julia', 'string.quoted.double.julia' ], + value: 'foo' + }, + { + scopes: [ + 'keyword.other.testitem.julia', + 'string.quoted.double.julia', + 'punctuation.definition.string.end.julia' + ], + value: '"' + }, + { scopes: [ 'keyword.other.testitem.julia' ], value: ' ' }, + { + scopes: [ 'keyword.other.testitem.julia', 'keyword.control.julia' ], + value: 'begin' + }, + { scopes: [ 'keyword.other.testitem.julia' ], value: ' x ' }, + { + scopes: [ 'keyword.other.testitem.julia', 'keyword.operator.update.julia' ], + value: '=' + }, + { scopes: [ 'keyword.other.testitem.julia' ], value: ' ' }, + { + scopes: [ 'keyword.other.testitem.julia', 'constant.numeric.julia' ], + value: '1' + }, + { scopes: [ 'keyword.other.testitem.julia' ], value: ' ' }, + { + scopes: [ 'keyword.other.testitem.julia', 'keyword.control.end.julia' ], + value: 'end' + }, + { + scopes: [ + 'keyword.other.testitem.julia', + 'punctuation.separator.semicolon.julia' + ], + value: ';' + }, + // TODO: Fails to turn off testitem mode, because the `end` wasn't on a newline! + { scopes: [ 'keyword.other.testitem.julia' ], value: ' y' }, + { + scopes: [ 'keyword.other.testitem.julia', 'keyword.operator.update.julia' ], + value: '=' + }, + { + scopes: [ 'keyword.other.testitem.julia', 'constant.numeric.julia' ], + value: '2' + } + ] + compareTokens(tokens, true_tokens) + }) })