@zajno/common 1.3.2 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.github/workflows/CI.yml +8 -0
  2. package/coverage/clover.xml +132 -125
  3. package/coverage/coverage-final.json +39 -39
  4. package/coverage/lcov-report/index.html +25 -25
  5. package/coverage/lcov-report/src/__tests__/helpers/index.html +1 -1
  6. package/coverage/lcov-report/src/__tests__/helpers/main.ts.html +1 -1
  7. package/coverage/lcov-report/src/async/arrays.ts.html +1 -1
  8. package/coverage/lcov-report/src/async/index.html +1 -1
  9. package/coverage/lcov-report/src/dates/calc.ts.html +1 -1
  10. package/coverage/lcov-report/src/dates/convert.ts.html +1 -1
  11. package/coverage/lcov-report/src/dates/datex.ts.html +1 -1
  12. package/coverage/lcov-report/src/dates/format.ts.html +1 -1
  13. package/coverage/lcov-report/src/dates/index.html +1 -1
  14. package/coverage/lcov-report/src/dates/index.ts.html +1 -1
  15. package/coverage/lcov-report/src/dates/parse.ts.html +1 -1
  16. package/coverage/lcov-report/src/dates/period.ts.html +1 -1
  17. package/coverage/lcov-report/src/dates/shift.ts.html +1 -1
  18. package/coverage/lcov-report/src/dates/types.ts.html +1 -1
  19. package/coverage/lcov-report/src/dates/yearDate.ts.html +1 -1
  20. package/coverage/lcov-report/src/enumHelper.ts.html +1 -1
  21. package/coverage/lcov-report/src/event.ts.html +1 -1
  22. package/coverage/lcov-report/src/index.html +1 -1
  23. package/coverage/lcov-report/src/lazy.light.ts.html +3 -3
  24. package/coverage/lcov-report/src/logger/batch.ts.html +1 -1
  25. package/coverage/lcov-report/src/logger/console.ts.html +1 -1
  26. package/coverage/lcov-report/src/logger/index.html +1 -1
  27. package/coverage/lcov-report/src/logger/index.ts.html +1 -1
  28. package/coverage/lcov-report/src/logger/named.ts.html +1 -1
  29. package/coverage/lcov-report/src/logger/proxy.ts.html +1 -1
  30. package/coverage/lcov-report/src/math/arrays.ts.html +32 -8
  31. package/coverage/lcov-report/src/math/calc.ts.html +1 -1
  32. package/coverage/lcov-report/src/math/distribution.ts.html +1 -1
  33. package/coverage/lcov-report/src/math/index.html +11 -11
  34. package/coverage/lcov-report/src/math/index.ts.html +1 -1
  35. package/coverage/lcov-report/src/transitionObserver.ts.html +1 -1
  36. package/coverage/lcov-report/src/types.ts.html +4 -4
  37. package/coverage/lcov-report/src/validation/ValidationErrors.ts.html +1 -1
  38. package/coverage/lcov-report/src/validation/creditCard.ts.html +1 -1
  39. package/coverage/lcov-report/src/validation/helpers.ts.html +1 -1
  40. package/coverage/lcov-report/src/validation/index.html +1 -1
  41. package/coverage/lcov-report/src/validation/index.ts.html +1 -1
  42. package/coverage/lcov-report/src/validation/types.ts.html +1 -1
  43. package/coverage/lcov-report/src/validation/validators.ts.html +1 -1
  44. package/coverage/lcov-report/src/validation/wrappers.ts.html +1 -1
  45. package/coverage/lcov-report/src/viewModels/FlagModel.ts.html +6 -6
  46. package/coverage/lcov-report/src/viewModels/LabeledFlagModel.ts.html +26 -17
  47. package/coverage/lcov-report/src/viewModels/MultiSelectModel.ts.html +104 -95
  48. package/coverage/lcov-report/src/viewModels/NumberModel.ts.html +1 -1
  49. package/coverage/lcov-report/src/viewModels/SelectModel.ts.html +1 -1
  50. package/coverage/lcov-report/src/viewModels/SelectViewModel.ts.html +14 -17
  51. package/coverage/lcov-report/src/viewModels/Validatable.ts.html +12 -12
  52. package/coverage/lcov-report/src/viewModels/index.html +21 -21
  53. package/coverage/lcov-report/src/viewModels/wrappers.ts.html +1 -1
  54. package/coverage/lcov-report/transitionObserver.ts.html +77 -41
  55. package/coverage/lcov.info +185 -171
  56. package/lib/math/arrays.d.ts +2 -1
  57. package/lib/math/arrays.d.ts.map +1 -1
  58. package/lib/math/arrays.js +9 -1
  59. package/lib/math/arrays.js.map +1 -1
  60. package/lib/viewModels/MultiSelectModel.d.ts +2 -0
  61. package/lib/viewModels/MultiSelectModel.d.ts.map +1 -1
  62. package/lib/viewModels/MultiSelectModel.js +3 -1
  63. package/lib/viewModels/MultiSelectModel.js.map +1 -1
  64. package/package.json +1 -1
  65. package/src/math/arrays.ts +9 -1
  66. package/src/viewModels/MultiSelectModel.ts +4 -1
  67. package/src/viewModels/__tests__/multiSelect.test.ts +127 -12
  68. package/yarn-error.log +3709 -0
  69. package/coverage/lcov-report/NumberModel.ts.html +0 -188
  70. package/coverage/lcov-report/arrays.ts.html +0 -602
  71. package/coverage/lcov-report/calc.ts.html +0 -278
  72. package/coverage/lcov-report/enumHelper.ts.html +0 -449
  73. package/coverage/lcov-report/src/viewModels/labeled.ts.html +0 -128
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zajno/common",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "Zajno's re-usable utilities for JS/TS projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,4 +1,4 @@
1
- import { Comparator, Predicate } from '../types';
1
+ import { Comparator, Getter, Predicate } from '../types';
2
2
  import { random } from './calc';
