diff --git a/.github/workflows/crypress.yml b/.github/workflows/crypress.yml new file mode 100644 index 0000000..d12a5ae --- /dev/null +++ b/.github/workflows/crypress.yml @@ -0,0 +1,88 @@ +# name: Cypress Tests with Install Job and UI Chrome Job x 5 +# # https://docs.cypress.io/guides/continuous-integration/github-actions#Worker-Jobs +# on: [push] + +# jobs: +# install: +# runs-on: ubuntu-latest +# container: cypress/browsers:node12.18.3-chrome87-ff82 +# steps: +# - name: Checkout +# uses: actions/checkout@v2 + + +# - name: Cypress install +# uses: cypress-io/github-action@v2 +# with: +# # Disable running of tests within install job +# runTests: false +# build: yarn build + +# - name: Save build folder +# uses: actions/upload-artifact@v2 +# with: +# name: dist +# if-no-files-found: error +# path: dist +# ui-chrome-tests: +# runs-on: ubuntu-latest +# container: cypress/browsers:node12.18.3-chrome87-ff82 +# needs: install +# strategy: +# fail-fast: false +# matrix: +# # run copies of the current job in parallel +# # containers: [1, 2, 3, 4, 5] +# containers: [1] +# steps: +# - name: Checkout +# uses: actions/checkout@v2 + +# - name: Download the build folders +# uses: actions/download-artifact@v2 +# with: +# name: dist +# path: dist + +# - name: 'UI Tests - Chrome' +# uses: cypress-io/github-action@v2 +# with: +# # we have already installed all dependencies above +# install: false +# start: yarn start:ci +# wait-on: 'http://localhost:3000' +# wait-on-timeout: 120 +# browser: chrome +# record: true +# parallel: true +# group: 'UI - Chrome' +# spec: cypress/tests/ui/* +# env: +# CYPRESS_RECORD_KEY: ${{ secrets.DASHBOARDRECORDKEY }} +# # Recommended: pass the GitHub token lets this action correctly +# # determine the unique run id necessary to re-run the checks +# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + +name: Chrome headless + +on: push + +jobs: + chrome-headless: + runs-on: ubuntu-18.04 + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: Headless Chrome + uses: cypress-io/github-action@v2 + timeout-minutes: 10 + with: + build: npm run build + start: npm start + browser: chrome + headless: true + record: true + env: + # pass the Dashboard record key as an environment variable + CYPRESS_RECORD_KEY: ${{ secrets.dashboardRecordKey }} \ No newline at end of file diff --git a/README.md b/README.md index 4de993c..cce6b9f 100644 --- a/README.md +++ b/README.md @@ -21,15 +21,67 @@ To build the examples locally, run: ```bash yarn + +yarn start +``` +### NOTE: as of 2024 node doenst support some things im using tofix that run +### if you get code: 'ERR_OSSL_EVP_UNSUPPORTED' error +`export NODE_OPTIONS=--openssl-legacy-provider` + +### Then open `http://localhost:3000` in a browser + + +---------- + +# how to debug regex generator grammer parser +``` +yarn global add nearley +nearleyc grammer.ne -o src/lib/grammer.js +nearley-railroad grammer.ne -o grammar.html +python -m http.server 80 +``` + +# NOTE ALL CYPRESS TESTS ARE CURRENTLY BORKED! broken :/ as of 20240718 +## Locally run integration tests with crypress +```bash yarn start ``` +### in a new tab run +```bash +yarn +yarn run cypress:open +``` + +### Run integration tests with crypress +```bash +yarn +yarn run cy:ci +``` + + +### open grammar.html in your browser to view railroad diagram of grammer +### http://localhost:80/grammar.html + +### Github actions how to setup DASHBOARDRECORDKEY +### [cypress setup api key](https://docs.cypress.io/guides/dashboard/projects#Set-up-a-project-to-record) + + + # [Actions secrets](https://github.com/wisehackermonkey/text-processor-react/settings/secrets/actions) +# [Actions secrets](https://github.com//settings/secrets/actions) + + +# https://dashboard.cypress.io/projects/ + + -### Then open `http://localhost:8886` in a browser. - # TODO add - ~~better css~~ DONE - ~~add localstorage~~ DONE +- add save file button + - add open file - add pastebin save with api key +- add cool colored text visualizer for the regex +- chatgpt plugin with buttons for helper # links [GitHub - react-monaco-editor/react-monaco-editor: Monaco Editor for React.](https://github.com/react-monaco-editor/react-monaco-editor) [Monaco Editor Playground](https://microsoft.github.io/monaco-editor/playground.html#creating-the-editor-editor-basic-options) diff --git a/assets/2021-10-29-17-59-05.png b/assets/2021-10-29-17-59-05.png new file mode 100644 index 0000000..d3f2651 Binary files /dev/null and b/assets/2021-10-29-17-59-05.png differ diff --git a/assets/2021-10-29-17-59-40.png b/assets/2021-10-29-17-59-40.png new file mode 100644 index 0000000..6335c40 Binary files /dev/null and b/assets/2021-10-29-17-59-40.png differ diff --git a/assets/2021-10-29-18-00-50.png b/assets/2021-10-29-18-00-50.png new file mode 100644 index 0000000..841c91f Binary files /dev/null and b/assets/2021-10-29-18-00-50.png differ diff --git a/cypress.json b/cypress.json new file mode 100644 index 0000000..0bd7287 --- /dev/null +++ b/cypress.json @@ -0,0 +1,3 @@ +{ + "projectId": "wu2ucs" + } \ No newline at end of file diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 0000000..02e4254 --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/cypress/integration/sample_spec.js b/cypress/integration/sample_spec.js new file mode 100644 index 0000000..fdaa895 --- /dev/null +++ b/cypress/integration/sample_spec.js @@ -0,0 +1,56 @@ +/// + +describe('My First Test', () => { + it('search replace "type"', () => { + cy.visit('https://wisehackermonkey.github.io/text-processor-react/') + + cy.get('.view-lines').click({ force: true }).type(`test\ntest`) + cy.get('[value="multi_newline"]').click({ force: true }) + + cy.get(':nth-child(2) > :nth-child(3) > :nth-child(2) > .MuiInput-root > #outlined-multiline-static').click({ force: true }).type("###") + cy.get(':nth-child(2) > :nth-child(1) > .MuiButton-root').click({ force: true }) + cy.get('.view-line').should(($div) => { + expect($div.get(0).innerText).to.contain(`test###test`) + }) + }) + + it('generates text', () => { + cy.visit("http://localhost:3000") + cy.get(':nth-child(7) > .css-1p5q5e5-MuiStack-root > :nth-child(3) > :nth-child(1) > .MuiInput-root > #outlined-multiline-static').should($div => { + expect($div.get(0).innerHTML).to.contain("") + }) + cy.get('[value="int"]').click() + cy.get(':nth-child(7) > .css-1p5q5e5-MuiStack-root > :nth-child(3) > :nth-child(1) > .MuiInput-root > #outlined-multiline-static').should($div => { + expect($div.get(0).innerHTML).to.contain("/([0-9]{1,7})/g") + }) + + cy.get(':nth-child(7) > .css-1p5q5e5-MuiStack-root > :nth-child(3) > :nth-child(2) > .MuiInput-root > #outlined-multiline-static').should($div => { + expect($div.get(0).innerHTML).to.contain("") + }) + cy.get(':nth-child(7) > .css-1p5q5e5-MuiStack-root > :nth-child(1) > :nth-child(1)').click() + cy.get(':nth-child(7) > .css-1p5q5e5-MuiStack-root > :nth-child(3) > :nth-child(2) > .MuiInput-root > #outlined-multiline-static').should($div => { + expect($div.get(0).innerHTML.match(/([0-9]{1,7})/g).length >= 1).to.eq(true) + }) + + cy.get('.css-1p5q5e5-MuiStack-root > :nth-child(1) > :nth-child(2)').click() + cy.get('.view-line').should(($div) => { + expect($div.get(0).innerText.match(/([0-9]{1,7})/g).length >= 1).to.eq(true) + }) + cy.get('.css-1p5q5e5-MuiStack-root > .MuiToggleButtonGroup-root > [value="clear"]').click() + + }); + + it('build regex', () => { + cy.visit("http://localhost:3000") + cy.get('.css-1lwbda4-MuiStack-root > .MuiFormControl-root > .MuiInput-root > #outlined-multiline-static').should(($div) => { + expect($div.get(0).innerHTML).to.eq("//g") + }) + + cy.get('.css-1bi0bj-MuiStack-root > :nth-child(1)').click() + cy.get('.css-1lwbda4-MuiStack-root > .MuiFormControl-root > .MuiInput-root > #outlined-multiline-static').should(($div) => { + expect($div.get(0).innerHTML).to.eq("/([\\t\\n\\r]+)/g") + }) + cy.get('[value="ipaddress"]').click() + }); + +}) diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js new file mode 100644 index 0000000..6dd4507 --- /dev/null +++ b/cypress/plugins/index.js @@ -0,0 +1,23 @@ +/// +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +/** + * @type {Cypress.PluginConfig} + */ +// eslint-disable-next-line no-unused-vars +module.exports = (on, config) => { + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config + +} diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 0000000..119ab03 --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) diff --git a/cypress/support/index.js b/cypress/support/index.js new file mode 100644 index 0000000..d68db96 --- /dev/null +++ b/cypress/support/index.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/grammar.html b/grammar.html new file mode 100644 index 0000000..fc44317 --- /dev/null +++ b/grammar.html @@ -0,0 +1,177 @@ + + + + + + + +

