Skip to content

Commit 0cf005e

Browse files
committed
started writing tests, edited testing.md
1 parent 9477cc3 commit 0cf005e

File tree

7 files changed

+1423
-426
lines changed

7 files changed

+1423
-426
lines changed

client/__test__/mocks/styleMock.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = {};

client/index.integration.test.jsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import { setupServer } from 'msw/node';
4+
import { rest } from 'msw';
5+
6+
jest.mock('./i18n');
7+
8+
const server = setupServer(
9+
rest.get('/session', (req, res, ctx) =>
10+
res(ctx.json({ greeting: 'hello there' }))
11+
)
12+
);
13+
14+
beforeAll(() => server.listen());
15+
afterEach(() => server.resetHandlers());
16+
afterAll(() => server.close());
17+
18+
describe('Application root', () => {
19+
it('should render without crashing', () => {
20+
const div = document.createElement('div');
21+
div.id = 'root';
22+
document.body.appendChild(div);
23+
// require("./index.jsx");
24+
// expect(ReactDOM.render).toHaveBeenCalledWith(<App />, div);
25+
});
26+
});
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import configureStore from 'redux-mock-store';
3+
import thunk from 'redux-thunk';
4+
import axios from 'axios';
5+
import { act } from 'react-dom/test-utils';
6+
import Editor from './Editor';
7+
import {
8+
reduxRender,
9+
fireEvent,
10+
screen,
11+
within,
12+
prettyDOM
13+
} from '../../../test-utils';
14+
import { initialTestState } from '../../../redux_test_stores/test_store';
15+
16+
jest.mock('../../../i18n');
17+
18+
describe('<Editor />', () => {
19+
const mockStore = configureStore([thunk]);
20+
const store = mockStore(initialTestState);
21+
22+
const subjectProps = { provideController: jest.fn() };
23+
24+
const subject = () => reduxRender(<Editor {...subjectProps} />, { store });
25+
26+
beforeEach(() => {
27+
axios.get.mockImplementationOnce((x) => Promise.resolve({ data: 'foo' }));
28+
});
29+
30+
afterEach(() => {
31+
store.clearActions();
32+
});
33+
34+
it('renders successfully', () => {
35+
act(() => {
36+
subject();
37+
});
38+
});
39+
});

client/redux_test_stores/test_store.js

Lines changed: 98 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,87 @@ const mockProjects = [
1818
];
1919

