-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtest.ts
174 lines (146 loc) · 5.32 KB
/
test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import { flatten, pick, pickMany, pickManyDistinct } from "../index";
import { RandomPicker } from "../randomPicker";
const items = [
{ original: "Bronze", weight: 20 },
{ original: "Silver", weight: 10 },
{ original: "Gold", weight: 3 },
{ original: "Platinum", weight: 1 },
];
describe("RandomPicker", () => {
it("should be created with a list of items with their weight", () => {
const picker = new RandomPicker(items);
expect(picker).toBeDefined();
});
it("should throw an error if created with a wrong set of items", () => {
// Duplicate item
expect(
() => new RandomPicker([...items, { original: "Platinum", weight: 5 }])
).toThrow();
// Empty list
expect(() => new RandomPicker([])).toThrow();
// Negative weight
expect(
() => new RandomPicker([{ original: "Wood", weight: -5 }])
).toThrow();
});
it("should have some utility getters", () => {
const picker = new RandomPicker(items);
expect(picker.getItems()).toEqual(["Bronze", "Silver", "Gold", "Platinum"]);
expect(picker.getWeights()).toEqual([20, 10, 3, 1]);
expect(picker.getTotalWeight()).toEqual(34);
expect(picker.getCount()).toEqual(4);
});
it("should be able to pick an item", () => {
const picker = new RandomPicker(items);
const pickedItem = picker.pick();
expect(items.some((i) => i.original === pickedItem)).toBeTruthy();
});
it("should be able to pick N items", () => {
const picker = new RandomPicker(items);
const picked = picker.pickMany(3);
expect(picked.length).toBe(3);
expect(
picked.every((p) => items.some((i) => i.original === p))
).toBeTruthy();
});
it("works with objects", () => {
const objectItems = [
{ original: { name: "Bronze" }, weight: 20 },
{ original: { name: "Silver" }, weight: 10 },
{ original: { name: "Gold" }, weight: 3 },
{ original: { name: "Platinum" }, weight: 1 },
];
const picker = new RandomPicker(objectItems);
const pickedItem = picker.pick();
expect(
objectItems.some((item) => item.original.name === pickedItem.name)
).toBeTruthy();
});
it("uses the custom random generator when passed", () => {
const pickerAlwaysFirst = new RandomPicker(items, { next: () => 0 });
const picked1 = pickerAlwaysFirst.pick();
const picked2 = pickerAlwaysFirst.pick();
const picked3 = pickerAlwaysFirst.pick();
const testFirstItem = items.at(0)?.original;
expect(
[picked1, picked2, picked3].every((item) => item === testFirstItem)
).toBeTruthy();
const pickerAlwaysLast = new RandomPicker(items, { next: () => 1 });
const picked4 = pickerAlwaysLast.pick();
const picked5 = pickerAlwaysLast.pick();
const picked6 = pickerAlwaysLast.pick();
const testLastItem = items.at(-1)?.original;
expect(
[picked4, picked5, picked6].every((item) => item === testLastItem)
).toBeTruthy();
});
it("should not allow random generator going outside boundaries of [0-1]", () => {
const picker = new RandomPicker(items, { next: () => 5 });
expect(() => picker.pick()).toThrow();
});
it("should remove items if flag is enabled", () => {
const picker = new RandomPicker(items, { removeOnPick: true });
expect(picker.getCount()).toBe(4);
picker.pick();
expect(picker.getCount()).toBe(3);
picker.pickMany(2);
expect(picker.getCount()).toBe(1);
picker.pick();
expect(picker.getCount()).toBe(0);
expect(() => picker.pick()).toThrow();
});
});
describe("pick", () => {
it("should pick", () => {
const pickedItem = pick(items);
expect(items.some((i) => i.original === pickedItem)).toBeTruthy();
});
});
describe("pickMany", () => {
it("should pick many", () => {
const picked = pickMany(items, 3);
expect(picked.length).toBe(3);
expect(
picked.every((p) => items.some((i) => i.original === p))
).toBeTruthy();
});
});
describe("flatten", () => {
const itemsWithDuplicates = [...items, { original: "Gold", weight: 1 }];
const flat = flatten(itemsWithDuplicates);
expect(flat.length).toBe(4);
expect(flat.find((i) => i.original === "Gold")).toStrictEqual({
original: "Gold",
weight: 4,
});
});
describe("pickManyDistinct", () => {
it("should pick many distinct items", () => {
const picker = new RandomPicker(items);
const picked = picker.pickManyDistinct(2);
const pickedUnique = new Set(picked);
expect(pickedUnique.size).toBe(2);
expect(picked.length).toBe(2);
expect(
picked.every((p) => items.some((i) => i.original === p))
).toBeTruthy();
expect(picker.getCount()).toBe(items.length);
});
it("should return all items when amount picked is same as array length", () => {
const picker = new RandomPicker(items);
const picked = picker.pickManyDistinct(items.length);
const pickedUnique = new Set(picked);
expect(picked.length).toBe(items.length);
expect(pickedUnique.size).toBe(items.length);
expect(
picked.every((p) => items.some((i) => i.original === p))
).toBeTruthy();
expect(picker.getCount()).toBe(items.length);
});
it("should throw error when picked more items than array length", () => {
expect(() => pickManyDistinct(items, 8)).toThrow();
});
it("should not allow negative numbers to be picked", () => {
expect(() => pickManyDistinct(items, -1)).toThrow();
});
});