Skip to content

Commit 07e7a27

Browse files
authored
Merge pull request tttstudios#47 from Twotalltotems/improvement/unit-test-setup
Unit Test Setup & Github Action
2 parents 44635bc + c99466a commit 07e7a27

File tree

8 files changed

+184
-6
lines changed

8 files changed

+184
-6
lines changed

.github/workflows/test.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
branches:
9+
- master
10+
11+
12+
jobs:
13+
build:
14+
15+
runs-on: ubuntu-latest
16+
17+
container:
18+
image: node:13.4.0
19+
20+
steps:
21+
- uses: actions/checkout@v1
22+
- name: Run Jest
23+
uses: stefanoeb/jest-action@1.0.2
24+
- name: Run Unit Test
25+
run: npm install --only=dev && npm test
26+

CONTRIBUTING.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Introduction
2+
3+
Thank you for considering contributing to `@twotalltotems/react-native-otp-input`. It's people like you that make the library better.
4+
5+
# Ways to Contribute
6+
7+
There are many ways to contribute, from writing tutorials or blog posts, improving the documentation, submitting bug reports and feature requests or writing code which can be incorporated into the library.
8+
9+
10+
# Your First Contribution
11+
If you decided to look into a pending issue, hope the guideline below can help you start.
12+
13+
>1. Create your own fork of the code
14+
>2. Do the changes in your fork
15+
>3. If you like the change and think the project could use it:
16+
* Be sure you have followed the code style for the project.
17+
* Well test your changes and add unit tests if necessary.
18+
* Be sure to run `npm test` before submitting a pull request. This would help us maintain the compatablity of the library.
19+
>4. Send a pull request.
20+
21+
# Code review process
22+
The development team in TTT Studios looks at Pull Requests on a regular basis. Depends on the PR reviewed, we might reach out with some feedback or clarification.
23+
24+
After feedback/clarification has been given we expect responses within two weeks. After two weeks we may close the pull request if it isn't showing any activity.
25+
26+
TTT Studios appreaciate your interest and effort in contributing to the library. Look forward to your great Pull Requests!
27+
28+
29+
30+
31+
32+

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
![PaginatableList](https://raw.githubusercontent.com/Twotalltotems/react-native-otp-input/master/assets/otp_banner.jpg)
22
# React Native OTP Input
33

4+
![Tests](https://github.com/Twotalltotems/react-native-otp-input/workflows/Tests/badge.svg)
5+
46
**@twotalltotems/react-native-otp-input** is a tiny Javascript library which provides an elegant UI for the end user to input one time passcode (OTP). It handles the input suggestion on iOS when the OTP SMS is received. For Android, it will autofill when the user presses the copy button on the SMS notification bar. It also features a carefully crafted flow to handle edge cases for volatile user gestures. We provide default UI, but you can always customize the appearance as you like.
57

68
![demo.gif](https://s3.ca-central-1.amazonaws.com/tttevents/iosvideo.gif)

__tests__/App.test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import "react-native"
2+
import React from 'react'
3+
import { shallow, mount } from 'enzyme'
4+
import OTPInputView from '../index'
5+
6+
const setup = (props = {}) => {
7+
const wrapper = shallow(<OTPInputView {...props} />)
8+
return wrapper;
9+
}
10+
11+
describe('OTPInputView renders correclty.', () => {
12+
let shallowWrapper;
13+
it('OTP container view renders correctly.', () => {
14+
shallowWrapper = setup()
15+
const otpInputView = shallowWrapper.find({ testID: 'OTPInputView' })
16+
17+
expect(otpInputView.length).toBe(1)
18+
})
19+
20+
it('Render same amount of input slots as prop `pinCount`', () => {
21+
const pinCount = 6
22+
shallowWrapper = setup({ pinCount })
23+
const inputSlotViews = shallowWrapper.find({ testID: 'inputSlotView' })
24+
25+
expect(inputSlotViews.length).toBe(pinCount)
26+
})
27+
28+
it('Render the slots initial state as `code` prop.', () => {
29+
const code = '123456'
30+
const pinCount = code.length
31+
const reactWrapper = mount(<OTPInputView code={code} pinCount={pinCount} />)
32+
const textInputs = reactWrapper.find({ testID: 'textInput' }).hostNodes()
33+
const chars = code.split('')
34+
35+
textInputs.map((textInput, index) => {
36+
expect(textInput.props().value).toBe(chars[index])
37+
})
38+
})
39+
})
40+
41+

babel.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
presets: ["module:metro-react-native-babel-preset"]
3+
}

index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ export default class OTPInputView extends Component {
195195
const { clearInputs, placeholderCharacter, placeholderTextColor } = this.props
196196
const { color: defaultPlaceholderTextColor } = { ...defaultTextFieldStyle, ...codeInputFieldStyle }
197197
return (
198-
<View pointerEvents="none" key={index + "view"}>
198+
<View pointerEvents="none" key={index + "view"} testID="inputSlotView">
199199
<TextInput
200+
testID="textInput"
200201
underlineColorAndroid='rgba(0,0,0,0)'
201202
style={selectedIndex === index ? [defaultTextFieldStyle, codeInputFieldStyle, codeInputHighlightStyle] : [defaultTextFieldStyle, codeInputFieldStyle]}
202203
ref={ref => { this.fields[index] = ref }}
@@ -228,6 +229,7 @@ export default class OTPInputView extends Component {
228229
const digits = this.getDigits()
229230
return (
230231
<View
232+
testID="OTPInputView"
231233
style={style}
232234
>
233235
<TouchableWithoutFeedback

package.json

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,25 @@
33
"version": "1.2.0",
44
"description": "is a tiny JS library for one time passcode (OTP). Supports smart input suggestion on iOS and code autofill on Android (it will be filled when you press the copy button on the SMS notification bar)",
55
"main": "index.js",
6-
"directories": {
7-
"test": "test"
8-
},
96
"scripts": {
10-
"test": "echo \"Error: no test specified\" && exit 1"
7+
"start": "node node_modules/react-native/local-cli/cli.js start",
8+
"test": "jest"
9+
},
10+
"jest": {
11+
"preset": "react-native",
12+
"setupFilesAfterEnv": [
13+
"<rootDir>setup-tests.js"
14+
],
15+
"testEnvironment": "enzyme",
16+
"testEnvironmentOptions": {
17+
"enzymeAdapter": "react16"
18+
},
19+
"testMatch": [
20+
"<rootDir>/__tests__/*.test.js"
21+
],
22+
"transform": {
23+
"^.+\\.jsx$": "babel-jest"
24+
}
1125
},
1226
"repository": {
1327
"type": "git",
@@ -31,5 +45,18 @@
3145
"Anson Yao <yaoenxin@gmail.com> (https://github.com/ansonyao)",
3246
"Felipe Peña <felipe@penya.cl> (http://felipe.penya.cl)"
3347
],
34-
"license": "MIT"
48+
"license": "MIT",
49+
"devDependencies": {
50+
"@babel/core": "^7.8.4",
51+
"babel-jest": "^25.1.0",
52+
"enzyme": "^3.11.0",
53+
"enzyme-adapter-react-16": "^1.15.2",
54+
"jest": "^25.1.0",
55+
"jest-environment-enzyme": "^7.1.2",
56+
"jest-enzyme": "^7.1.2",
57+
"jsdom": "^16.1.0",
58+
"react": "16",
59+
"react-dom": "^16.12.0",
60+
"react-native": "^0.61.5"
61+
}
3562
}

setup-tests.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import 'react-native';
2+
import 'jest-enzyme';
3+
import Adapter from 'enzyme-adapter-react-16';
4+
import Enzyme from 'enzyme';
5+
6+
/**
7+
* Set up DOM in node.js environment for Enzyme to mount to
8+
*/
9+
const { JSDOM } = require('jsdom');
10+
11+
const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
12+
const { window } = jsdom;
13+
14+
function copyProps(src, target) {
15+
Object.defineProperties(target, {
16+
...Object.getOwnPropertyDescriptors(src),
17+
...Object.getOwnPropertyDescriptors(target),
18+
});
19+
}
20+
21+
global.window = window;
22+
global.document = window.document;
23+
global.navigator = {
24+
userAgent: 'node.js',
25+
};
26+
copyProps(window, global);
27+
28+
/**
29+
* Resolve the unnecessary warning log while running unit test.
30+
* Referring solution from https://github.com/airbnb/enzyme/issues/831#issuecomment-490644160
31+
*/
32+
const originalConsoleError = console.error;
33+
console.error = (message) => {
34+
if (message.startsWith('Warning:')) {
35+
return;
36+
}
37+
38+
originalConsoleError(message);
39+
};
40+
41+
/**
42+
* Set up Enzyme to mount to DOM, simulate events,
43+
* and inspect the DOM in tests.
44+
*/
45+
Enzyme.configure({ adapter: new Adapter() });

0 commit comments

Comments
 (0)