Skip to content

Commit 41adaa1

Browse files
committed
Add a test for the intersection observer used on the module level
1 parent 34fe531 commit 41adaa1

28 files changed

+7323
-213
lines changed

.babelrc

Lines changed: 0 additions & 6 deletions
This file was deleted.

.eslintrc.js

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
module.exports = {
2-
"env": {
3-
"browser": true,
4-
"es6": true,
5-
"node": true
2+
env: {
3+
browser: true,
4+
es6: true,
5+
node: true
6+
},
7+
extends: [
8+
"eslint:recommended",
9+
"plugin:prettier/recommended",
10+
"plugin:react/recommended",
11+
"plugin:jest/recommended"
12+
],
13+
globals: {
14+
Atomics: "readonly",
15+
SharedArrayBuffer: "readonly"
16+
},
17+
parserOptions: {
18+
ecmaFeatures: {
19+
jsx: true
620
},
7-
"extends": [
8-
"eslint:recommended",
9-
"plugin:react/recommended",
10-
"plugin:jest/recommended"
11-
],
12-
"globals": {
13-
"Atomics": "readonly",
14-
"SharedArrayBuffer": "readonly"
15-
},
16-
"parserOptions": {
17-
"ecmaFeatures": {
18-
"jsx": true
19-
},
20-
"ecmaVersion": 2018,
21-
"sourceType": "module"
22-
},
23-
"plugins": [
24-
"react"
25-
],
26-
"rules": {
27-
}
21+
ecmaVersion: 2018,
22+
sourceType: "module"
23+
},
24+
plugins: ["react", "prettier"],
25+
rules: {
26+
"prettier/prettier": "error"
27+
}
2828
};

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
.DS_Store
22
node_modules
3-
dist
3+
dist
4+
.cache
5+
coverage

.npmignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
.DS_Store
22
node_modules
3-
src
3+
src
4+
coverage
5+
examples

.prettierrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"semi": false,
3+
"singleQuote": true,
4+
"tabWidth": 2,
5+
"useTabs": false
6+
}

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,14 @@ import { mockIntersectionObserver } from 'jsdom-testing-mocks"
6161
const intersectionObserver = mockIntersectionObserver()
6262

6363
it('loads the image when the component is in the viewport', () => {
64-
const { getByAltText, queryByAltText, getByTestId } = render(<TestComponent />)
64+
const { getByAltText, queryByAltText, container } = render(<TestComponent />)
6565

6666
expect(queryByAltText('alt text')).not.toBeInTheDocument()
6767

68-
// when this element is in the viewport - show the image
69-
intersectionObserver.enterNode(getByTestId('trigger'))
68+
// when the component's root node is in the viewport - show the image
69+
act(() => {
70+
intersectionObserver.enterNode(container.firstChild)
71+
})
7072

7173
expect(getByAltText('alt text')).toBeInTheDocument()
7274
})

