Migrate from CRA to Vite (#170)

* Basic CRA to Vite conversion

* Restore ESLint support

* Remove semicolons from vite config

* Add vite client types to tsconfig

* Migrate to Vitest for testing (not working on Mac)

* some test progress (#175)

* some test progress

* something maybe working

* remove local lib

* small clean up

* tweaks

* fix dependency

* clean up deps

* remove vitest import

* vitest config is needed even though we're not using vitest

* more tweaks to vite config

---------

Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
This commit is contained in:
Frank Noirot
2023-07-20 19:25:04 -04:00
committed by GitHub
parent 1666e17ca5
commit b89faa4a28
22 changed files with 2554 additions and 6386 deletions

12
.eslintrc Normal file
View File

@ -0,0 +1,12 @@
{
"extends": [
"react-app",
"react-app/jest"
],
"rules": {
"semi": [
"error",
"never"
]
}
}

View File

@ -13,9 +13,8 @@ jobs:
with: with:
node-version: '16.x' node-version: '16.x'
- run: yarn install - run: yarn install
- run: yarn build:wasm:ci - run: yarn build:wasm
- run: yarn simpleserver:ci - run: yarn simpleserver:ci
- run: npm pkg delete type
- run: yarn test:nowatch - run: yarn test:nowatch
- run: yarn test:cov - run: yarn test:cov
- run: yarn test:rust - run: yarn test:rust

3
babel.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
presets: ["@babel/preset-env"],
}

View File

@ -2,25 +2,25 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta <meta
name="description" name="description"
content="Web site created using create-react-app" content="Web site created using create-react-app"
/> />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="apple-touch-icon" href="/logo192.png" />
<!-- <!--
manifest.json provides metadata used when your web app is installed on a manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
--> -->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <link rel="manifest" href="/manifest.json" />
<!-- <!--
Notice the use of %PUBLIC_URL% in the tags above. Notice the use of in the tags above.
It will be replaced with the URL of the `public` folder during the build. It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML. Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will Unlike "/favicon.ico" or "favicon.ico", "/favicon.ico" will
work correctly both with client-side routing and a non-root public URL. work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
@ -39,5 +39,6 @@
To begin the development, run `npm start` or `yarn start`. To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
<script type="module" src="/src/index.tsx"></script>
</body> </body>
</html> </html>

15
jest.config.js Normal file
View File

@ -0,0 +1,15 @@
module.exports = {
testEnvironment: 'jsdom',
preset: 'ts-jest/presets/js-with-ts',
transform: {
'^.+\\.(ts|tsx)?$': 'ts-jest',
"^.+\\.(js|jsx)$": "babel-jest",
},
transformIgnorePatterns: [
"//node_modules/(?!(allotment|@tauri-apps/api)/)",
],
moduleNameMapper: {
'^allotment$': 'allotment/dist/legacy',
},
setupFilesAfterEnv: ['./src/setupTests.ts'],
}

View File

@ -12,7 +12,7 @@
"@testing-library/jest-dom": "^5.14.1", "@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0", "@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^13.2.1", "@testing-library/user-event": "^13.2.1",
"@types/jest": "^27.0.1", "@types/jest": "^29.5.3",
"@types/node": "^16.7.13", "@types/node": "^16.7.13",
"@types/react": "^18.0.0", "@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0", "@types/react-dom": "^18.0.0",
@ -25,8 +25,7 @@
"react-hot-toast": "^2.4.1", "react-hot-toast": "^2.4.1",
"react-json-view": "^1.21.3", "react-json-view": "^1.21.3",
"react-modal-promise": "^1.0.2", "react-modal-promise": "^1.0.2",
"react-router-dom": "^6.14.1", "react-router-dom": "^6.14.2",
"react-scripts": "5.0.1",
"sketch-helpers": "^0.0.3", "sketch-helpers": "^0.0.3",
"swr": "^2.0.4", "swr": "^2.0.4",
"toml": "^3.0.0", "toml": "^3.0.0",
@ -34,34 +33,27 @@
"typescript": "^4.4.2", "typescript": "^4.4.2",
"util": "^0.12.5", "util": "^0.12.5",
"uuid": "^9.0.0", "uuid": "^9.0.0",
"wasm-pack": "^0.11.1", "wasm-pack": "^0.12.1",
"web-vitals": "^2.1.0", "web-vitals": "^2.1.0",
"zustand": "^4.1.4" "zustand": "^4.1.4"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "vite",
"build": "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && source \"$HOME/.cargo/env\" && curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -y && yarn build:wasm:ci && react-scripts build", "build": "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && source \"$HOME/.cargo/env\" && curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -y && yarn build:wasm && vite build",
"build:local": "react-scripts build", "build:local": "vite build",
"build:both": "react-scripts build", "build:both": "vite build",
"build:both:local": "yarn build:wasm && react-scripts build", "build:both:local": "yarn build:wasm && vite build",
"test": "react-scripts test", "test": "jest",
"test:nowatch": "react-scripts test --watchAll=false --forceExit", "test:nowatch": "jest --watchAll=false --forceExit",
"test:rust": "(cd src/wasm-lib && cargo test && cargo clippy)", "test:rust": "(cd src/wasm-lib && cargo test && cargo clippy)",
"test:cov": "react-scripts test --watchAll=false --coverage=true --forceExit", "test:cov": "jest --watchAll=false --coverage=true --forceExit",
"simpleserver:ci": "http-server ./public --cors -p 3000 &", "simpleserver:ci": "http-server ./public --cors -p 3000 &",
"simpleserver": "http-server ./public --cors -p 3000", "simpleserver": "http-server ./public --cors -p 3000",
"eject": "react-scripts eject",
"fmt": "prettier --write ./src/**/*.{ts,tsx,js} && prettier --write ./src/**/**/*.{ts,tsx,js}", "fmt": "prettier --write ./src/**/*.{ts,tsx,js} && prettier --write ./src/**/**/*.{ts,tsx,js}",
"remove-importmeta": "sed -i '' 's/import.meta.url//g' \"./src/wasm-lib/pkg/wasm_lib.js\"", "build:wasm": "yarn wasm-prep && (cd src/wasm-lib && wasm-pack build --target web --out-dir pkg) && cp src/wasm-lib/pkg/wasm_lib_bg.wasm public && yarn fmt && yarn remove-importmeta",
"remove-importmeta:ci": "sed -i 's/import.meta.url//g' \"./src/wasm-lib/pkg/wasm_lib.js\"", "remove-importmeta": "sed -i 's/import.meta.url//g' \"./src/wasm-lib/pkg/wasm_lib.js\"; sed -i '' 's/import.meta.url//g' \"./src/wasm-lib/pkg/wasm_lib.js\" || echo \"sed for both mac and linux\"",
"add-missing-import": "echo \"import util from 'util'; if (typeof window !== 'undefined' && !window.TextEncoder) { window.TextEncoder = util.TextEncoder; window.TextDecoder = util.TextDecoder}\" | cat - ./src/wasm-lib/pkg/wasm_lib.js > temp && mv temp ./src/wasm-lib/pkg/wasm_lib.js", "wasm-prep": "rm -rf src/wasm-lib/pkg && mkdir src/wasm-lib/pkg",
"build:wasm:ci": "mkdir src/wasm-lib/pkg; cd src/wasm-lib && wasm-pack build --target web --out-dir pkg && cd ../../ && cp src/wasm-lib/pkg/wasm_lib_bg.wasm public && yarn remove-importmeta:ci && yarn add-missing-import && yarn fmt", "lint": "eslint --fix src"
"build:wasm": "mkdir src/wasm-lib/pkg; cd src/wasm-lib && wasm-pack build --target web --out-dir pkg && cd ../../ && cp src/wasm-lib/pkg/wasm_lib_bg.wasm public && yarn remove-importmeta && yarn add-missing-import && yarn fmt"
},
"jest": {
"transformIgnorePatterns": [
"node_modules/(?!(three|allotment|@tauri-apps/api)/)"
]
}, },
"prettier": { "prettier": {
"trailingComma": "es5", "trailingComma": "es5",
@ -69,18 +61,6 @@
"semi": false, "semi": false,
"singleQuote": true "singleQuote": true
}, },
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
],
"rules": {
"semi": [
"error",
"never"
]
}
},
"browserslist": { "browserslist": {
"production": [ "production": [
">0.2%", ">0.2%",
@ -94,16 +74,28 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-env": "^7.22.9",
"@tauri-apps/cli": "^1.3.1", "@tauri-apps/cli": "^1.3.1",
"@types/crypto-js": "^4.1.1", "@types/crypto-js": "^4.1.1",
"@types/isomorphic-fetch": "^0.0.36",
"@types/uuid": "^9.0.1", "@types/uuid": "^9.0.1",
"@types/ws": "^8.5.5", "@types/ws": "^8.5.5",
"@vitejs/plugin-react": "^4.0.3",
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"babel-jest": "^29.6.1",
"eslint": "^8.44.0",
"eslint-config-react-app": "^7.0.1",
"isomorphic-fetch": "^3.0.0",
"jest": "^29.6.1",
"jest-environment-jsdom": "^29.6.1",
"postcss": "^8.4.19", "postcss": "^8.4.19",
"prettier": "^2.8.0", "prettier": "^2.8.0",
"setimmediate": "^1.0.5", "setimmediate": "^1.0.5",
"tailwindcss": "^3.2.4", "tailwindcss": "^3.2.4",
"ws": "^8.13.0", "ts-jest": "^29.1.1",
"vite": "^4.4.3",
"vite-plugin-eslint": "^1.8.1",
"vite-tsconfig-paths": "^4.2.0",
"yarn": "^1.22.19" "yarn": "^1.22.19"
} }
} }