2020
const initialTestState = {
21-
ide: null,
22-
files: [],
23-
preferences: {},
21+
ide: {
22+
isPlaying: false,
23+
isAccessibleOutputPlaying: false,
24+
modalIsVisible: false,
25+
sidebarIsExpanded: false,
26+
consoleIsExpanded: true,
27+
preferencesIsVisible: false,
28+
projectOptionsVisible: false,
29+
newFolderModalVisible: false,
30+
uploadFileModalVisible: false,
31+
shareModalVisible: false,
32+
shareModalProjectId: 'abcd',
33+
shareModalProjectName: 'My Cute Sketch',
34+
shareModalProjectUsername: 'p5_user',
35+
editorOptionsVisible: false,
36+
keyboardShortcutVisible: false,
37+
unsavedChanges: false,
38+
infiniteLoop: false,
39+
previewIsRefreshing: false,
40+
infiniteLoopMessage: '',
41+
justOpenedProject: false,
42+
previousPath: '/',
43+
errorType: undefined,
44+
runtimeErrorWarningVisible: true,
45+
parentId: undefined
46+
},
47+
files: [
48+
{
49+
name: 'root',
50+
id: '606fc1c46045e19ca2ee2648',
51+
_id: '606fc1c46045e19ca2ee2648',
52+
children: [
53+
'606fc1c46045e19ca2ee2646',
54+
'606fc1c46045e19ca2ee2645',
55+
'606fc1c46045e19ca2ee2647'
56+
],
57+
fileType: 'folder',
58+
content: ''
59+
},
60+
{
61+
name: 'sketch.js',
62+
content:
63+
'function setup() { createCanvas(400, 400); } function draw() { background(220); }',
64+
id: '606fc1c46045e19ca2ee2645',
65+
_id: '606fc1c46045e19ca2ee2645',
66+
isSelectedFile: true,
67+
fileType: 'file',
68+
children: []
69+
},
70+
{
71+
name: 'index.html',
72+
content: `<!DOCTYPE html> <html lang="en"> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.2.0/p5.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.2.0/addons/p5.sound.min.js"></script> <link rel="stylesheet" type="text/css" href="style.css"> <meta charset="utf-8" /> </head> <body> <script src="sketch.js"></script> </body> </html>`,
73+
id: '606fc1c46045e19ca2ee2646',
74+
_id: '606fc1c46045e19ca2ee2646',
75+
fileType: 'file',
76+
children: []
77+
},
78+
{
79+
name: 'style.css',
80+
content:
81+
'html, body { margin: 0; padding: 0; } canvas { display: block; } ',
82+
id: '606fc1c46045e19ca2ee2647',
83+
_id: '606fc1c46045e19ca2ee2647',
84+
fileType: 'file',
85+
children: []
86+
}
87+
],
88+
preferences: {
89+
fontSize: 18,
90+
autosave: true,
91+
linewrap: true,
92+
lineNumbers: true,
93+
lintWarning: false,
94+
textOutput: false,
95+
gridOutput: false,
96+
soundOutput: false,
97+
theme: 'light',
98+
autorefresh: false,
99+
language: 'en-US',
100+
autocloseBracketsQuotes: true
101+
},
24102
user: {
25103
26104
username: 'happydog',
@@ -31,7 +109,11 @@ const initialTestState = {
31109
totalSize: 0,
32110
authenticated: true
33111
},
34-
project: null,
112+
project: {
113+
name: 'Zealous sunflower',
114+
updatedAt: '',
115+
isSaving: false
116+
},
35117
sketches: mockProjects,
36118
search: {
37119
collectionSearchTerm: '',
@@ -41,10 +123,19 @@ const initialTestState = {
41123
field: 'createdAt',
42124
direction: 'DESCENDING'
43125
},
44-
editorAccessibility: {},
45-
toast: {},
126+
editorAccessibility: {
127+
lintMessages: [],
128+
forceDesktop: false
129+
},
130+
toast: {
131+
isVisible: false,
132+
text: ''
133+
},
46134
console: [],
47-
assets: {},
135+
assets: {
136+
list: [],
137+
totalSize: 0
138+
},
48139
loading: false,
49140
collections: []
50141
};

developer_docs/testing.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ In unit tests, you're testing the functionality of a single component and no mor
6666
In both of these cases, the component being tested is not merely an implementation detail. Thus, it's important for the unit tests to test the error cases that could occur to ensure that the component is robust. For example, for a user-facing input field that should only take positive numbers, a unit test would want to cover what happens when users enter negative numbers or letters.
6767

6868
### Integration tests
69-
Testing multiple components together. A small example is rendering a parent component in order to test the interactions between children components. Generally, they validate how multiple units of your application work together. Jest, which is what we use, uses jsdom under the hood to emulate common browser APIs with less overhead than automation like a headless browser, and its mocking tools can stub out external API calls. We use integration tests to maximize coverage and to make sure all the pieces play nice together. We want our integration tests to cover the testing of components that don't have unit tests because they're only used in one place and are merely an implementation detail. The integration tests can test the "happy path" flow, while we expect the unit tests to have tested the error cases already.
69+
Testing multiple components together. A small example is rendering a parent component in order to test the interactions between children components. Generally, they validate how multiple units of your application work together. Jest, which is what we use, uses jsdom under the hood to emulate common browser APIs with less overhead than automation like a headless browser, and its mocking tools can stub out external API calls. We use integration tests to maximize coverage and to make sure all the pieces play nice together. We want our integration tests to cover the testing of components that don't have unit tests because they're only used in one place and are merely an implementation detail. The integration tests can test the expected user flows, while we expect the unit tests to have tested the error cases more rigorously.
7070

7171
See [this great article on CSS tricks](https://css-tricks.com/react-integration-testing-greater-coverage-fewer-tests/) about integration tests for more information about this.
7272

73-
To reiterate, we use integration tests to test our "happy path" flows and maximize coverage on individual components that are only used once. We use unit tests to test the robustness of user-facing components and reusable components.
73+
To reiterate, we use integration tests to maximize coverage on individual components that are only used once. We use unit tests to test the robustness of user-facing components and reusable components.
7474

7575
### Snapshot testing
7676
You can save a snapshot of what the HTML looks like when the component is rendered.
@@ -173,7 +173,6 @@ You can also see it used in the context of a test [in the SketchList.test.jsx fi
173173
### Folder structure
174174
All tests are directly adjacent to the files that they are testing, as described in the [React docs](https://reactjs.org/docs/faq-structure.html#grouping-by-file-type). For example, if you're testing ``examplefolder/Sketchlist.test.jsx``, the test would be in ``examplefolder/Sketchlist.test.jsx``. This is so that the tests are as close as possible to the files. This also means that any snapshot files will be stored in the same folder, such as ``examplefolder/__snapshots__/Sketchlist.test.jsx.snap``
175175

176-
CASSIE - WHERE DO WE PUT THE INTEGRATION TESTS?
177176
Integration tests should be adjacent to the components they're testing. They should be called ``ComponentName.integration.test.jsx``
178177
179178
Manual mocks are in ``__mocks__`` folders are adjacent to the modules that they're mocking.

0 commit comments

Comments
 (0)