Skip to content

Commit

Permalink
add tests + codecov
Browse files Browse the repository at this point in the history
  • Loading branch information
bony2023 committed Jun 14, 2022
1 parent 6b2d0ef commit c77e141
Show file tree
Hide file tree
Showing 12 changed files with 1,806 additions and 1,821 deletions.
5 changes: 5 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
coverage:
status:
project:
default:
target: 90%
2 changes: 1 addition & 1 deletion .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ jobs:
node-version: 16.15.1
- run: yarn install
- run: ./node_modules/.bin/npm-install-peers
- run: yarn test
- run: yarn test && ./node_modules/.bin/codecov -t ${{secrets.CODECOV_REPO_TOKEN}}
18 changes: 13 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,17 @@
},
"homepage": "https://github.com/bony2023/react-terminal#readme",
"devDependencies": {
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^14.2.0",
"@types/enzyme": "^3.10.4",
"@types/enzyme-adapter-react-16": "^1.0.5",
"@types/jest": "^24.0.25",
"@types/jest": "^28.1.1",
"@types/react": "^18.0.12",
"@types/react-dom": "^18.0.5",
"@types/react-test-renderer": "^16.9.1",
"@typescript-eslint/eslint-plugin": "^2.14.0",
"@typescript-eslint/parser": "^2.14.0",
"codecov": "^3.6.1",
"cross-env": "^7.0.3",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
Expand All @@ -52,26 +55,32 @@
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-react-hooks": "^4.5.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^24.9.0",
"jest": "^28.1.1",
"jest-environment-jsdom": "^28.1.1",
"npm-install-peers": "^1.2.1",
"react-test-renderer": "^17.0.2",
"rollup": "^2.75.6",
"rollup-plugin-postcss": "^3.1.8",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.32.1",
"sass": "^1.52.3",
"source-map-loader": "^4.0.0",
"ts-jest": "^24.2.0",
"ts-jest": "^28.0.5",
"ts-loader": "^9.3.0",
"typescript": "^4.3.5",
"webpack": "^5.73.0",
"webpack-cli": "^4.9.2"
},
"resolutions": {
"cheerio": "1.0.0-rc.10"
},
"peerDependencies": {
"prop-types": "^15.7.2",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"jest": {
"testEnvironment": "jsdom",
"setupFiles": [
"<rootDir>/tests/setupTests.ts"
],
Expand Down Expand Up @@ -100,7 +109,6 @@
},
"dependencies": {
"prop-types": "^15.7.2",
"react-device-detect": "^2.2.2",
"sass": "^1.52.3"
"react-device-detect": "^2.2.2"
}
}
3 changes: 2 additions & 1 deletion src/components/Terminal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default function Terminal(props: any) {
ref={wrapperRef}
id={style.terminalContainer}
className={style[`theme--${theme}`]}
data-testid="terminal"
>
<div className={`${style.terminal}`} style={{ background: themeStyles.themeToolbarColor, color: themeStyles.themeColor }}>
{controls}
Expand All @@ -74,7 +75,7 @@ Terminal.propTypes = {
PropTypes.node
])),
welcomeMessage: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.node]),
errorMessage: PropTypes.oneOfType([PropTypes.string, PropTypes.object])
errorMessage: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.node])
};

