Skip to content

Commit 3e570a6

Browse files
authored
Merge pull request #21 from chilllab/test
Test
2 parents d98dd4f + 307e36c commit 3e570a6

File tree

11 files changed

+2399
-189
lines changed

11 files changed

+2399
-189
lines changed

.eslintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"import/no-extraneous-dependencies": "off",
7070
"jsx-a11y/control-has-associated-label": "off",
7171
"jsx-a11y/anchor-has-content": "off",
72-
"react/no-access-state-in-setstate": "off"
72+
"react/no-access-state-in-setstate": "off",
73+
"no-plusplus": "off"
7374
}
7475
}

.npmignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,23 @@
22
*.log
33
.DS_Store*
44
.idea/
5+
report.*.json
56

67
// specific files
78
node_modules/
89
test/
910
CHANGELOG.md
1011
src/
1112
demo/
13+
test/
1214

1315
// setting files
1416
.babelrc
1517
.travis.yml
1618
.eslintrc
1719
.eslintignore
20+
.travis.yml
1821

1922
Makefile
2023
README.md
21-
rollup.config.js
22-
rollup.config.demo.js
24+
rollup.config.js

.travis.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
language: node_js
2+
cache:
3+
directories:
4+
- node_modules
5+
node_js:
6+
- "16"
7+
notifications:
8+
email: false
9+
install:
10+
- yarn
11+
script:
12+
- make test

Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@ lint-fix:
77
@npx eslint --fix .
88
dev:
99
@echo "Start server..."
10-
@NODE_ENV=development npx rollup -c rollup.config.demo.js -w
10+
@NODE_ENV=development npx rollup -c ./demo/rollup.config.js -w
1111
.PHONY: lint lint-fix dev
1212

13+
# Test
14+
test: lint-fix
15+
@echo "Running test..."
16+
@npx jest
17+
.PHONY: test
18+
1319
# Deployment
1420
build:
1521
@echo "Building lib..."
@@ -20,5 +26,5 @@ build:
2026
build-demo:
2127
@echo "Building demo..."
2228
@rm -rf ./demo/dist
23-
@NODE_ENV=production npx rollup -c rollup.config.demo.js
29+
@NODE_ENV=production npx rollup -c ./demo/rollup.config.js
2430
.PHONY: build build-demo

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,23 @@ The options can be passed into genConfig or as React props
9999
```sh
100100
$ make dev
101101
```
102-
5. Open the browser to reivew the demo:
102+
4. Open the browser to reivew the demo:
103103
```sh
104104
$ open http://localhost:5555
105105
```
106-
7. Edit the files inside [src](/src).
106+
5. Edit the files inside [src](/src).
107107

108+
## Test
109+
110+
1. Lint test:
111+
```sh
112+
$ make lint-test
113+
```
114+
115+
2. code test:
116+
```sh
117+
$ make test
118+
```
108119

109120
## License
110121

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import path from "path";
12
import babel from "rollup-plugin-babel";
23
import resolve from "@rollup/plugin-node-resolve";
34
import commonjs from "@rollup/plugin-commonjs";
@@ -23,19 +24,19 @@ if (process.env.NODE_ENV === "development" && process.env.MODE !== "build") {
2324
serve({
2425
open: false,
2526
verbose: true,
26-
contentBase: ["demo"],
27+
contentBase: [path.resolve(__dirname, "./")],
2728
host: "localhost",
2829
port: 5555
2930
}),
30-
livereload({ watch: "demo" })
31+
livereload({ watch: path.resolve(__dirname, "./") })
3132
]);
3233
}
3334