main

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +NUMBERS + + + + + + + + + + + + + +LETTERS + + + + + + + + + + + + + + + + + + + + +
+

LETTERS

+
+ + + + + + + + + + + + + + + + + + + +/[a-zA-Z]/ + + + + + + + + + + + + + + + + +
+

NUMBERS

+
+ + + + + + + + + + + + + + + + + + + +int + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/grammer.ne b/grammer.ne new file mode 100644 index 0000000..f82cbd5 --- /dev/null +++ b/grammer.ne @@ -0,0 +1,36 @@ + +@builtin "whitespace.ne" # `_` means arbitrary amount of whitespace +@builtin "number.ne" # `int`, `decimal`, and `percentage` number primitives + +@{% + // Moo lexer documention is here: + // https://github.com/no-context/moo + + const moo = require("moo") + const lexer = moo.compile({ + whitespace: { match: /[\s\t\n]+/, lineBreaks: true }, + number: /[0-9]+/, + word: /[a-zA-Z]+/, + symbols: /[^a-zA-Z0-9\s\t\n\r]+/ + }); + + +const un_nest = (d) =>{ + + return d.flat(10) +} + +%} + +# Pass your lexer with @lexer: +@lexer lexer + + +main -> ( terminals ):* {% d=> un_nest(d[0]) %} + +terminals -> NUMBERS | LETTERS | SYMBOLS | WHITESPACE {% d=> d[0] %} + +LETTERS -> %word {%([first])=>( {"type": first.type,"text":first.text, token: 'LETTERS'}) %} +SYMBOLS -> %symbols {%([first])=>( {"type": first.type,"text":first.text, token: 'SYMBOLS'}) %} +NUMBERS -> %number {%([first])=>( {"type": first.type,"text":first.text, token: 'NUMBERS'}) %} +WHITESPACE -> %whitespace {%([first])=>( {"type": first.type,"text":first.text, token: 'WHITESPACE'}) %} diff --git a/package.json b/package.json index c10f375..e46544c 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,11 @@ "scripts": { "start": "webpack serve --open --config webpack.config.js --hot --inline --progress --port 3000 ", "build": "webpack build --mode production --config webpack.config.js", - "test": "jest" + "test": "jest", + "start-server": "webpack serve --config webpack.config.js --port 3000", + "cy:ci": "START_SERVER_AND_TEST_INSECURE=1 start-server-and-test start-server https-get://localhost:3000 cy:run", + "cy:run": "cypress run", + "cypress:open": "cypress open" }, "authors": [ "Leon Shi ", @@ -22,6 +26,7 @@ "css-loader": "^6.3.0", "jest": "^27.3.1", "monaco-editor-webpack-plugin": "^4.2.0", + "start-server-and-test": "^1.14.0", "style-loader": "^3.3.0", "webpack": "^5.55.1", "webpack-cli": "^4.8.0", @@ -33,14 +38,17 @@ "@fontsource/roboto": "^4.5.1", "@mui/icons-material": "^5.0.5", "@mui/material": "^5.0.6", + "cypress": "^8.7.0", "file-loader": "^6.2.0", "itt": "^0.7.3", "moo": "^0.5.1", + "nearley": "^2.20.1", "pprint": "^0.0.1", "randexp": "^0.5.3", "react": "^17.0.2", "react-dom": "^17.0.2", "react-github-fork-ribbon": "^0.6.0", - "react-monaco-editor": "latest" + "react-monaco-editor": "latest", + "util": "^0.12.4" } } diff --git a/sample_spec.js b/sample_spec.js new file mode 100644 index 0000000..5dce06a --- /dev/null +++ b/sample_spec.js @@ -0,0 +1,5 @@ +describe('My First Test', () => { + it('Does not do much!', () => { + expect(true).to.equal(true) + }) + }) \ No newline at end of file diff --git a/src/PatternSelector.js b/src/PatternSelector.js index 1a0faf7..a06b3cc 100644 --- a/src/PatternSelector.js +++ b/src/PatternSelector.js @@ -18,6 +18,15 @@ import patternParse from "./lib/patternParse"; import { Button } from "@mui/material"; import { Label } from "@mui/icons-material"; +import Parser from "../src/lib/parser" +import h from "./helper" + + +// pipe(input object, ,[,