3
3
 
4
4
  export function arrayCompareG<T>(arr: ReadonlyArray<T>, cond: (current: T, previous: T) => boolean): T {
@@ -251,3 +251,11 @@ export function removeItem<T>(array: T[], item: NonFunction<T> | Predicate<T>):
251
251
 
252
252
  return array.splice(index, 1)[0];
253
253
  }
254
+
255
+ export function arrayRepeat<T>(factory: Getter<T>, count = 1) {
256
+ const res: T[] = [];
257
+ for (let i = 0; i < count; ++i) {
258
+ res.push(Getter.getValue(factory));
259
+ }
260
+ return res;
261
+ }
@@ -56,7 +56,7 @@ export class MultiSelect<T = any> extends ValidatableModel<ReadonlyArray<T>> imp
56
56
  set value(v: readonly string[]) { this.selectValues(v); }
57
57
 
58
58
  isIndexSelected(index: number) { return this._indexes.has(index); }
59
- isValueSelected(value: string) { return this.values.includes(value); }
59
+ isValueSelected(value: string) { return this.selectedValues.includes(value); }
60
60
 
61
61
  get count() { return this._items.length; }
62
62
  get selectedCount() { return this._indexes.size; }
@@ -121,6 +121,9 @@ export class MultiSelect<T = any> extends ValidatableModel<ReadonlyArray<T>> imp
121
121
  }
122
122
  };
123
123
 