3435
export default {
35-
input: "demo/index.js",
36+
input: path.resolve(__dirname, "./index.js"),
3637
output: [
3738
{
38-
file: "demo/dist/index.js",
39+
file: path.resolve(__dirname, "./dist/index.js"),
3940
format: "iife",
4041
sourcemap: true
4142
}

package.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@
3131
"babel-eslint": "^10.1.0",
3232
"classnames": "^2.3.1",
3333
"dom-to-image": "^2.6.0",
34+
"enzyme": "^3.11.0",
3435
"eslint": "^7.27.0",
3536
"eslint-config-airbnb": "^18.2.1",
3637
"eslint-plugin-import": "^2.23.3",
3738
"eslint-plugin-jsx-a11y": "^6.4.1",
3839
"eslint-plugin-react": "^7.23.2",
3940
"eslint-plugin-react-hooks": "^4.2.0",
4041
"file-saver": "^2.0.5",
42+
"jest": "^27.0.5",
4143
"prop-types": "^15.7.2",
4244
"rc-slider": "^9.7.2",
4345
"react": "^17.0.2",
@@ -54,5 +56,17 @@
5456
"repository": {
5557
"type": "git",
5658
"url": "https://github.com/chilllab/react-nice-avatar"
57-
}
59+
},
60+
"jest": {
61+
"testRegex": ".*\\.(test|spec)\\.js$",
62+
"moduleFileExtensions": [
63+
"js"
64+
],
65+
"moduleDirectories": [
66+
"node_modules"
67+
]
68+
},
69+
"browserslist": [
70+
"last 2 versions"
71+
]
5872
}

src/index.js

Lines changed: 3 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import React, { Component } from "react";
22
import PropTypes from "prop-types";
33

4+
import { genConfig } from "./utils";
5+
46
import Face from "./face";
57
import Hair from "./hair";
68
import Hat from "./hat";
@@ -12,42 +14,6 @@ import Nose from "./nose";
1214
import Mouth from "./mouth";
1315
import Shirt from "./shirt";
1416