View File

@ -49,6 +49,7 @@ export function App() {
setIsStreamReady, setIsStreamReady,
isStreamReady, isStreamReady,
token, token,
formatCode,
} = useStore((s) => ({ } = useStore((s) => ({
editorView: s.editorView, editorView: s.editorView,
setEditorView: s.setEditorView, setEditorView: s.setEditorView,
@ -74,7 +75,8 @@ export function App() {
setMediaStream: s.setMediaStream, setMediaStream: s.setMediaStream,
isStreamReady: s.isStreamReady, isStreamReady: s.isStreamReady,
setIsStreamReady: s.setIsStreamReady, setIsStreamReady: s.setIsStreamReady,
token: s.token token: s.token,
formatCode: s.formatCode,
})) }))
// const onChange = React.useCallback((value: string, viewUpdate: ViewUpdate) => { // const onChange = React.useCallback((value: string, viewUpdate: ViewUpdate) => {
const onChange = (value: string, viewUpdate: ViewUpdate) => { const onChange = (value: string, viewUpdate: ViewUpdate) => {
@ -262,13 +264,13 @@ export function App() {
<SetToken /> <SetToken />
<div className="h-full flex flex-col items-start"> <div className="h-full flex flex-col items-start">
<PanelHeader title="Editor" /> <PanelHeader title="Editor" />
{/* <button <button
disabled={!shouldFormat} // disabled={!shouldFormat}
onClick={formatCode} onClick={formatCode}
className={`${!shouldFormat && 'text-gray-300'}`} // className={`${!shouldFormat && 'text-gray-300'}`}
> >
format format
</button> */} </button>
<div <div
className="bg-red h-full w-full overflow-auto" className="bg-red h-full w-full overflow-auto"
id="code-mirror-override" id="code-mirror-override"

View File

@ -1,9 +1,9 @@
@import '../node_modules/allotment/dist/style.css';
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
@import '../node_modules/allotment/dist/style.css';
@import './colors.css';
body { body {
margin: 0; margin: 0;

View File

@ -29,7 +29,7 @@ describe('findClosingBrace', () => {
}) })
describe('testing AST', () => { describe('testing AST', () => {
test('test 5 + 6', () => { test('5 + 6', () => {
const tokens = lexer('5 +6') const tokens = lexer('5 +6')
const result = abstractSyntaxTree(tokens) const result = abstractSyntaxTree(tokens)
delete (result as any).nonCodeMeta delete (result as any).nonCodeMeta
@ -66,7 +66,7 @@ describe('testing AST', () => {
], ],
}) })
}) })
test('test const myVar = 5', () => { test('const myVar = 5', () => {
const tokens = lexer('const myVar = 5') const tokens = lexer('const myVar = 5')
const { body } = abstractSyntaxTree(tokens) const { body } = abstractSyntaxTree(tokens)
expect(body).toEqual([ expect(body).toEqual([
@ -98,7 +98,7 @@ describe('testing AST', () => {
}, },
]) ])
}) })
test('test multi-line', () => { test('multi-line', () => {
const code = `const myVar = 5 const code = `const myVar = 5
const newVar = myVar + 1 const newVar = myVar + 1
` `
@ -171,7 +171,7 @@ const newVar = myVar + 1
}, },
]) ])
}) })
test('test using std function "log"', () => { test('using std function "log"', () => {
const code = `log(5, "hello", aIdentifier)` const code = `log(5, "hello", aIdentifier)`
const tokens = lexer(code) const tokens = lexer(code)
const { body } = abstractSyntaxTree(tokens) const { body } = abstractSyntaxTree(tokens)
@ -1392,7 +1392,7 @@ describe('testing pipe operator special', () => {
}) })
describe('nests binary expressions correctly', () => { describe('nests binary expressions correctly', () => {
it('it works with the simple case', () => { it('works with the simple case', () => {
const code = `const yo = 1 + 2` const code = `const yo = 1 + 2`
const { body } = abstractSyntaxTree(lexer(code)) const { body } = abstractSyntaxTree(lexer(code))
expect(body[0]).toEqual({ expect(body[0]).toEqual({
@ -1435,7 +1435,7 @@ describe('nests binary expressions correctly', () => {
], ],
}) })
}) })
it('it should nest according to precedence with multiply first', () => { it('should nest according to precedence with multiply first', () => {
// should be binExp { binExp { lit-1 * lit-2 } + lit} // should be binExp { binExp { lit-1 * lit-2 } + lit}
const code = `const yo = 1 * 2 + 3` const code = `const yo = 1 * 2 + 3`
const { body } = abstractSyntaxTree(lexer(code)) const { body } = abstractSyntaxTree(lexer(code))
@ -1492,7 +1492,7 @@ describe('nests binary expressions correctly', () => {
], ],
}) })
}) })
it('it should nest according to precedence with sum first', () => { it('should nest according to precedence with sum first', () => {
// should be binExp { lit-1 + binExp { lit-2 * lit-3 } } // should be binExp { lit-1 + binExp { lit-2 * lit-3 } }
const code = `const yo = 1 + 2 * 3` const code = `const yo = 1 + 2 * 3`
const { body } = abstractSyntaxTree(lexer(code)) const { body } = abstractSyntaxTree(lexer(code))
@ -1549,7 +1549,7 @@ describe('nests binary expressions correctly', () => {
], ],
}) })
}) })
it('it should nest properly with two opperators of equal precedence', () => { it('should nest properly with two opperators of equal precedence', () => {
const code = `const yo = 1 + 2 - 3` const code = `const yo = 1 + 2 - 3`
const { body } = abstractSyntaxTree(lexer(code)) const { body } = abstractSyntaxTree(lexer(code))
expect((body[0] as any).declarations[0].init).toEqual({ expect((body[0] as any).declarations[0].init).toEqual({
@ -1586,7 +1586,7 @@ describe('nests binary expressions correctly', () => {
}, },
}) })
}) })
it('it should nest properly with two opperators of equal (but higher) precedence', () => { it('should nest properly with two opperators of equal (but higher) precedence', () => {
const code = `const yo = 1 * 2 / 3` const code = `const yo = 1 * 2 / 3`
const { body } = abstractSyntaxTree(lexer(code)) const { body } = abstractSyntaxTree(lexer(code))
expect((body[0] as any).declarations[0].init).toEqual({ expect((body[0] as any).declarations[0].init).toEqual({
@ -1623,7 +1623,7 @@ describe('nests binary expressions correctly', () => {
}, },
}) })
}) })
it('it should nest properly with longer example', () => { it('should nest properly with longer example', () => {
const code = `const yo = 1 + 2 * (3 - 4) / 5 + 6` const code = `const yo = 1 + 2 * (3 - 4) / 5 + 6`
const { body } = abstractSyntaxTree(lexer(code)) const { body } = abstractSyntaxTree(lexer(code))
const init = (body[0] as any).declarations[0].init const init = (body[0] as any).declarations[0].init

View File

@ -53,7 +53,7 @@ describe('parseExpression', () => {
}, },
}) })
}) })
it('parses a more complex expression with parentheses with more ', () => { it('parses a more complex expression with parentheses with more', () => {
const result = parseExpression(lexer('1 * ( 2 + 3 ) / 4')) const result = parseExpression(lexer('1 * ( 2 + 3 ) / 4'))
expect(result).toEqual({ expect(result).toEqual({
type: 'BinaryExpression', type: 'BinaryExpression',
@ -78,7 +78,7 @@ describe('parseExpression', () => {
right: { type: 'Literal', value: 4, raw: '4', start: 16, end: 17 }, right: { type: 'Literal', value: 4, raw: '4', start: 16, end: 17 },
}) })
}) })
it('same as last one but with a 1 + at the start ', () => { it('same as last one but with a 1 + at the start', () => {
const result = parseExpression(lexer('1 + ( 2 + 3 ) / 4')) const result = parseExpression(lexer('1 + ( 2 + 3 ) / 4'))
expect(result).toEqual({ expect(result).toEqual({
type: 'BinaryExpression', type: 'BinaryExpression',
@ -103,7 +103,7 @@ describe('parseExpression', () => {
}, },
}) })
}) })
it('nested braces ', () => { it('nested braces', () => {
const result = parseExpression(lexer('1 * (( 2 + 3 ) / 4 + 5 )')) const result = parseExpression(lexer('1 * (( 2 + 3 ) / 4 + 5 )'))
expect(result).toEqual({ expect(result).toEqual({
type: 'BinaryExpression', type: 'BinaryExpression',
@ -141,7 +141,7 @@ describe('parseExpression', () => {
}, },
}) })
}) })
it('multiple braces around the same thing ', () => { it('multiple braces around the same thing', () => {
const result = parseExpression(lexer('1 * ((( 2 + 3 )))')) const result = parseExpression(lexer('1 * ((( 2 + 3 )))'))
expect(result).toEqual({ expect(result).toEqual({
type: 'BinaryExpression', type: 'BinaryExpression',

View File

@ -316,32 +316,32 @@ show(mySketch)
}) })
describe('testing math operators', () => { describe('testing math operators', () => {
it('it can sum', async () => { it('can sum', async () => {
const code = ['const myVar = 1 + 2'].join('\n') const code = ['const myVar = 1 + 2'].join('\n')
const { root } = await exe(code) const { root } = await exe(code)
expect(root.myVar.value).toBe(3) expect(root.myVar.value).toBe(3)
}) })
it('it can subtract', async () => { it('can subtract', async () => {
const code = ['const myVar = 1 - 2'].join('\n') const code = ['const myVar = 1 - 2'].join('\n')
const { root } = await exe(code) const { root } = await exe(code)
expect(root.myVar.value).toBe(-1) expect(root.myVar.value).toBe(-1)
}) })
it('it can multiply', async () => { it('can multiply', async () => {
const code = ['const myVar = 1 * 2'].join('\n') const code = ['const myVar = 1 * 2'].join('\n')
const { root } = await exe(code) const { root } = await exe(code)
expect(root.myVar.value).toBe(2) expect(root.myVar.value).toBe(2)
}) })
it('it can divide', async () => { it('can divide', async () => {
const code = ['const myVar = 1 / 2'].join('\n') const code = ['const myVar = 1 / 2'].join('\n')
const { root } = await exe(code) const { root } = await exe(code)
expect(root.myVar.value).toBe(0.5) expect(root.myVar.value).toBe(0.5)
}) })
it('it can modulus', async () => { it('can modulus', async () => {
const code = ['const myVar = 5 % 2'].join('\n') const code = ['const myVar = 5 % 2'].join('\n')
const { root } = await exe(code) const { root } = await exe(code)
expect(root.myVar.value).toBe(1) expect(root.myVar.value).toBe(1)
}) })
it('it can do multiple operations', async () => { it('can do multiple operations', async () => {
const code = ['const myVar = 1 + 2 * 3'].join('\n') const code = ['const myVar = 1 + 2 * 3'].join('\n')
const { root } = await exe(code) const { root } = await exe(code)
expect(root.myVar.value).toBe(7) expect(root.myVar.value).toBe(7)
@ -356,7 +356,7 @@ describe('testing math operators', () => {
const { root } = await exe(code) const { root } = await exe(code)
expect(root.myVar.value).toBe(3) expect(root.myVar.value).toBe(3)
}) })
it('with identifier', async () => { it('with lots of testing', async () => {
const code = ['const myVar = 2 * ((2 + 3 ) / 4 + 5)'].join('\n') const code = ['const myVar = 2 * ((2 + 3 ) / 4 + 5)'].join('\n')
const { root } = await exe(code) const { root } = await exe(code)
expect(root.myVar.value).toBe(12.5) expect(root.myVar.value).toBe(12.5)

View File

@ -194,7 +194,7 @@ const part001 = startSketchAt([-1.2, 4.83])
const yo = 5 + 6 const yo = 5 + 6
const yo2 = hmm([identifierGuy + 5]) const yo2 = hmm([identifierGuy + 5])
show(part001)` show(part001)`
it('should move a value into a new variable', async () => { it('should move a binary expression into a new variable', async () => {
const ast = abstractSyntaxTree(lexer(code)) const ast = abstractSyntaxTree(lexer(code))
const programMemory = await enginelessExecutor(ast) const programMemory = await enginelessExecutor(ast)
const startIndex = code.indexOf('100 + 100') + 1 const startIndex = code.indexOf('100 + 100') + 1
@ -222,7 +222,7 @@ show(part001)`
expect(newCode).toContain(`const newVar = 2.8`) expect(newCode).toContain(`const newVar = 2.8`)
expect(newCode).toContain(`line([newVar, 0], %)`) expect(newCode).toContain(`line([newVar, 0], %)`)
}) })
it('should move a value into a new variable', async () => { it('should move a callExpression into a new variable', async () => {
const ast = abstractSyntaxTree(lexer(code)) const ast = abstractSyntaxTree(lexer(code))
const programMemory = await enginelessExecutor(ast) const programMemory = await enginelessExecutor(ast)
const startIndex = code.indexOf('def(') const startIndex = code.indexOf('def(')
@ -236,7 +236,7 @@ show(part001)`
expect(newCode).toContain(`const newVar = def('yo')`) expect(newCode).toContain(`const newVar = def('yo')`)
expect(newCode).toContain(`angledLine([newVar, 3.09], %)`) expect(newCode).toContain(`angledLine([newVar, 3.09], %)`)
}) })
it('should move a value into a new variable', async () => { it('should move a binary expression with call expression into a new variable', async () => {
const ast = abstractSyntaxTree(lexer(code)) const ast = abstractSyntaxTree(lexer(code))
const programMemory = await enginelessExecutor(ast) const programMemory = await enginelessExecutor(ast)
const startIndex = code.indexOf('jkl(') + 1 const startIndex = code.indexOf('jkl(') + 1
@ -250,7 +250,7 @@ show(part001)`
expect(newCode).toContain(`const newVar = jkl('yo') + 2`) expect(newCode).toContain(`const newVar = jkl('yo') + 2`)
expect(newCode).toContain(`angledLine([newVar, 3.09], %)`) expect(newCode).toContain(`angledLine([newVar, 3.09], %)`)
}) })
it('should move a value into a new variable', async () => { it('should move a identifier into a new variable', async () => {
const ast = abstractSyntaxTree(lexer(code)) const ast = abstractSyntaxTree(lexer(code))
const programMemory = await enginelessExecutor(ast) const programMemory = await enginelessExecutor(ast)
const startIndex = code.indexOf('identifierGuy +') + 1 const startIndex = code.indexOf('identifierGuy +') + 1

View File

@ -173,7 +173,7 @@ show(part001)`
}) })
describe('testing isTypeInValue', () => { describe('testing isTypeInValue', () => {
it('it finds the pipeSubstituion', () => { it('finds the pipeSubstituion', () => {
const val = createCallExpression('yoyo', [ const val = createCallExpression('yoyo', [
createArrayExpression([ createArrayExpression([
createLiteral(1), createLiteral(1),
@ -201,7 +201,7 @@ describe('testing getNodePathFromSourceRange', () => {
|> line([0.94, 2.61], %) |> line([0.94, 2.61], %)
|> line([-0.21, -1.4], %) |> line([-0.21, -1.4], %)
show(part001)` show(part001)`
it('it finds the second line when cursor is put at the end', () => { it('finds the second line when cursor is put at the end', () => {
const searchLn = `line([0.94, 2.61], %)` const searchLn = `line([0.94, 2.61], %)`
const sourceIndex = code.indexOf(searchLn) + searchLn.length const sourceIndex = code.indexOf(searchLn) + searchLn.length
const ast = abstractSyntaxTree(lexer(code)) const ast = abstractSyntaxTree(lexer(code))
@ -216,7 +216,7 @@ show(part001)`
[1, 'index'], [1, 'index'],
]) ])
}) })
it('it finds the last line when cursor is put at the end', () => { it('finds the last line when cursor is put at the end', () => {
const searchLn = `line([-0.21, -1.4], %)` const searchLn = `line([-0.21, -1.4], %)`
const sourceIndex = code.indexOf(searchLn) + searchLn.length const sourceIndex = code.indexOf(searchLn) + searchLn.length
const ast = abstractSyntaxTree(lexer(code)) const ast = abstractSyntaxTree(lexer(code))

View File

@ -1,5 +1,5 @@
import { getAngle } from '../../lib/utils' import { getAngle } from '../../lib/utils'
import { Selection, TooTip, toolTips } from '../../useStore' import { TooTip, toolTips } from '../../useStore'
import { import {
Program, Program,
VariableDeclarator, VariableDeclarator,

View File

@ -50,7 +50,7 @@ describe('testing getConstraintType', () => {
it('testing xLine', () => { it('testing xLine', () => {
expect(helper2(`xLine(5, %)`)).toBe('yRelative') expect(helper2(`xLine(5, %)`)).toBe('yRelative')
}) })
it('testing xLine', () => { it('testing yLine', () => {
expect(helper2(`yLine(5, %)`)).toBe('xRelative') expect(helper2(`yLine(5, %)`)).toBe('xRelative')
}) })
it('testing xLineTo', () => { it('testing xLineTo', () => {
@ -197,7 +197,7 @@ const part001 = startSketchAt([0, 0])
|> xLine(segLen('seg01', %), %) // ln-xLineTo-free should convert to xLine |> xLine(segLen('seg01', %), %) // ln-xLineTo-free should convert to xLine
|> yLine(segLen('seg01', %), %) // ln-yLineTo-free should convert to yLine |> yLine(segLen('seg01', %), %) // ln-yLineTo-free should convert to yLine
show(part001)` show(part001)`
it('It should transform the ast', async () => { it('should transform the ast', async () => {
const ast = abstractSyntaxTree(lexer(inputScript)) const ast = abstractSyntaxTree(lexer(inputScript))
const selectionRanges: Selections['codeBasedSelections'] = inputScript const selectionRanges: Selections['codeBasedSelections'] = inputScript
.split('\n') .split('\n')
@ -256,7 +256,7 @@ const part001 = startSketchAt([0, 0])
|> angledLineToX([333, myVar3], %) // select for horizontal constraint 10 |> angledLineToX([333, myVar3], %) // select for horizontal constraint 10
|> angledLineToY([301, myVar], %) // select for vertical constraint 10 |> angledLineToY([301, myVar], %) // select for vertical constraint 10
show(part001)` show(part001)`
it('It should transform horizontal lines the ast', async () => { it('should transform horizontal lines the ast', async () => {
const expectModifiedScript = `const myVar = 2 const expectModifiedScript = `const myVar = 2
const myVar2 = 12 const myVar2 = 12
const myVar3 = -10 const myVar3 = -10
@ -313,7 +313,7 @@ show(part001)`
const newCode = recast(newAst) const newCode = recast(newAst)
expect(newCode).toBe(expectModifiedScript) expect(newCode).toBe(expectModifiedScript)
}) })
it('It should transform vertical lines the ast', async () => { it('should transform vertical lines the ast', async () => {
const expectModifiedScript = `const myVar = 2 const expectModifiedScript = `const myVar = 2
const myVar2 = 12 const myVar2 = 12
const myVar3 = -10 const myVar3 = -10

View File

@ -318,7 +318,7 @@ const yo = 6`)
"number '6' from 46 to 47", "number '6' from 46 to 47",
]) ])
}) })
it('testing tokenising line comments', () => { it('testing tokenising line comments by itself', () => {
const result = stringSummaryLexer(`log('hi') const result = stringSummaryLexer(`log('hi')
// comment on a line by itself // comment on a line by itself
const yo=45`) const yo=45`)

View File

@ -1,20 +1,6 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom' import '@testing-library/jest-dom'
import WebSocket from 'ws'; import util from 'util'
import 'setimmediate' import fetch from 'isomorphic-fetch'
class WebsocketWrapper {
constructor(url: string) {
return new WebSocket(url, {
headers: {
'Autherization': `Bearer ${process.env.KITTYCAD_TOKEN}`,
}
})
}
}
class MockRTCPeerConnection { class MockRTCPeerConnection {
constructor() { constructor() {
@ -51,4 +37,8 @@ class MockRTCPeerConnection {
// @ts-ignore // @ts-ignore
global.RTCPeerConnection = MockRTCPeerConnection global.RTCPeerConnection = MockRTCPeerConnection
// @ts-ignore // @ts-ignore
global.WebSocket = WebsocketWrapper global.fetch = fetch
// @ts-ignore
global.TextDecoder = util.TextDecoder
global.TextEncoder = util.TextEncoder

View File

@ -1,6 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es5", "target": "esnext",
"lib": [ "lib": [
"dom", "dom",
"dom.iterable", "dom.iterable",
@ -13,7 +13,7 @@
"strict": true, "strict": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"module": "esnext", "module": "CommonJS",
"moduleResolution": "node", "moduleResolution": "node",
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
@ -22,5 +22,6 @@
}, },
"include": [ "include": [
"src" "src"
] ],
"references": [{ "path": "./tsconfig.node.json" }]
} }

9
tsconfig.node.json Normal file
View File

@ -0,0 +1,9 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}

1
vite-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

18
vite.config.ts Normal file
View File

@ -0,0 +1,18 @@
import react from '@vitejs/plugin-react'
import viteTsconfigPaths from 'vite-tsconfig-paths'
import eslint from 'vite-plugin-eslint'
export default {
server: {
open: true,
port: 3000,
},
build: {
outDir: 'build',
},
plugins: [
react(),
viteTsconfigPaths(),
eslint(),
],
}

8689
yarn.lock

File diff suppressed because it is too large Load Diff