124
+ selectIndex = (index: number) => this.setIndexSelected(index, true);
125
+ deSelectIndex = (index: number) => this.setIndexSelected(index, false);
126
+
124
127
  reset = () => {
125
128
  super.reset();
126
129
  this.setInitialIndexes();
@@ -1,23 +1,138 @@
1
- import { MultiSelect } from '../MultiSelectModel';
1
+ import { reaction, toJS } from 'mobx';
2
+ import { arrayRepeat } from '../../math';
3
+ import { MultiSelect, MultiSelectString } from '../MultiSelectModel';
4
+
5
+ type SetType<T> = { items: T[], selected: number[], accessor: (item: T) => string };
2
6
 
3
7
  describe('MultiSelectModel', () => {
4
- it('consistent', () => {
8
+ it('creates', () => {
5
9
  expect(() => new MultiSelect(null, null).values).toThrow();
6
10
  expect(() => new MultiSelect([1], null).values).toThrow();
11
+ });
12
+
13
+ const sets: SetType<any>[] = [
14
+ { items: [1, 2, 3], selected: [1], accessor: i => `_${i}_` },
15
+ { items: [1, 2, 3], selected: [], accessor: i => `_${i}_` },
16
+ { items: ['a', 'b', 'c'], selected: [2], accessor: i => i },
17
+ ];
18
+
19
+ describe('consistent', () => {
20
+ sets.forEach((set, setIndex) => {
21
+ it(`variant ${setIndex + 1}`, () => {
22
+ const items = set.items; // [1, 2, 3];
23
+ const accessor = set.accessor; // (i: number) => `_${i}_`;
24
+ const initialSelected = set.selected; // [1];
25
+ const values = items.map(accessor);
26
+ const selectedValues = initialSelected.map(i => accessor(items[i]));
7
27
 
8
- const items = [1, 2, 3];
9
- const accessor = (i: number) => `_${i}_`;
10
- const values = items.map(accessor);
11
- const initialSelected = [1];
28
+ const vm = new MultiSelect(items, accessor, ...initialSelected);
12
29
 
13
- const vm = new MultiSelect(items, accessor, ...initialSelected);
30
+ expect(vm.items).toStrictEqual(items);
31
+ expect(vm.values).toStrictEqual(values);
32
+ expect(vm.count).toBe(items.length);
33
+ expect(vm.selectedCount).toBe(initialSelected.length);
34
+ expect(vm.selectedIndexes).toStrictEqual(initialSelected);
35
+ expect(vm.selectedValues).toStrictEqual(selectedValues);
14
36
 
15
- expect(vm.items).toStrictEqual(items);
16
- expect(vm.values).toStrictEqual(values);
17
- expect(vm.selectedIndexes).toStrictEqual(initialSelected);
37
+ initialSelected.forEach(index => {
38
+ expect(vm.isIndexSelected(index)).toBe(initialSelected.includes(index));
39
+ });
18
40
 
19
- initialSelected.forEach(index => {
20
- expect(vm.isIndexSelected(index)).toBe(initialSelected.includes(index));
41
+ values.forEach((value) => {
42
+ expect(vm.isValueSelected(value)).toBe(selectedValues.includes(value));
43
+ });
44
+ });
21
45
  });
46
+
47
+ });
48
+
49
+ it('reacts', () => {
50
+ const vm = new MultiSelectString(['a', 'b', 'c']);
51
+
52
+ expect(vm.count).toBe(3);
53
+ expect(vm.selectedCount).toBe(0);
54
+ expect(vm.selectedIndexes).toHaveLength(0);
55
+
56
+ const mocks = arrayRepeat(() => jest.fn().mockImplementation(null), 5);
57
+ const [
58
+ onSelectedIndexes,
59
+ onSelectedItems,
60
+ onSelectedValues,
61
+ onIsIndexSelected,
62
+ onIsValueSelected,
63
+ ] = mocks;
64
+
65
+ const wrapMock = mock => ((a: any) => mock(toJS(a)));
66
+
67
+ const expectEmptyCalls = () => {
68
+ expect(onSelectedIndexes).toHaveBeenCalledWith([]);
69
+ expect(onSelectedItems).toHaveBeenCalledWith([]);
70
+ expect(onSelectedValues).toHaveBeenCalledWith([]);
71
+ mocks.forEach(m => m.mockClear());
72
+ };
73
+
74
+ reaction(() => vm.selectedIndexes, wrapMock(onSelectedIndexes));
75
+ reaction(() => vm.selectedItems, wrapMock(onSelectedItems));
76
+ reaction(() => vm.selectedValues, wrapMock(onSelectedValues));
77
+
78
+ // initially – 'false', so expect only when 'true' should be passed
79
+ reaction(() => vm.isIndexSelected(0), wrapMock(onIsIndexSelected));
80
+ reaction(() => vm.isValueSelected('a'), wrapMock(onIsValueSelected));
81
+
82
+ vm.selectIndex(1);
83
+
84
+ expect(onSelectedIndexes).toHaveBeenCalledWith([1]);
85
+ expect(onSelectedItems).toHaveBeenCalledWith(['b']);
86
+ expect(onSelectedValues).toHaveBeenCalledWith(['b']);
87
+ expect(onIsIndexSelected).not.toHaveBeenCalled();
88
+ expect(onIsValueSelected).not.toHaveBeenCalled();
89
+ mocks.forEach(m => m.mockClear());
90
+
91
+ vm.deSelectIndex(1);
92
+ expect(onIsIndexSelected).not.toHaveBeenCalled();
93
+ expect(onIsValueSelected).not.toHaveBeenCalled();
94
+ expectEmptyCalls();
95
+
96
+ vm.selectItem('c');
97
+
98
+ expect(onSelectedIndexes).toHaveBeenCalledWith([2]);
99
+ expect(onSelectedItems).toHaveBeenCalledWith(['c']);
100
+ expect(onSelectedValues).toHaveBeenCalledWith(['c']);
101
+ expect(onIsIndexSelected).not.toHaveBeenCalled();
102
+ expect(onIsValueSelected).not.toHaveBeenCalled();
103
+ mocks.forEach(m => m.mockClear());
104
+
105
+ vm.deSelectItem('c');
106
+ expect(onIsIndexSelected).not.toHaveBeenCalled();
107
+ expect(onIsValueSelected).not.toHaveBeenCalled();
108
+ expectEmptyCalls();
109
+
110
+ vm.selectValue('a');
111
+
112
+ expect(onSelectedIndexes).toHaveBeenCalledWith([0]);
113
+ expect(onSelectedItems).toHaveBeenCalledWith(['a']);
114
+ expect(onSelectedValues).toHaveBeenCalledWith(['a']);
115
+ expect(onIsIndexSelected).toHaveBeenCalledWith(true);
116
+ expect(onIsValueSelected).toHaveBeenCalledWith(true);
117
+ mocks.forEach(m => m.mockClear());
118
+
119
+ vm.deSelectValue('a');
120
+ expect(onIsIndexSelected).toHaveBeenCalledWith(false);
121
+ expect(onIsValueSelected).toHaveBeenCalledWith(false);
122
+ expectEmptyCalls();
123
+
124
+ vm.selectItems(['a', 'b']);
125
+
126
+ expect(onSelectedIndexes).toHaveBeenCalledWith([0, 1]);
127
+ expect(onSelectedItems).toHaveBeenCalledWith(['a', 'b']);
128
+ expect(onSelectedValues).toHaveBeenCalledWith(['a', 'b']);
129
+ expect(onIsIndexSelected).toHaveBeenCalledWith(true);
130
+ expect(onIsValueSelected).toHaveBeenCalledWith(true);
131
+ mocks.forEach(m => m.mockClear());
132
+
133
+ vm.reset();
134
+ expect(onIsIndexSelected).toHaveBeenCalledWith(false);
135
+ expect(onIsValueSelected).toHaveBeenCalledWith(false);
136
+ expectEmptyCalls();
22
137
  });
23
138
  });