15-
const sex = ["man", "woman"];
16-
const faceColor = ["#F9C9B6", "#AC6651"];
17-
const earSize = ["small", "big"];
18-
const hairColor = ["#000", "#fff", "#77311D", "#FC909F", "#D2EFF3", "#506AF4", "#F48150"];
19-
const hairStyleMan = ["normal", "thick", "mohawk"];
20-
const hairStyleWoman = ["normal", "womanLong", "womanShort"];
21-
const hatColor = ["#000", "#fff", "#77311D", "#FC909F", "#D2EFF3", "#506AF4", "#F48150"];
22-
const hatStyle = ["beanie", "turban", "none"];
23-
const eyeBrowWoman = ["up", "upWoman"];
24-
const eyeStyle = ["circle", "oval", "smile"];
25-
const noseStyle = ["short", "long", "round"];
26-
const mouthStyle = ["laugh", "smile", "peace"];
27-
const shirtStyle = ["hoody", "short", "polo"];
28-
const shirtColor = ["#9287FF", "#6BD9E9", "#FC909F", "#F4D150", "#77311D"];
29-
const bgColor = ["#9287FF", "#6BD9E9", "#FC909F", "#F4D150", "#E0DDFF", "#D2EFF3", "#FFEDEF", "#FFEBA4", "#506AF4", "#F48150", "#74D153"];
30-
const glassesStyle = ["round", "square", "none"];
31-
32-
const _pickRandomFromList = (data, { avoidList = [], usually = [] } = {}) => {
33-
// Filter out avoid options
34-
const avoidSet = new Set(
35-
avoidList.filter((item) => Boolean(item))
36-
);
37-
let myData = data.filter((item) => !avoidSet.has(item));
38-
39-
// Increase selecting possibility of usually options
40-
const usuallyData = usually
41-
.filter((item) => Boolean(item))
42-
.reduce((acc, cur) => acc.concat(new Array(15).fill(cur)), []);
43-
myData = myData.concat(usuallyData);
44-
45-
// Pick randon one from the list
46-
const amount = myData.length;
47-
const randomIdx = Math.floor(Math.random() * amount);
48-
return myData[randomIdx];
49-
};
50-
5117
export default class ReactNiceAvatar extends Component {
5218
static propTypes = {
5319
id: PropTypes.string,
@@ -160,69 +126,4 @@ export default class ReactNiceAvatar extends Component {
160126
}
161127
}
162128

163-
export const genConfig = (userConfig = {}) => {
164-
const response = {};
165-
166-
response.sex = userConfig.sex || _pickRandomFromList(sex);
167-
response.faceColor = userConfig.faceColor || _pickRandomFromList(faceColor);
168-
response.earSize = userConfig.earSize || _pickRandomFromList(earSize);
169-
response.eyeStyle = userConfig.eyeStyle || _pickRandomFromList(eyeStyle);
170-
response.noseStyle = userConfig.noseStyle || _pickRandomFromList(noseStyle);
171-
response.mouthStyle = userConfig.mouthStyle || _pickRandomFromList(mouthStyle);
172-
response.shirtStyle = userConfig.shirtStyle || _pickRandomFromList(shirtStyle);
173-
response.glassesStyle = userConfig.glassesStyle || _pickRandomFromList(glassesStyle, { usually: ["none"] });
174-
175-
// Hair
176-
let hairColorAvoidList = [];
177-
let hairColorUsually = [];
178-
if (!userConfig.hairColor) {
179-
switch (response.sex) {
180-
case "woman": {
181-
hairColorAvoidList = response.faceColor === faceColor[1] && ["#77311D"] || [];
182-
break;
183-
}
184-
case "man": {
185-
hairColorUsually = ["#000"];
186-
}
187-
}
188-
}
189-
response.hairColor = userConfig.hairColor || _pickRandomFromList(hairColor, {
190-
avoidList: hairColorAvoidList,
191-
usually: hairColorUsually
192-
});
193-
194-
let myHairStyle = userConfig.hairStyle;
195-
if (!myHairStyle) {
196-
switch (response.sex) {
197-
case "man": {
198-
myHairStyle = _pickRandomFromList(hairStyleMan, { usually: ["normal", "thick"] });
199-
break;
200-
}
201-
case "woman": {
202-
myHairStyle = _pickRandomFromList(hairStyleWoman);
203-
break;
204-
}
205-
}
206-
}
207-
response.hairStyle = myHairStyle;
208-
209-
// Hat
210-
response.hatStyle = userConfig.hatStyle || _pickRandomFromList(hatStyle, { usually: ["none"] });
211-
response.hatColor = userConfig.hatColor || _pickRandomFromList(hatColor);
212-
const _hairOrHatColor = response.hatStyle === "none" && response.hairColor || response.hatColor;
213-
214-
// Eyebrow
215-
let myEyeBrowStyle = userConfig.eyeBrowStyle || "up";
216-
if (!userConfig.eyeBrowStyle && response.sex === "woman") {
217-
myEyeBrowStyle = _pickRandomFromList(eyeBrowWoman);
218-
}
219-
response.eyeBrowStyle = myEyeBrowStyle;
220-
221-
// Shirt color
222-
response.shirtColor = userConfig.shirtColor || _pickRandomFromList(shirtColor, { avoidList: [_hairOrHatColor] });
223-
224-
// Background color
225-
response.bgColor = userConfig.bgColor || _pickRandomFromList(bgColor, { avoidList: [_hairOrHatColor, response.shirtColor] });
226-
227-
return response;
228-
};
129+
export { genConfig } from "./utils";

src/utils.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* Pick random one from the list
3+
*/
4+
export const pickRandomFromList = (data, { avoidList = [], usually = [] } = {}) => {
5+
// Filter out avoid options
6+
const avoidSet = new Set(
7+
avoidList.filter((item) => Boolean(item))
8+
);
9+
let myData = data.filter((item) => !avoidSet.has(item));
10+
11+
// Increase selecting possibility of usually options
12+
const usuallyData = usually
13+
.filter((item) => Boolean(item))
14+
.reduce((acc, cur) => acc.concat(new Array(15).fill(cur)), []);
15+
myData = myData.concat(usuallyData);
16+
17+
// Pick randon one from the list
18+
const amount = myData.length;
19+
const randomIdx = Math.floor(Math.random() * amount);
20+
return myData[randomIdx];
21+
};
22+
23+
/**
24+
* Gennerate avatar configurations
25+
*/
26+
export const defaultOptions = {
27+
sex: ["man", "woman"],
28+
faceColor: ["#F9C9B6", "#AC6651"],
29+
earSize: ["small", "big"],
30+
hairColor: ["#000", "#fff", "#77311D", "#FC909F", "#D2EFF3", "#506AF4", "#F48150"],
31+
hairStyleMan: ["normal", "thick", "mohawk"],
32+
hairStyleWoman: ["normal", "womanLong", "womanShort"],
33+
hatColor: ["#000", "#fff", "#77311D", "#FC909F", "#D2EFF3", "#506AF4", "#F48150"],
34+
hatStyle: ["beanie", "turban", "none"],
35+
eyeBrowWoman: ["up", "upWoman"],
36+
eyeStyle: ["circle", "oval", "smile"],
37+
glassesStyle: ["round", "square", "none"],
38+
noseStyle: ["short", "long", "round"],
39+
mouthStyle: ["laugh", "smile", "peace"],
40+
shirtStyle: ["hoody", "short", "polo"],
41+
shirtColor: ["#9287FF", "#6BD9E9", "#FC909F", "#F4D150", "#77311D"],
42+
bgColor: ["#9287FF", "#6BD9E9", "#FC909F", "#F4D150", "#E0DDFF", "#D2EFF3", "#FFEDEF", "#FFEBA4", "#506AF4", "#F48150", "#74D153"]
43+
};
44+
export const genConfig = (userConfig = {}) => {
45+
const response = {};
46+
response.sex = userConfig.sex || pickRandomFromList(defaultOptions.sex);
47+
response.faceColor = userConfig.faceColor || pickRandomFromList(defaultOptions.faceColor);
48+
response.earSize = userConfig.earSize || pickRandomFromList(defaultOptions.earSize);
49+
response.eyeStyle = userConfig.eyeStyle || pickRandomFromList(defaultOptions.eyeStyle);
50+
response.noseStyle = userConfig.noseStyle || pickRandomFromList(defaultOptions.noseStyle);
51+
response.mouthStyle = userConfig.mouthStyle || pickRandomFromList(defaultOptions.mouthStyle);
52+
response.shirtStyle = userConfig.shirtStyle || pickRandomFromList(defaultOptions.shirtStyle);
53+
response.glassesStyle = userConfig.glassesStyle || pickRandomFromList(defaultOptions.glassesStyle, { usually: ["none"] });
54+
55+
// Hair
56+
let hairColorAvoidList = [];
57+
let hairColorUsually = [];
58+
if (!userConfig.hairColor) {
59+
switch (response.sex) {
60+
case "woman": {
61+
hairColorAvoidList = response.faceColor === defaultOptions.faceColor[1] && ["#77311D"] || [];
62+
break;
63+
}
64+
case "man": {
65+
hairColorUsually = ["#000"];
66+
}
67+
}
68+
}
69+
response.hairColor = userConfig.hairColor || pickRandomFromList(defaultOptions.hairColor, {
70+
avoidList: hairColorAvoidList,
71+
usually: hairColorUsually
72+
});
73+
74+
let myHairStyle = userConfig.hairStyle;
75+
if (!myHairStyle) {
76+
switch (response.sex) {
77+
case "man": {
78+
myHairStyle = pickRandomFromList(defaultOptions.hairStyleMan, { usually: ["normal", "thick"] });
79+
break;
80+
}
81+
case "woman": {
82+
myHairStyle = pickRandomFromList(defaultOptions.hairStyleWoman);
83+
break;
84+
}
85+
}
86+
}
87+
response.hairStyle = myHairStyle;
88+
89+
// Hat
90+
response.hatStyle = userConfig.hatStyle || pickRandomFromList(defaultOptions.hatStyle, { usually: ["none"] });
91+
response.hatColor = userConfig.hatColor || pickRandomFromList(defaultOptions.hatColor);
92+
const _hairOrHatColor = response.hatStyle === "none" && response.hairColor || response.hatColor;
93+
94+
// Eyebrow
95+
let myEyeBrowStyle = userConfig.eyeBrowStyle || "up";
96+
if (!userConfig.eyeBrowStyle && response.sex === "woman") {
97+
myEyeBrowStyle = pickRandomFromList(defaultOptions.eyeBrowWoman);
98+
}
99+
response.eyeBrowStyle = myEyeBrowStyle;
100+
101+
// Shirt color
102+
response.shirtColor = userConfig.shirtColor || pickRandomFromList(defaultOptions.shirtColor, { avoidList: [_hairOrHatColor] });
103+
104+
// Background color
105+
response.bgColor = userConfig.bgColor || pickRandomFromList(defaultOptions.bgColor, { avoidList: [_hairOrHatColor, response.shirtColor] });
106+
107+
return response;
108+
};

0 commit comments

Comments
 (0)