Terminal.defaultProps = {
Expand Down
3 changes: 1 addition & 2 deletions src/hooks/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const useEditorInput = (
navigator.clipboard.readText()
.then(pastedText => {
const [caretTextBefore, caretTextAfter] = Utils.splitStringAtIndex(editorInput || "", caretPosition);
nextInput = nextInput = caretTextBefore + pastedText + caretTextAfter;
nextInput = caretTextBefore + pastedText + caretTextAfter;
setCaretPosition(caretPosition + pastedText.length);
setEditorInput(nextInput);
});
Expand Down Expand Up @@ -152,7 +152,6 @@ export const useBufferedContent = (
setCaretPosition(0);
setBeforeCaretText("");
setAfterCaretText("");


if (text) {
const commandArguments = rest.join(" ");
Expand Down
179 changes: 179 additions & 0 deletions tests/integration/components/Terminal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { act } from 'react-dom/test-utils';
import { ReactTerminal, TerminalContextProvider } from "../../../src";

describe('ReactTerminal', () => {
test('renders ReactTerminal component', () => {
render(
<TerminalContextProvider>
<ReactTerminal/>
</TerminalContextProvider>
);
});

test('selects terminal component', async () => {
render(
<TerminalContextProvider>
<ReactTerminal/>
</TerminalContextProvider>
);

await userEvent.click(screen.getByTestId('terminal'));
});

test('write some text on terminal component', () => {
const { container } = render(
<TerminalContextProvider>
<ReactTerminal/>
</TerminalContextProvider>
);

const terminalContainer = screen.getByTestId('terminal')
writeText(terminalContainer, 'invalid_command');
expect(container.querySelector('.lineText')?.textContent).toBe('invalid_command');
});

test('execute an invalid command on terminal component returns default text', () => {
const { container } = render(
<TerminalContextProvider>
<ReactTerminal/>
</TerminalContextProvider>
);

const terminalContainer = screen.getByTestId('terminal')
writeText(terminalContainer, 'invalid_command');
writeText(terminalContainer, 'Enter');
expect(container.textContent).toContain('not found!');
});

test('execute a valid command on terminal component', () => {
const { container } = render(
<TerminalContextProvider>
<ReactTerminal commands={{ whoami: 'jackharper' }}/>
</TerminalContextProvider>
);

const terminalContainer = screen.getByTestId('terminal')
writeText(terminalContainer, 'whoami');
writeText(terminalContainer, 'Enter');
expect(container.textContent).toContain('jackharper');
});

test('backspace deletes a character', () => {
const { container } = render(
<TerminalContextProvider>
<ReactTerminal commands={{ whoami: 'jackharper' }}/>
</TerminalContextProvider>
);

const terminalContainer = screen.getByTestId('terminal')
writeText(terminalContainer, 'whoami');
writeText(terminalContainer, 'Backspace');
expect(container.textContent).toContain('whoam');
writeText(terminalContainer, 'i');
writeText(terminalContainer, 'Enter');
expect(container.textContent).toContain('jackharper');
});

test('up arrow fetch previous command', () => {
const { container } = render(
<TerminalContextProvider>
<ReactTerminal commands={{ whoami: 'jackharper' }}/>
</TerminalContextProvider>
);

const terminalContainer = screen.getByTestId('terminal')
writeText(terminalContainer, 'whoami');
writeText(terminalContainer, 'Enter');
writeText(terminalContainer, 'ArrowUp');
expect(screen.getAllByText("whoami").length).toBe(2);
});

test('down arrow fetch next command', () => {
const { container } = render(
<TerminalContextProvider>
<ReactTerminal commands={{ whoami: 'jackharper' }}/>
</TerminalContextProvider>
);

const terminalContainer = screen.getByTestId('terminal')
writeText(terminalContainer, 'ArrowUp');
expect(container.querySelectorAll('.preWhiteSpace')[0].textContent).toBe('');
expect(container.querySelectorAll('.preWhiteSpace')[1].textContent).toBe('');
writeText(terminalContainer, 'whoami');
writeText(terminalContainer, 'Enter');
writeText(terminalContainer, 'ArrowUp');
expect(screen.getAllByText("whoami").length).toBe(2);
writeText(terminalContainer, 'ArrowUp');
expect(screen.getAllByText("whoami").length).toBe(2);
writeText(terminalContainer, 'ArrowDown');
expect(screen.getAllByText("whoami").length).toBe(1);
writeText(terminalContainer, 'ArrowDown');
expect(screen.getAllByText("whoami").length).toBe(1);
});

test('arrow left/right moves the cursor', () => {
const { container } = render(
<TerminalContextProvider>
<ReactTerminal commands={{ whoami: 'jackharper' }}/>
</TerminalContextProvider>
);

const terminalContainer = screen.getByTestId('terminal')
writeText(terminalContainer, 'whoami');
writeText(terminalContainer, 'ArrowLeft');
expect(container.querySelectorAll('.preWhiteSpace')[0].textContent).toBe('whoam');
expect(container.querySelectorAll('.preWhiteSpace')[1].textContent).toBe('i');
writeText(terminalContainer, 'ArrowRight');
expect(container.querySelectorAll('.preWhiteSpace')[0].textContent).toBe('whoami');
expect(container.querySelectorAll('.preWhiteSpace')[1].textContent).toBe('');
});

test('empty command does nothing', () => {
const { container } = render(
<TerminalContextProvider>
<ReactTerminal commands={{ whoami: 'jackharper' }}/>
</TerminalContextProvider>
);

const terminalContainer = screen.getByTestId('terminal')
writeText(terminalContainer, '');
writeText(terminalContainer, 'Enter');
expect(container.querySelectorAll('.preWhiteSpace')[0].textContent).toBe('');
expect(container.querySelectorAll('.preWhiteSpace')[1].textContent).toBe('');
});

test('clear command clears the console', () => {
const { container } = render(
<TerminalContextProvider>
<ReactTerminal/>
</TerminalContextProvider>
);

const terminalContainer = screen.getByTestId('terminal')
writeText(terminalContainer, 'invalid_command');
writeText(terminalContainer, 'Enter');
writeText(terminalContainer, 'clear');
writeText(terminalContainer, 'Enter');
expect(terminalContainer.textContent).toBe('>>>');
});
});

function writeText(container: any, value: string, metaKey = false) {
if (["Enter", "Backspace", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(value)) {
fireEvent.keyDown(container, {
metaKey: metaKey,
key: value
});
return;
}

value.split('').forEach(char => {
fireEvent.keyDown(container, {
metaKey: metaKey,
key: char
});
})
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Utils from "../../src/common/Utils";
import Utils from "../../../src/common/Utils";

describe("Utils", () => {
it("splitStringAtIndex splits string at a index", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from "react";
import renderer from "react-test-renderer";
import ContextProvider from "../../src/contexts";
import { TerminalContextProvider } from "../../src/contexts/TerminalContext";
import Editor from "../../src/components/Editor";
import ContextProvider from "../../../src/contexts";
import { TerminalContextProvider } from "../../../src/contexts/TerminalContext";
import Editor from "../../../src/components/Editor";

let props: any;
const renderWrapper = () => (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from "react";
import renderer from "react-test-renderer";
import ContextProvider from "../../src/contexts";
import { TerminalContextProvider } from "../../src/contexts/TerminalContext";
import Terminal from "../../src/components/Terminal";
import ContextProvider from "../../../src/contexts";
import { TerminalContextProvider } from "../../../src/contexts/TerminalContext";
import Terminal from "../../../src/components/Terminal";

let props: any;
const renderWrapper = () => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
exports[`Terminal Terminal doesn't render control bar 1`] = `
<div
className="theme--light"
data-testid="terminal"
id="terminalContainer"
>
<div
Expand Down Expand Up @@ -67,6 +68,7 @@ exports[`Terminal Terminal doesn't render control bar 1`] = `
exports[`Terminal Terminal doesn't render control buttons 1`] = `
<div
className="theme--light"
data-testid="terminal"
id="terminalContainer"
>
<div
Expand Down Expand Up @@ -134,6 +136,7 @@ exports[`Terminal Terminal doesn't render control buttons 1`] = `
exports[`Terminal Terminal renders correctly 1`] = `
<div
className="theme--light"
data-testid="terminal"
id="terminalContainer"
>
<div
Expand Down
Loading

0 comments on commit c77e141

Please sign in to comment.