From f91db1e2eaa6561fb43c5f8598ea37ca0d8a7fba Mon Sep 17 00:00:00 2001 From: May <143908478+mmendieta2@users.noreply.github.com> Date: Fri, 20 Mar 2026 23:40:06 +0000 Subject: [PATCH 1/5] Add stateUtils.text.js and created tests for stateUtils.js Co-authored-by: Diego Salvaleon --- .../IDE/components/Editor/stateUtils.test.js | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 client/modules/IDE/components/Editor/stateUtils.test.js diff --git a/client/modules/IDE/components/Editor/stateUtils.test.js b/client/modules/IDE/components/Editor/stateUtils.test.js new file mode 100644 index 0000000000..9eff8f2dd8 --- /dev/null +++ b/client/modules/IDE/components/Editor/stateUtils.test.js @@ -0,0 +1,77 @@ +import { EditorState } from '@codemirror/state'; +import { EditorView } from '@codemirror/view'; +import { getFileMode, makeCssLinter } from './stateUtils'; + +describe('getFileMode', () => { + it('Returns correct javascript file mode', () => { + const fileName = 'file1.js'; + const mode = getFileMode(fileName); + const expectedMode = 'javascript'; + + expect(mode).toBe(expectedMode); + }); + + it('Returns correct css file mode', () => { + const fileName = 'file1.css'; + const mode = getFileMode(fileName); + const expectedMode = 'css'; + + expect(mode).toBe(expectedMode); + }); + + it('Returns correct html file mode', () => { + const fileName = 'file1.html'; + const mode = getFileMode(fileName); + const expectedMode = 'html'; + + expect(mode).toBe(expectedMode); + }); + + it('Returns correct xml file mode', () => { + const fileName = 'file1.xml'; + const mode = getFileMode(fileName); + const expectedMode = 'xml'; + + expect(mode).toBe(expectedMode); + }); + + it('Returns correct json file mode', () => { + const fileName = 'file1.json'; + const mode = getFileMode(fileName); + const expectedMode = 'application/json'; + + expect(mode).toBe(expectedMode); + }); + + it('Returns correct frag|glsl file mode', () => { + const fileName = 'file1.frag'; + const fileName2 = 'file2.glsl'; + const mode = getFileMode(fileName); + const mode2 = getFileMode(fileName2); + const expectedMode = 'x-shader/x-fragment'; + + expect(mode).toBe(expectedMode); + expect(mode2).toBe(expectedMode); + }); + it('Returns correct vert|stl|mtl file mode', () => { + const fileName = 'file1.vert'; + const fileName2 = 'file2.stl'; + const fileName3 = 'file3.mtl'; + const mode = getFileMode(fileName); + const mode2 = getFileMode(fileName2); + const mode3 = getFileMode(fileName3); + const expectedMode = 'x-shader/x-vertex'; + + expect(mode).toBe(expectedMode); + expect(mode2).toBe(expectedMode); + expect(mode3).toBe(expectedMode); + }); + it('Returns plain text otherwise file mode', () => { + const fileName = 'file1.py'; + const mode = getFileMode(fileName); + const expectedMode = 'text/plain'; + expect(mode).toBe(expectedMode); + }); +}); + +describe('makeCssLinter', () => {}); From f36ec87893bbe6ceee2e1583af9fc2932357f6e9 Mon Sep 17 00:00:00 2001 From: May <143908478+mmendieta2@users.noreply.github.com> Date: Fri, 20 Mar 2026 23:56:06 +0000 Subject: [PATCH 2/5] Export more functions from stateUtils.js --- .../modules/IDE/components/Editor/stateUtils.test.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client/modules/IDE/components/Editor/stateUtils.test.js b/client/modules/IDE/components/Editor/stateUtils.test.js index 9eff8f2dd8..c268bef944 100644 --- a/client/modules/IDE/components/Editor/stateUtils.test.js +++ b/client/modules/IDE/components/Editor/stateUtils.test.js @@ -1,6 +1,14 @@ import { EditorState } from '@codemirror/state'; import { EditorView } from '@codemirror/view'; -import { getFileMode, makeCssLinter } from './stateUtils'; +import { + getFileMode, // Completed + getFileLanguage, // TODO + getFileLinter, // TODO + makeCssLinter, // TODO + makeHtmlLinter, // TODO + makeJsLinter, // TODO + getFileEmmetConfig // TODO +} from './stateUtils'; describe('getFileMode', () => { it('Returns correct javascript file mode', () => { @@ -74,4 +82,6 @@ describe('getFileMode', () => { }); }); +describe('getFileLanguage', () => {}); +describe('getFileLinter', () => {}); describe('makeCssLinter', () => {}); From f39b0c83cdb91b59e5939f5c2a310a205001f402 Mon Sep 17 00:00:00 2001 From: May <143908478+mmendieta2@users.noreply.github.com> Date: Sat, 28 Mar 2026 00:11:39 +0000 Subject: [PATCH 3/5] Add tests for createNewFileState function in stateUtils.js --- .../IDE/components/Editor/stateUtils.test.js | 160 ++++++++++++++++-- 1 file changed, 150 insertions(+), 10 deletions(-) diff --git a/client/modules/IDE/components/Editor/stateUtils.test.js b/client/modules/IDE/components/Editor/stateUtils.test.js index c268bef944..29bed261df 100644 --- a/client/modules/IDE/components/Editor/stateUtils.test.js +++ b/client/modules/IDE/components/Editor/stateUtils.test.js @@ -1,13 +1,11 @@ import { EditorState } from '@codemirror/state'; import { EditorView } from '@codemirror/view'; +import p5JavaScript from './p5JavaScript'; + import { - getFileMode, // Completed - getFileLanguage, // TODO - getFileLinter, // TODO - makeCssLinter, // TODO - makeHtmlLinter, // TODO - makeJsLinter, // TODO - getFileEmmetConfig // TODO + getFileMode, + createNewFileState, + updateFileStates } from './stateUtils'; describe('getFileMode', () => { @@ -61,6 +59,7 @@ describe('getFileMode', () => { expect(mode).toBe(expectedMode); expect(mode2).toBe(expectedMode); }); + it('Returns correct vert|stl|mtl file mode', () => { const fileName = 'file1.vert'; const fileName2 = 'file2.stl'; @@ -74,14 +73,155 @@ describe('getFileMode', () => { expect(mode2).toBe(expectedMode); expect(mode3).toBe(expectedMode); }); + it('Returns plain text otherwise file mode', () => { const fileName = 'file1.py'; const mode = getFileMode(fileName); const expectedMode = 'text/plain'; expect(mode).toBe(expectedMode); }); + + it('Empty fileName', () => { + const fileName = ''; + const mode = getFileMode(fileName); + const expectedMode = 'text/plain'; + expect(mode).toBe(expectedMode); + }); + + it('Unknown fileName', () => { + const fileName = 'file1.xyz'; + const mode = getFileMode(fileName); + const expectedMode = 'text/plain'; + expect(mode).toBe(expectedMode); + }); +}); + +describe('createNewFileState', () => { + it('Enables line wrap', () => { + const fileName = 'file1.js'; + const content = ``; + const settings = { + linewrap: true, + lineNumbers: true, + autocomplete: false, + autocloseBracketsQuotes: false, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn() + }; + const result = createNewFileState(fileName, content, settings); + + const parent = document.createElement('div'); + const cmView = new EditorView({ state: result.cmState, parent }); + const cmGutter = parent.querySelector('.cm-lineWrapping'); + + expect(cmGutter).not.toBeNull(); + }); + + it('Enables line wrap', () => { + const fileName = 'file1.js'; + const content = ``; + const settings = { + linewrap: false, + lineNumbers: true, + autocomplete: false, + autocloseBracketsQuotes: false, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn() + }; + const result = createNewFileState(fileName, content, settings); + + const parent = document.createElement('div'); + const cmView = new EditorView({ state: result.cmState, parent }); + const div = parent.querySelector('.cm-lineWrapping'); + + expect(div).toBeNull(); + }); + + it('Enables line numbers', () => { + const fileName = 'file1.js'; + const content = ``; + const settings = { + linewrap: false, + lineNumbers: true, + autocomplete: false, + autocloseBracketsQuotes: false, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn() + }; + const result = createNewFileState(fileName, content, settings); + + const parent = document.createElement('div'); + const cmView = new EditorView({ state: result.cmState, parent }); + const div = parent.querySelector('.cm-lineNumbers'); + + expect(div).not.toBeNull(); + }); + + it('Disable line numbers', () => { + const fileName = 'file1.js'; + const content = ``; + const settings = { + linewrap: false, + lineNumbers: false, + autocomplete: false, + autocloseBracketsQuotes: false, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn() + }; + const result = createNewFileState(fileName, content, settings); + + const parent = document.createElement('div'); + const cmView = new EditorView({ state: result.cmState, parent }); + const div = parent.querySelector('.cm-lineNumbers'); + + expect(div).toBeNull(); + }); + + it('Enable autocomplete', () => { + const fileName = 'file1.js'; + const content = ``; + const settings = { + linewrap: false, + lineNumbers: false, + autocomplete: true, + autocloseBracketsQuotes: false, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn() + }; + const result = createNewFileState(fileName, content, settings); + + const parent = document.createElement('div'); + const cmView = new EditorView({ state: result.cmState, parent }); + const div = parent.querySelector('.cm-content'); + + console.log(div.outerHTML); + + const hasAriaAutocomplete = div.hasAttribute('aria-autocomplete'); + + expect(hasAriaAutocomplete).toBe(true); + }); + + it('Disable autocomplete', () => { + const fileName = 'file1.js'; + const content = ``; + const settings = { + linewrap: false, + lineNumbers: false, + autocomplete: false, + autocloseBracketsQuotes: false, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn() + }; + const result = createNewFileState(fileName, content, settings); + + const parent = document.createElement('div'); + const cmView = new EditorView({ state: result.cmState, parent }); + const div = parent.querySelector('.cm-content'); + + const hasAriaAutocomplete = div.hasAttribute('aria-autocomplete'); + + expect(hasAriaAutocomplete).toBe(false); + }); }); -describe('getFileLanguage', () => {}); -describe('getFileLinter', () => {}); -describe('makeCssLinter', () => {}); +describe('updateFileStates', () => {}); From e4d2dcabba07770340dbce68c37a716c93cee715 Mon Sep 17 00:00:00 2001 From: May <143908478+mmendieta2@users.noreply.github.com> Date: Sat, 28 Mar 2026 22:40:48 +0000 Subject: [PATCH 4/5] Add autoCloseBracketsQuotes and Tidy Code keymap tests --- .../IDE/components/Editor/stateUtils.test.js | 157 +++++++++++++++--- 1 file changed, 138 insertions(+), 19 deletions(-) diff --git a/client/modules/IDE/components/Editor/stateUtils.test.js b/client/modules/IDE/components/Editor/stateUtils.test.js index 29bed261df..4a64f7ed9a 100644 --- a/client/modules/IDE/components/Editor/stateUtils.test.js +++ b/client/modules/IDE/components/Editor/stateUtils.test.js @@ -1,12 +1,7 @@ -import { EditorState } from '@codemirror/state'; import { EditorView } from '@codemirror/view'; -import p5JavaScript from './p5JavaScript'; - -import { - getFileMode, - createNewFileState, - updateFileStates -} from './stateUtils'; +import { keymap } from '@codemirror/view'; +import * as tidier from './tidier'; +import { getFileMode, createNewFileState } from './stateUtils'; describe('getFileMode', () => { it('Returns correct javascript file mode', () => { @@ -97,6 +92,10 @@ describe('getFileMode', () => { }); describe('createNewFileState', () => { + function getDocText(cmView) { + return cmView.state.doc.toString(); + } + it('Enables line wrap', () => { const fileName = 'file1.js'; const content = ``; @@ -112,9 +111,9 @@ describe('createNewFileState', () => { const parent = document.createElement('div'); const cmView = new EditorView({ state: result.cmState, parent }); - const cmGutter = parent.querySelector('.cm-lineWrapping'); + const div = parent.querySelector('.cm-lineWrapping'); - expect(cmGutter).not.toBeNull(); + expect(div).not.toBeNull(); }); it('Enables line wrap', () => { @@ -194,11 +193,7 @@ describe('createNewFileState', () => { const cmView = new EditorView({ state: result.cmState, parent }); const div = parent.querySelector('.cm-content'); - console.log(div.outerHTML); - - const hasAriaAutocomplete = div.hasAttribute('aria-autocomplete'); - - expect(hasAriaAutocomplete).toBe(true); + expect(div).toHaveAttribute('aria-autocomplete', 'list'); }); it('Disable autocomplete', () => { @@ -218,10 +213,134 @@ describe('createNewFileState', () => { const cmView = new EditorView({ state: result.cmState, parent }); const div = parent.querySelector('.cm-content'); - const hasAriaAutocomplete = div.hasAttribute('aria-autocomplete'); + expect(div).not.toHaveAttribute('aria-autocomplete', 'list'); + }); + + it('Enables autoclose brackets and quotes', () => { + const fileName = 'file1.js'; + const content = ``; + const settings = { + linewrap: false, + lineNumbers: false, + autocomplete: false, + autocloseBracketsQuotes: true, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn() + }; + + const result = createNewFileState(fileName, content, settings); - expect(hasAriaAutocomplete).toBe(false); + expect(result.closeBracketsCpt.get(result.cmState).length).toBeGreaterThan( + 0 + ); }); -}); -describe('updateFileStates', () => {}); + it('Disable autoclose brackets and quotes', () => { + const fileName = 'file1.js'; + const content = ``; + const settings = { + linewrap: false, + lineNumbers: false, + autocomplete: false, + autocloseBracketsQuotes: false, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn() + }; + + const result = createNewFileState(fileName, content, settings); + + expect(result.closeBracketsCpt.get(result.cmState).length).toBe(0); + }); + + it('Tidy code keymap defined', () => { + const tidySpy = jest + .spyOn(tidier, 'tidyCodeWithPrettier') + .mockImplementation(() => {}); + + const fileName = 'file1.css'; + const content = `h1{color: blue;}`; + const settings = { + linewrap: false, + lineNumbers: false, + autocomplete: false, + autocloseBracketsQuotes: false, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn() + }; + + const result = createNewFileState(fileName, content, settings); + + const cmView = new EditorView({ state: result.cmState }); + + const km = result.cmState + .facet(keymap) + .flat() + .find((k) => k.key === 'Shift-Mod-F'); + + expect(km).toBeDefined(); + tidySpy.mockRestore(); + }); + + it('Tidy code keymap calls correct function', () => { + const tidySpy = jest + .spyOn(tidier, 'tidyCodeWithPrettier') + .mockImplementation(() => {}); + + const fileName = 'file1.css'; + const content = `h1{color: blue;}`; + const settings = { + linewrap: false, + lineNumbers: false, + autocomplete: false, + autocloseBracketsQuotes: false, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn() + }; + + const result = createNewFileState(fileName, content, settings); + + const cmView = new EditorView({ state: result.cmState }); + + const km = result.cmState + .facet(keymap) + .flat() + .find((k) => k.key === 'Shift-Mod-F'); + + km.run(cmView); + + expect(tidySpy).toHaveBeenCalledWith(cmView, expect.any(String)); + tidySpy.mockRestore(); + }); + + it('Tidy code keymap correctly formats code', () => { + const tidySpy = jest + .spyOn(tidier, 'tidyCodeWithPrettier') + .mockImplementation(() => {}); + + const fileName = 'file1.css'; + const content = `h1{color: blue;}`; + const formattedContent = `h1 {\n color: blue;\n}`; + const settings = { + linewrap: false, + lineNumbers: false, + autocomplete: false, + autocloseBracketsQuotes: false, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn() + }; + + const result = createNewFileState(fileName, content, settings); + + const cmView = new EditorView({ state: result.cmState }); + + const km = result.cmState + .facet(keymap) + .flat() + .find((k) => k.key === 'Shift-Mod-F'); + + km.run(cmView); + + expect(getDocText(cmView)).toBe(formattedContent); + tidySpy.mockRestore(); + }); +}); From a32a95188decbe526e11c28bb311fabc72135e79 Mon Sep 17 00:00:00 2001 From: RyRy241 <142365031+RyRy241@users.noreply.github.com> Date: Mon, 30 Mar 2026 01:42:39 +0000 Subject: [PATCH 5/5] Added changes --- .../IDE/components/Editor/stateUtils.test.js | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) diff --git a/client/modules/IDE/components/Editor/stateUtils.test.js b/client/modules/IDE/components/Editor/stateUtils.test.js index 4a64f7ed9a..c8dd38dfef 100644 --- a/client/modules/IDE/components/Editor/stateUtils.test.js +++ b/client/modules/IDE/components/Editor/stateUtils.test.js @@ -1,3 +1,4 @@ +import { EditorState } from '@codemirror/state'; import { EditorView } from '@codemirror/view'; import { keymap } from '@codemirror/view'; import * as tidier from './tidier'; @@ -344,3 +345,195 @@ describe('createNewFileState', () => { tidySpy.mockRestore(); }); }); + +function makeView(fileName, content = '', extraSettings = {}) { + const settings = { + linewrap: false, + lineNumbers: false, + autocomplete: false, + autocloseBracketsQuotes: false, + onUpdateLinting: jest.fn(), + onViewUpdate: jest.fn(), + ...extraSettings + }; + const result = createNewFileState(fileName, content, settings); + const parent = document.createElement('div'); + const cmView = new EditorView({ state: result.cmState, parent }); + return { cmView, result, settings }; +} + +describe('getFileLanguage (indirect)', () => { + it('Loads a language extension for JS files without throwing', () => { + expect(() => makeView('sketch.js', 'var x = 1;')).not.toThrow(); + }); + + it('Loads a language extension for CSS files without throwing', () => { + expect(() => makeView('style.css', 'body { color: red; }')).not.toThrow(); + }); + + it('Loads a language extension for HTML files without throwing', () => { + expect(() => makeView('index.html', '
')).not.toThrow(); + }); + + it('Loads a language extension for XML files without throwing', () => { + expect(() => makeView('data.xml', '')).not.toThrow(); + }); + + it('Loads a language extension for JSON files without throwing', () => { + expect(() => makeView('data.json', '{}')).not.toThrow(); + }); + + it('Handles unsupported file types without throwing', () => { + expect(() => makeView('shader.frag', 'void main() {}')).not.toThrow(); + }); + + it('Handles plain text files without throwing', () => { + expect(() => makeView('readme.txt', 'hello world')).not.toThrow(); + }); +}); + +describe('getFileLinter (indirect)', () => { + it('Adds lint gutter for JS files', () => { + const { cmView } = makeView('sketch.js', 'var x = 1;'); + const lintGutter = cmView.dom.querySelector('.cm-gutter-lint'); + expect(lintGutter).not.toBeNull(); + }); + + it('Adds lint gutter for CSS files', () => { + const { cmView } = makeView('style.css', 'body { color: red; }'); + const lintGutter = cmView.dom.querySelector('.cm-gutter-lint'); + expect(lintGutter).not.toBeNull(); + }); + + it('Adds lint gutter for HTML files', () => { + const { cmView } = makeView('index.html', '
'); + const lintGutter = cmView.dom.querySelector('.cm-gutter-lint'); + expect(lintGutter).not.toBeNull(); + }); + + it('Does not add lint gutter for JSON files', () => { + const { cmView } = makeView('data.json', '{}'); + const lintGutter = cmView.dom.querySelector('.cm-gutter-lint'); + expect(lintGutter).toBeNull(); + }); + + it('Does not add lint gutter for plain text files', () => { + const { cmView } = makeView('readme.txt', 'hello'); + const lintGutter = cmView.dom.querySelector('.cm-gutter-lint'); + expect(lintGutter).toBeNull(); + }); +}); + +describe('makeJsLinter (indirect)', () => { + it('Calls onUpdateLinting for JS files', () => { + const onUpdateLinting = jest.fn(); + makeView('sketch.js', 'var x = 1;', { onUpdateLinting }); + expect(onUpdateLinting).toHaveBeenCalled(); + }); + + it('Reports diagnostics for invalid JS', () => { + const onUpdateLinting = jest.fn(); + makeView('sketch.js', 'var x = ;', { onUpdateLinting }); + const diagnostics = onUpdateLinting.mock.calls[0][0]; + expect(diagnostics.length).toBeGreaterThan(0); + }); + + it('Reports no diagnostics for valid JS', () => { + const onUpdateLinting = jest.fn(); + makeView('sketch.js', 'var x = 1;', { onUpdateLinting }); + const diagnostics = onUpdateLinting.mock.calls[0][0]; + expect(diagnostics.length).toBe(0); + }); + + it('Diagnostic has from, to, severity, and message fields', () => { + const onUpdateLinting = jest.fn(); + makeView('sketch.js', 'var x = ;', { onUpdateLinting }); + const diagnostics = onUpdateLinting.mock.calls[0][0]; + expect(diagnostics[0]).toHaveProperty('from'); + expect(diagnostics[0]).toHaveProperty('to'); + expect(diagnostics[0]).toHaveProperty('severity'); + expect(diagnostics[0]).toHaveProperty('message'); + }); +}); + +describe('makeCssLinter (indirect)', () => { + it('Calls onUpdateLinting for CSS files', () => { + const onUpdateLinting = jest.fn(); + makeView('style.css', 'body { color: red; }', { onUpdateLinting }); + expect(onUpdateLinting).toHaveBeenCalled(); + }); + + it('Reports diagnostics for invalid CSS', () => { + const onUpdateLinting = jest.fn(); + makeView('style.css', 'body { color: }', { onUpdateLinting }); + const diagnostics = onUpdateLinting.mock.calls[0][0]; + expect(diagnostics.length).toBeGreaterThan(0); + }); + + it('Reports no diagnostics for valid CSS', () => { + const onUpdateLinting = jest.fn(); + makeView('style.css', 'body { color: red; }', { onUpdateLinting }); + const diagnostics = onUpdateLinting.mock.calls[0][0]; + expect(diagnostics.length).toBe(0); + }); + + it('Diagnostic has from, to, severity, and message fields', () => { + const onUpdateLinting = jest.fn(); + makeView('style.css', 'body { color: }', { onUpdateLinting }); + const diagnostics = onUpdateLinting.mock.calls[0][0]; + expect(diagnostics[0]).toHaveProperty('from'); + expect(diagnostics[0]).toHaveProperty('to'); + expect(diagnostics[0]).toHaveProperty('severity'); + expect(diagnostics[0]).toHaveProperty('message'); + }); +}); + +describe('makeHtmlLinter (indirect)', () => { + it('Calls onUpdateLinting for HTML files', () => { + const onUpdateLinting = jest.fn(); + makeView('index.html', '
', { onUpdateLinting }); + expect(onUpdateLinting).toHaveBeenCalled(); + }); + + it('Reports diagnostics for invalid HTML', () => { + const onUpdateLinting = jest.fn(); + makeView('index.html', '
', { onUpdateLinting }); + const diagnostics = onUpdateLinting.mock.calls[0][0]; + expect(diagnostics.length).toBeGreaterThan(0); + }); + + it('Reports no diagnostics for valid HTML', () => { + const onUpdateLinting = jest.fn(); + makeView('index.html', '

Hello

', { onUpdateLinting }); + const diagnostics = onUpdateLinting.mock.calls[0][0]; + expect(diagnostics.length).toBe(0); + }); + + it('Diagnostic has from, to, severity, and message fields', () => { + const onUpdateLinting = jest.fn(); + makeView('index.html', '
', { onUpdateLinting }); + const diagnostics = onUpdateLinting.mock.calls[0][0]; + expect(diagnostics[0]).toHaveProperty('from'); + expect(diagnostics[0]).toHaveProperty('to'); + expect(diagnostics[0]).toHaveProperty('severity'); + expect(diagnostics[0]).toHaveProperty('message'); + }); +}); + +describe('getFileEmmetConfig (indirect)', () => { + it('Creates state for HTML files with emmet config without throwing', () => { + expect(() => makeView('index.html', '
')).not.toThrow(); + }); + + it('Creates state for CSS files with emmet config without throwing', () => { + expect(() => makeView('style.css', 'body {}')).not.toThrow(); + }); + + it('Creates state for JS files without emmet config without throwing', () => { + expect(() => makeView('sketch.js', 'var x = 1;')).not.toThrow(); + }); + + it('Creates state for JSON files without emmet config without throwing', () => { + expect(() => makeView('data.json', '{}')).not.toThrow(); + }); +}); \ No newline at end of file