babel.config.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
env: {
3+
test: {
4+
presets: [
5+
[
6+
'@babel/preset-env',
7+
{
8+
targets: {
9+
node: 'current'
10+
}
11+
}
12+
],
13+
'@babel/preset-react'
14+
]
15+
}
16+
},
17+
presets: ['@babel/preset-env', '@babel/preset-react']
18+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import React, { useRef } from 'react'
2+
import PropTypes from 'prop-types'
3+
import useIntersection from './useIntersection'
4+
5+
export const Section = ({ number }) => {
6+
const ref = useRef(null)
7+
const isIntersecting = useIntersection(ref)
8+
9+
return (
10+
<section
11+
ref={ref}
12+
style={{
13+
height: '20vh',
14+
backgroundColor: isIntersecting ? 'SeaGreen' : 'IndianRed'
15+
}}
16+
>
17+
A section {number} -{' '}
18+
{isIntersecting ? 'intersecting' : 'not intersecting'}
19+
</section>
20+
)
21+
}
22+
23+
Section.propTypes = {
24+
number: PropTypes.number.isRequired
25+
}
26+
27+
const App = () => {
28+
const sections = 10
29+
30+
return (
31+
<>
32+
{[...new Array(sections)].map((_, index) => (
33+
<Section number={index} key={index} />
34+
))}
35+
<div
36+
style={{
37+
position: 'fixed',
38+
top: '30vh',
39+
right: '0',
40+
bottom: '30vh',
41+
left: '0',
42+
outline: '2px dashed white',
43+
color: 'white',
44+
background: 'rgba(0,0,0,0.3)',
45+
display: 'flex',
46+
alignItems: 'center',
47+
justifyContent: 'center'
48+
}}
49+
>
50+
Intersection zone
51+
</div>
52+
</>
53+
)
54+
}
55+
56+
export default App
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import React from 'react'
2+
import { render, act } from '@testing-library/react'
3+
import '@testing-library/jest-dom/extend-expect'
4+
5+
import mockIntersectionObserver from '../../../src/mocks/intersection-observer'
6+
7+
import App, { Section } from './App'
8+
9+
const intersectionObserver = mockIntersectionObserver()
10+
11+
describe('Section is intersecting', () => {
12+
it('should render correctly when not inside the intersection zone', () => {
13+
const { getByText } = render(<Section number={1} />)
14+
15+
expect(getByText('A section 1 - not intersecting')).toBeInTheDocument()
16+
})
17+
18+
it('should render correctly when entering the intersection zone', () => {
19+
const { getByText, container } = render(<Section number={1} />)
20+
21+
act(() => {
22+
intersectionObserver.enterNode(container.firstChild)
23+
})
24+
25+
expect(getByText('A section 1 - intersecting')).toBeInTheDocument()
26+
})
27+
28+
it('should render correctly when leaving the intersection zone', () => {
29+
const { getByText, container } = render(<Section number={1} />)
30+
31+
act(() => {
32+
intersectionObserver.enterNode(container.firstChild)
33+
})
34+
35+
expect(getByText('A section 1 - intersecting')).toBeInTheDocument()
36+
37+
act(() => {
38+
intersectionObserver.leaveNode(container.firstChild)
39+
})
40+
41+
expect(getByText('A section 1 - not intersecting')).toBeInTheDocument()
42+
})
43+
44+
it('should enter all the nodes at once', () => {
45+
const { getAllByText } = render(<App />)
46+
47+
act(() => {
48+
intersectionObserver.enterAll()
49+
})
50+
51+
expect(getAllByText(/A section/).map(node => node.textContent)).toEqual([
52+
'A section 0 - intersecting',
53+
'A section 1 - intersecting',
54+
'A section 2 - intersecting',
55+
'A section 3 - intersecting',
56+
'A section 4 - intersecting',
57+
'A section 5 - intersecting',
58+
'A section 6 - intersecting',
59+
'A section 7 - intersecting',
60+
'A section 8 - intersecting',
61+
'A section 9 - intersecting'
62+
])
63+
})
64+
65+
it('should enter and leave all the nodes at once', () => {
66+
const { getAllByText } = render(<App />)
67+
68+
act(() => {
69+
intersectionObserver.enterAll()
70+
})
71+
72+
expect(getAllByText(/A section/).map(node => node.textContent)).toEqual([
73+
'A section 0 - intersecting',
74+
'A section 1 - intersecting',
75+
'A section 2 - intersecting',
76+
'A section 3 - intersecting',
77+
'A section 4 - intersecting',
78+
'A section 5 - intersecting',
79+
'A section 6 - intersecting',
80+
'A section 7 - intersecting',
81+
'A section 8 - intersecting',
82+
'A section 9 - intersecting'
83+
])
84+
85+
act(() => {
86+
intersectionObserver.leaveAll()
87+
})
88+
89+
expect(getAllByText(/A section/).map(node => node.textContent)).toEqual([
90+
'A section 0 - not intersecting',
91+
'A section 1 - not intersecting',
92+
'A section 2 - not intersecting',
93+
'A section 3 - not intersecting',
94+
'A section 4 - not intersecting',
95+
'A section 5 - not intersecting',
96+
'A section 6 - not intersecting',
97+
'A section 7 - not intersecting',
98+
'A section 8 - not intersecting',
99+
'A section 9 - not intersecting'
100+
])
101+
})
102+
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const rootConfig = require('../../../babel.config')
2+
3+
module.exports = rootConfig.env.test

0 commit comments

Comments
 (0)