1 | import test from 'ava'
|
2 | import Chance from '../chance.js'
|
3 | import _ from 'lodash'
|
4 |
|
5 |
|
6 | const mean = (arr) => arr.reduce((a, b) => a + b)/arr.length
|
7 | const stddev = (arr) => {
|
8 | var testMean = mean(arr)
|
9 | var deviation = arr.map((item) => (item - testMean) * (item - testMean))
|
10 | return Math.sqrt(deviation.reduce((a, b) => a + b )/arr.length)
|
11 | }
|
12 |
|
13 | const pool = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
|
14 |
|
15 | const chance = new Chance()
|
16 |
|
17 | test('normal() works as expected with no parameters and returns a number', t => {
|
18 | _.times(1000, () => {
|
19 | let norm = chance.normal()
|
20 | t.is(typeof norm, 'number')
|
21 | })
|
22 | })
|
23 |
|
24 | test('normal() returns values fairly close to the expected standard deviation and mean', t => {
|
25 | let testStddev = 1
|
26 | let testMean = 0
|
27 | let group = chance.n(chance.normal, 10000)
|
28 |
|
29 | t.true(Math.abs(mean(group) - testMean) < testStddev)
|
30 | t.true(Math.abs(stddev(group) - testStddev) < testStddev * 0.05)
|
31 | })
|
32 |
|
33 | test('normal() works as expected with a pool of custom values provided', t => {
|
34 | let testStddev = 0.0000000001
|
35 | let testMean = 2
|
36 |
|
37 | _.times(1000, () => {
|
38 | let norm = chance.normal({ mean: testMean, dev: testStddev, pool: pool })
|
39 | t.true(pool.indexOf(norm) !== -1)
|
40 | })
|
41 | })
|
42 |
|
43 | test('normal() recalculates and returns a value even if the normal() results in indexes outside the bounds of the pool', t => {
|
44 | let testStddev = 1.5
|
45 | let testMean = 3
|
46 |
|
47 | _.times(1000, () => {
|
48 | let norm = chance.normal({ mean: testMean, dev: testStddev, pool: pool })
|
49 | t.true(pool.indexOf(norm) !== -1)
|
50 | })
|
51 | })
|
52 |
|
53 | test('normal() can be used with other chance functions', t => {
|
54 | let testStddev = 1
|
55 | let testMean = 3
|
56 | let group = chance.n(chance.normal, 1000, { mean: testMean, dev: testStddev, pool: pool })
|
57 |
|
58 | t.true(group.length === 1000)
|
59 | t.true(pool.indexOf(group[0]) !== -1)
|
60 | t.true(pool.indexOf(group[999]) !== -1)
|
61 | })
|
62 |
|
63 | test('normal() should produce a correctly distributed group of pool items', t => {
|
64 | let testStddev = 2
|
65 | let testMean = 6
|
66 | let group = chance.n(chance.normal, 10000, { mean: testMean, dev: testStddev, pool: pool })
|
67 | let counts = _.countBy(group)
|
68 |
|
69 | t.true(counts.Sunday > counts.Saturday)
|
70 | t.true(counts.Saturday > counts.Friday)
|
71 | t.true(counts.Friday > counts.Thursday)
|
72 | t.true(counts.Thursday > counts.Wednesday)
|
73 | t.true(counts.Wednesday > counts.Tuesday)
|
74 | t.true(counts.Tuesday > counts.Monday)
|
75 | })
|
76 |
|
77 | test('normal() should throw an error quickly if the user has provided bad pool', t => {
|
78 | let testStddev = 5
|
79 | let testMean = 200
|
80 | const fn = () => chance.normal({ mean: testMean, dev: testStddev, pool: pool })
|
81 | t.throws(fn, 'Chance: Your pool is too small for the given mean and standard deviation. Please adjust.')
|
82 | })
|
83 |
|
84 | test('normal() should throw an error if called with non-number mean', t => {
|
85 | let testStddev = 5
|
86 | let testMean = []
|
87 | const fn = () => chance.normal({ mean: testMean, dev: testStddev, pool: pool })
|
88 | t.throws(fn, 'Chance: Mean (mean) must be a number')
|
89 | })
|
90 |
|
91 | test('normal() should throw an error if called with non-number stddev', t => {
|
92 | let testStddev = []
|
93 | let testMean = 5
|
94 | const fn = () => chance.normal({ mean: testMean, dev: testStddev, pool: pool })
|
95 | t.throws(fn, 'Chance: Standard deviation (dev) must be a number')
|
96 | })
|
97 |
|
98 | test('normal() should throw an error if the pool provided is not an array', t => {
|
99 | const fn = () => chance.normal({ pool: 'not an array' })
|
100 | t.throws(fn, 'Chance: The pool option must be a valid array.')
|
101 | })
|
102 |
|
103 | test('normal() should work with objects', t => {
|
104 | let testStddev = 1
|
105 | let testMean = 1
|
106 | let group = chance.n(chance.normal, 50, { mean: testMean, dev: testStddev, pool: [
|
107 | { a: 1, b: 10},
|
108 | { a: 2, b: 20},
|
109 | { a: 3, b: 30}
|
110 | ]})
|
111 |
|
112 | t.true(group.length === 50)
|
113 | t.truthy(group[0]['a'])
|
114 | })
|