Skip to content

Commit e22ffc1

Browse files
committed
add support for int, bool, and arrays of random values
1 parent 42a1349 commit e22ffc1

File tree

4 files changed

+85
-31
lines changed

4 files changed

+85
-31
lines changed

api.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,8 @@ const MergingAction = state => [
191191
<a name="module_fx.exports.Random"></a>
192192

193193
### fx.exports.Random(props)
194-
Describes an effect that will call an action with a [randomly generated number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) within a range.
195-
If provided the range will be `[min, max)` or else the default range is `[0, 1)`. The random number will be provided as the action `data`.
196-
197-
Use [`Math.floor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) if you want a random integer instead of a floating-point number.
198-
Remember the range will be `max` exclusive, so use your largest desired int + 1.
194+
Describes an effect that will call an action with one or more randomly generated value(s).
195+
If provided the range for [random numeric values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) will be `[min, max)` or else the default range is `[0, 1)`. Also `bool`eans, `int`egers, and arrays of `values` are supported. The random value will be provided as the action `data`.
199196

200197
**Kind**: static method of [<code>fx</code>](#module_fx)
201198

@@ -205,6 +202,9 @@ Remember the range will be `max` exclusive, so use your largest desired int + 1.
205202
| props.action | <code>\*</code> | action to call with the random number result |
206203
| props.min | <code>number</code> | minimum random number to generate |
207204
| props.max | <code>number</code> | maximum random number to generate |
205+
| props.int | <code>boolean</code> | round number to nearest integer |
206+
| props.bool | <code>boolean</code> | generate a boolean instead of a number (ignores numeric options) |
207+
| props.values | <code>Array.&lt;object&gt;</code> | generate an array of values (ignores other options, each object accepts same props as the root) |
208208

209209
**Example**
210210
```js
@@ -214,10 +214,9 @@ const RollDie = state => [
214214
state,
215215
Random({
216216
min: 1,
217-
// We use the max of 7 to include all values of 6.x
218217
max: 7,
219-
action: (_, randomNumber) => {
220-
const roll = Math.floor(randomNumber)
218+
int: true,
219+
action: (_, roll) => {
221220
// roll will be an int from 1-6
222221

223222
// return new state using roll

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hyperapp-fx",
3-
"version": "2.0.0-alpha.5",
3+
"version": "2.0.0-alpha.6",
44
"description": "Effects for use with Hyperapp",
55
"main": "dist/hyperappFx.js",
66
"module": "src/index.js",

src/fx/Random.js

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,51 @@
1+
function generateRandom(props) {
2+
if (props.values) {
3+
return props.values.map(generateRandom)
4+
}
5+
var min = props.min || 0
6+
var max = props.max || 1
7+
if (props.int) max++
8+
if (props.bool) {
9+
min = 0
10+
max = 2
11+
}
12+
var randomValue = Math.random() * (max - min) + min
13+
if (props.int || props.bool) {
14+
randomValue = Math.floor(randomValue)
15+
}
16+
if (props.bool) {
17+
randomValue = !!randomValue
18+
}
19+
return randomValue
20+
}
21+
122
function randomEffect(props, dispatch) {
2-
var randomValue = Math.random() * (props.max - props.min) + props.min
23+
var randomValue = generateRandom(props)
324
dispatch(props.action, randomValue)
425
}
526

627
/**
7-
* Describes an effect that will call an action with a [randomly generated number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) within a range.
8-
* If provided the range will be `[min, max)` or else the default range is `[0, 1)`. The random number will be provided as the action `data`.
9-
*
10-
* Use [`Math.floor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) if you want a random integer instead of a floating-point number.
11-
* Remember the range will be `max` exclusive, so use your largest desired int + 1.
28+
* Describes an effect that will call an action with one or more randomly generated value(s).
29+
* If provided the range for [random numeric values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) will be `[min, max)` or else the default range is `[0, 1)`. Also `bool`eans, `int`egers, and arrays of `values` are supported. The random value will be provided as the action `data`.
1230
*
1331
* @memberof module:fx
1432
* @param {object} props
1533
* @param {*} props.action - action to call with the random number result
1634
* @param {number} props.min - minimum random number to generate
1735
* @param {number} props.max - maximum random number to generate
36+
* @param {boolean} props.int - round number to nearest integer
37+
* @param {boolean} props.bool - generate a boolean instead of a number (ignores numeric options)
38+
* @param {object[]} props.values - generate an array of values (ignores other options, each object accepts same props as the root)
1839
* @example
1940
* import { Random } from "hyperapp-fx"
2041
*
2142
* const RollDie = state => [
2243
* state,
2344
* Random({
2445
* min: 1,
25-
* // We use the max of 7 to include all values of 6.x
2646
* max: 7,
27-
* action: (_, randomNumber) => {
28-
* const roll = Math.floor(randomNumber)
47+
* int: true,
48+
* action: (_, roll) => {
2949
* // roll will be an int from 1-6
3050
*
3151
* // return new state using roll
@@ -34,12 +54,5 @@ function randomEffect(props, dispatch) {
3454
* ]
3555
*/
3656
export function Random(props) {
37-
return [
38-
randomEffect,
39-
{
40-
action: props.action,
41-
min: props.min || 0,
42-
max: props.max || 1
43-
}
44-
]
57+
return [randomEffect, props]
4558
}

test/fx/Random.test.js

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,70 @@ import { runFx } from "../utils"
22
import { Random } from "../../src"
33

44
describe("Random effect", () => {
5+
const defaultRandom = Math.random
6+
afterEach(() => {
7+
Math.random = defaultRandom
8+
})
59
it("should call Math.random with default range", () => {
610
const randomValue = 0.5
7-
const defaultRandom = Math.random
811
Math.random = () => randomValue
912

1013
const action = jest.fn()
1114
const randomFx = Random({ action })
1215
const { dispatch } = runFx(randomFx)
1316
expect(dispatch).toBeCalledWith(action, randomValue)
14-
15-
Math.random = defaultRandom
1617
})
1718

1819
it("should call Math.random with custom range", () => {
19-
const defaultRandom = Math.random
2020
Math.random = () => 0.5
2121

2222
const action = jest.fn()
2323
const randomFx = Random({ min: 2, max: 5, action })
2424
const { dispatch } = runFx(randomFx)
2525
expect(dispatch).toBeCalledWith(action, 3.5)
26+
})
2627

27-
Math.random = defaultRandom
28+
it("should generate integers", () => {
29+
Math.random = () => 0.5
30+
31+
const action = jest.fn()
32+
const randomFx = Random({ int: true, min: 1, max: 3, action })
33+
const { dispatch } = runFx(randomFx)
34+
expect(dispatch).toBeCalledWith(action, 2)
35+
})
36+
37+
it("should generate false booleans", () => {
38+
Math.random = () => 0.4
39+
40+
const action = jest.fn()
41+
const randomFx = Random({ bool: true, action })
42+
const { dispatch } = runFx(randomFx)
43+
expect(dispatch).toBeCalledWith(action, false)
44+
})
45+
46+
it("should generate true booleans", () => {
47+
Math.random = () => 0.5
48+
49+
const action = jest.fn()
50+
const randomFx = Random({ bool: true, action })
51+
const { dispatch } = runFx(randomFx)
52+
expect(dispatch).toBeCalledWith(action, true)
53+
})
54+
55+
it("should generate multiple values", () => {
56+
Math.random = () => 0.5
57+
58+
const action = jest.fn()
59+
const randomFx = Random({
60+
values: [
61+
{},
62+
{ min: 2, max: 5 },
63+
{ int: true, min: 1, max: 3 },
64+
{ bool: true }
65+
],
66+
action
67+
})
68+
const { dispatch } = runFx(randomFx)
69+
expect(dispatch).toBeCalledWith(action, [0.5, 3.5, 2, true])
2870
})
2971
})

0 commit comments

Comments
 (0)