@zajno/common 1.2.8 → 1.3.2
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.
- package/coverage/clover.xml +587 -275
- package/coverage/coverage-final.json +39 -30
- package/coverage/lcov-report/NumberModel.ts.html +188 -0
- package/coverage/lcov-report/arrays.ts.html +602 -0
- package/coverage/lcov-report/calc.ts.html +278 -0
- package/coverage/lcov-report/enumHelper.ts.html +449 -0
- package/coverage/lcov-report/index.html +48 -33
- package/coverage/lcov-report/src/__tests__/helpers/index.html +1 -1
- package/coverage/lcov-report/src/__tests__/helpers/main.ts.html +2 -2
- package/coverage/lcov-report/src/async/arrays.ts.html +5 -5
- package/coverage/lcov-report/src/async/index.html +1 -1
- package/coverage/lcov-report/src/dates/calc.ts.html +1 -1
- package/coverage/lcov-report/src/dates/convert.ts.html +1 -1
- package/coverage/lcov-report/src/dates/datex.ts.html +1 -1
- package/coverage/lcov-report/src/dates/format.ts.html +1 -1
- package/coverage/lcov-report/src/dates/index.html +1 -1
- package/coverage/lcov-report/src/dates/index.ts.html +1 -1
- package/coverage/lcov-report/src/dates/parse.ts.html +1 -1
- package/coverage/lcov-report/src/dates/period.ts.html +1 -1
- package/coverage/lcov-report/src/dates/shift.ts.html +1 -1
- package/coverage/lcov-report/src/dates/types.ts.html +1 -1
- package/coverage/lcov-report/src/dates/yearDate.ts.html +1 -1
- package/coverage/lcov-report/src/enumHelper.ts.html +11 -11
- package/coverage/lcov-report/src/event.ts.html +3 -3
- package/coverage/lcov-report/src/index.html +41 -11
- package/coverage/lcov-report/src/lazy.light.ts.html +155 -0
- package/coverage/lcov-report/src/logger/batch.ts.html +107 -0
- package/coverage/lcov-report/src/logger/console.ts.html +10 -25
- package/coverage/lcov-report/src/logger/index.html +54 -39
- package/coverage/lcov-report/src/logger/index.ts.html +88 -61
- package/coverage/lcov-report/src/logger/named.ts.html +31 -31
- package/coverage/lcov-report/src/logger/proxy.ts.html +13 -13
- package/coverage/lcov-report/src/math/arrays.ts.html +269 -32
- package/coverage/lcov-report/src/math/calc.ts.html +11 -11
- package/coverage/lcov-report/src/math/distribution.ts.html +2 -2
- package/coverage/lcov-report/src/math/index.html +11 -11
- package/coverage/lcov-report/src/math/index.ts.html +6 -6
- package/coverage/lcov-report/src/transitionObserver.ts.html +5 -5
- package/coverage/lcov-report/src/types.ts.html +158 -0
- package/coverage/lcov-report/src/validation/ValidationErrors.ts.html +22 -22
- package/coverage/lcov-report/src/validation/creditCard.ts.html +4 -4
- package/coverage/lcov-report/src/validation/helpers.ts.html +6 -6
- package/coverage/lcov-report/src/validation/index.html +1 -1
- package/coverage/lcov-report/src/validation/index.ts.html +6 -6
- package/coverage/lcov-report/src/validation/types.ts.html +2 -2
- package/coverage/lcov-report/src/validation/validators.ts.html +5 -5
- package/coverage/lcov-report/src/validation/wrappers.ts.html +5 -5
- package/coverage/lcov-report/src/viewModels/FlagModel.ts.html +212 -0
- package/coverage/lcov-report/src/viewModels/LabeledFlagModel.ts.html +137 -0
- package/coverage/lcov-report/src/viewModels/MultiSelectModel.ts.html +563 -0
- package/coverage/lcov-report/src/viewModels/NumberModel.ts.html +197 -0
- package/coverage/lcov-report/src/viewModels/SelectModel.ts.html +464 -0
- package/coverage/lcov-report/src/viewModels/SelectViewModel.ts.html +437 -0
- package/coverage/lcov-report/src/viewModels/Validatable.ts.html +329 -0
- package/coverage/lcov-report/src/viewModels/index.html +186 -0
- package/coverage/lcov-report/src/viewModels/labeled.ts.html +128 -0
- package/coverage/lcov-report/src/viewModels/wrappers.ts.html +227 -0
- package/coverage/lcov-report/transitionObserver.ts.html +41 -77
- package/coverage/lcov.info +1128 -438
- package/lib/event.d.ts.map +1 -1
- package/lib/event.js +1 -1
- package/lib/event.js.map +1 -1
- package/lib/logger/batch.d.ts +3 -0
- package/lib/logger/batch.d.ts.map +1 -0
- package/lib/logger/batch.js +12 -0
- package/lib/logger/batch.js.map +1 -0
- package/lib/logger/console.d.ts +0 -1
- package/lib/logger/console.d.ts.map +1 -1
- package/lib/logger/console.js +0 -3
- package/lib/logger/console.js.map +1 -1
- package/lib/logger/file.d.ts +15 -0
- package/lib/logger/file.d.ts.map +1 -0
- package/lib/logger/file.js +43 -0
- package/lib/logger/file.js.map +1 -0
- package/lib/logger/index.d.ts +7 -6
- package/lib/logger/index.d.ts.map +1 -1
- package/lib/logger/index.js +34 -21
- package/lib/logger/index.js.map +1 -1
- package/lib/logger/named.js +3 -3
- package/lib/logger/named.js.map +1 -1
- package/lib/logger/proxy.d.ts +1 -1
- package/lib/logger/proxy.d.ts.map +1 -1
- package/lib/logger/proxy.js +2 -2
- package/lib/logger/proxy.js.map +1 -1
- package/lib/math/arrays.d.ts +15 -0
- package/lib/math/arrays.d.ts.map +1 -1
- package/lib/math/arrays.js +69 -1
- package/lib/math/arrays.js.map +1 -1
- package/lib/transitionObserver.d.ts.map +1 -1
- package/lib/transitionObserver.js +2 -2
- package/lib/transitionObserver.js.map +1 -1
- package/lib/types.d.ts +9 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +18 -0
- package/lib/types.js.map +1 -1
- package/lib/viewModels/FlagModel.d.ts +19 -0
- package/lib/viewModels/FlagModel.d.ts.map +1 -0
- package/lib/viewModels/FlagModel.js +39 -0
- package/lib/viewModels/FlagModel.js.map +1 -0
- package/lib/viewModels/MultiSelectModel.d.ts +45 -0
- package/lib/viewModels/MultiSelectModel.d.ts.map +1 -0
- package/lib/viewModels/MultiSelectModel.js +162 -0
- package/lib/viewModels/MultiSelectModel.js.map +1 -0
- package/lib/viewModels/NumberModel.d.ts +18 -0
- package/lib/viewModels/NumberModel.d.ts.map +1 -0
- package/lib/viewModels/NumberModel.js +41 -0
- package/lib/viewModels/NumberModel.js.map +1 -0
- package/lib/viewModels/PromptModal.d.ts +31 -0
- package/lib/viewModels/PromptModal.d.ts.map +1 -0
- package/lib/viewModels/PromptModal.js +57 -0
- package/lib/viewModels/PromptModal.js.map +1 -0
- package/lib/viewModels/SelectModel.d.ts +33 -0
- package/lib/viewModels/SelectModel.d.ts.map +1 -0
- package/lib/viewModels/SelectModel.js +110 -0
- package/lib/viewModels/SelectModel.js.map +1 -0
- package/lib/viewModels/{TextInputViewModel.d.ts → TextModel.d.ts} +12 -10
- package/lib/viewModels/TextModel.d.ts.map +1 -0
- package/lib/viewModels/{TextInputViewModel.js → TextModel.js} +13 -28
- package/lib/viewModels/TextModel.js.map +1 -0
- package/lib/viewModels/Validatable.d.ts +9 -7
- package/lib/viewModels/Validatable.d.ts.map +1 -1
- package/lib/viewModels/Validatable.js +22 -8
- package/lib/viewModels/Validatable.js.map +1 -1
- package/lib/viewModels/ValuesCollector.d.ts +26 -0
- package/lib/viewModels/ValuesCollector.d.ts.map +1 -0
- package/lib/viewModels/ValuesCollector.js +51 -0
- package/lib/viewModels/ValuesCollector.js.map +1 -0
- package/lib/viewModels/index.d.ts +8 -5
- package/lib/viewModels/index.d.ts.map +1 -1
- package/lib/viewModels/index.js +8 -5
- package/lib/viewModels/index.js.map +1 -1
- package/lib/viewModels/types.d.ts +16 -0
- package/lib/viewModels/types.d.ts.map +1 -0
- package/lib/viewModels/types.js +3 -0
- package/lib/viewModels/types.js.map +1 -0
- package/lib/viewModels/wrappers.d.ts +12 -0
- package/lib/viewModels/wrappers.d.ts.map +1 -0
- package/lib/viewModels/wrappers.js +43 -0
- package/lib/viewModels/wrappers.js.map +1 -0
- package/package.json +1 -1
- package/src/event.ts +2 -2
- package/src/logger/__tests__/{index.test.ts → logger.test.ts} +97 -41
- package/src/logger/batch.ts +9 -0
- package/src/logger/console.ts +0 -5
- package/src/logger/file.ts +46 -0
- package/src/logger/index.ts +37 -28
- package/src/logger/named.ts +3 -3
- package/src/logger/proxy.ts +2 -2
- package/src/math/__tests__/arrays.test.ts +53 -0
- package/src/math/arrays.ts +79 -0
- package/src/transitionObserver.ts +2 -2
- package/src/types.ts +21 -0
- package/src/viewModels/FlagModel.ts +44 -0
- package/src/viewModels/MultiSelectModel.ts +161 -0
- package/src/viewModels/NumberModel.ts +39 -0
- package/src/viewModels/PromptModal.ts +65 -0
- package/src/viewModels/SelectModel.ts +128 -0
- package/src/viewModels/{TextInputViewModel.ts → TextModel.ts} +25 -28
- package/src/viewModels/Validatable.ts +26 -11
- package/src/viewModels/ValuesCollector.ts +81 -0
- package/src/viewModels/__tests__/multiSelect.test.ts +23 -0
- package/src/viewModels/__tests__/select.test.ts +71 -0
- package/src/viewModels/__tests__/wrappers.test.ts +79 -0
- package/src/viewModels/index.ts +10 -5
- package/src/viewModels/types.ts +19 -0
- package/src/viewModels/wrappers.ts +49 -0
- package/lib/viewModels/PromptModalViewModel.d.ts +0 -27
- package/lib/viewModels/PromptModalViewModel.d.ts.map +0 -1
- package/lib/viewModels/PromptModalViewModel.js +0 -56
- package/lib/viewModels/PromptModalViewModel.js.map +0 -1
- package/lib/viewModels/RadioButtonGroupViewModel.d.ts +0 -11
- package/lib/viewModels/RadioButtonGroupViewModel.d.ts.map +0 -1
- package/lib/viewModels/RadioButtonGroupViewModel.js +0 -51
- package/lib/viewModels/RadioButtonGroupViewModel.js.map +0 -1
- package/lib/viewModels/RadioButtonViewModel.d.ts +0 -9
- package/lib/viewModels/RadioButtonViewModel.d.ts.map +0 -1
- package/lib/viewModels/RadioButtonViewModel.js +0 -32
- package/lib/viewModels/RadioButtonViewModel.js.map +0 -1
- package/lib/viewModels/SelectViewModel.d.ts +0 -25
- package/lib/viewModels/SelectViewModel.d.ts.map +0 -1
- package/lib/viewModels/SelectViewModel.js +0 -88
- package/lib/viewModels/SelectViewModel.js.map +0 -1
- package/lib/viewModels/TextInputViewModel.d.ts.map +0 -1
- package/lib/viewModels/TextInputViewModel.js.map +0 -1
- package/src/viewModels/PromptModalViewModel.ts +0 -71
- package/src/viewModels/RadioButtonGroupViewModel.ts +0 -47
- package/src/viewModels/RadioButtonViewModel.ts +0 -26
- package/src/viewModels/SelectViewModel.ts +0 -88
- package/yarn-error.log +0 -3709
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
import faker from 'faker';
|
|
2
|
-
import logger, { createLogger, getMode,
|
|
2
|
+
import logger, { batchLoggers, createLogger, getMode, ILogger, setMode } from '..';
|
|
3
3
|
import fc from 'fast-check';
|
|
4
4
|
import { toArbitrary } from '../../__tests__/helpers/main';
|
|
5
|
+
import { Getter } from '../../types';
|
|
5
6
|
|
|
6
7
|
const CONSOLE = console;
|
|
7
8
|
|
|
8
9
|
describe('#logger-tests', () => {
|
|
9
10
|
|
|
10
|
-
const customLogger
|
|
11
|
-
|
|
11
|
+
const customLogger = {
|
|
12
|
+
log: jest.fn().mockImplementation(null),
|
|
13
|
+
warn: jest.fn().mockImplementation(null),
|
|
14
|
+
error: jest.fn().mockImplementation(null),
|
|
15
|
+
};
|
|
16
|
+
const customLoggerGetter = () => customLogger;
|
|
17
|
+
|
|
18
|
+
const consoleMocks: Record<keyof ILogger, jest.SpyInstance> = {
|
|
19
|
+
log: jest.spyOn(CONSOLE, 'log').mockImplementation(null),
|
|
20
|
+
warn: jest.spyOn(CONSOLE, 'warn').mockImplementation(null),
|
|
21
|
+
error: jest.spyOn(CONSOLE, 'error').mockImplementation(null),
|
|
22
|
+
} as const;
|
|
23
|
+
const loggerMethods = Object.keys(consoleMocks) as (keyof ILogger)[];
|
|
12
24
|
|
|
13
25
|
it('use logger without mode (default logger)', () => {
|
|
14
26
|
const _textToLog: fc.Arbitrary<string> = toArbitrary(() => faker.internet.url());
|
|
@@ -19,10 +31,8 @@ describe('#logger-tests', () => {
|
|
|
19
31
|
const methodName = loggerMethods[iteration];
|
|
20
32
|
logger[methodName](textToLog);
|
|
21
33
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
expect(getMode()).toBeFalsy();
|
|
25
|
-
expect(spyCLog).not.toHaveBeenCalled();
|
|
34
|
+
expect(getMode()).toBe(false);
|
|
35
|
+
expect(consoleMocks[methodName]).not.toHaveBeenCalled();
|
|
26
36
|
|
|
27
37
|
++iteration;
|
|
28
38
|
}), {
|
|
@@ -30,45 +40,45 @@ describe('#logger-tests', () => {
|
|
|
30
40
|
});
|
|
31
41
|
});
|
|
32
42
|
|
|
33
|
-
it('use logger with runtime mode
|
|
43
|
+
it('use logger with runtime mode disabling', () => {
|
|
34
44
|
const _textToLog: fc.Arbitrary<string> = toArbitrary(() => faker.random.word());
|
|
35
45
|
|
|
36
46
|
let iteration = 0;
|
|
37
47
|
fc.assert(
|
|
38
48
|
fc.property(_textToLog, (textToLog) => {
|
|
39
|
-
|
|
49
|
+
// set mode before or after creating a new logger
|
|
50
|
+
|
|
51
|
+
if (iteration % 2 === 0) { setMode('console'); setMode(customLoggerGetter); setMode(false); }
|
|
40
52
|
const logger = createLogger(faker.random.word());
|
|
41
|
-
if (iteration % 2 === 1) { setMode('console'); setMode(
|
|
53
|
+
if (iteration % 2 === 1) { setMode('console'); setMode(customLoggerGetter); setMode(false); }
|
|
42
54
|
|
|
43
55
|
const methodName = loggerMethods[iteration % 3];
|
|
44
56
|
logger[methodName](textToLog);
|
|
45
57
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
expect(getMode()).toBeFalsy();
|
|
49
|
-
expect(spyLogger).not.toHaveBeenCalled();
|
|
58
|
+
expect(getMode()).toBe(false);
|
|
59
|
+
expect(consoleMocks[methodName]).not.toHaveBeenCalled();
|
|
50
60
|
++iteration;
|
|
51
61
|
}), {
|
|
52
62
|
numRuns: loggerMethods.length * 2,
|
|
53
63
|
});
|
|
54
64
|
});
|
|
55
65
|
|
|
56
|
-
it('use logger with \'
|
|
66
|
+
it('use logger with \'null\' mode', () => {
|
|
57
67
|
const _textToLog: fc.Arbitrary<string> = toArbitrary(() => faker.internet.url());
|
|
58
68
|
|
|
59
69
|
let iteration = 0;
|
|
60
70
|
fc.assert(
|
|
61
71
|
fc.property(_textToLog, (textToLog) => {
|
|
62
|
-
if (iteration % 2 === 0) setMode(
|
|
72
|
+
if (iteration % 2 === 0) setMode(null);
|
|
63
73
|
const logger = createLogger(faker.random.word());
|
|
64
|
-
if (iteration % 2 === 1) setMode(
|
|
74
|
+
if (iteration % 2 === 1) setMode(null);
|
|
65
75
|
|
|
66
76
|
const methodName = loggerMethods[iteration % 3];
|
|
67
77
|
logger[methodName](textToLog);
|
|
68
78
|
|
|
69
79
|
const spyLogger = jest.spyOn(CONSOLE, methodName);
|
|
70
80
|
|
|
71
|
-
expect(getMode()).
|
|
81
|
+
expect(getMode()).toBeNull();
|
|
72
82
|
expect(spyLogger).not.toHaveBeenCalled();
|
|
73
83
|
++iteration;
|
|
74
84
|
}), {
|
|
@@ -76,75 +86,121 @@ describe('#logger-tests', () => {
|
|
|
76
86
|
});
|
|
77
87
|
});
|
|
78
88
|
|
|
79
|
-
it('use logger with \'
|
|
80
|
-
const
|
|
89
|
+
it('use logger with \'console\' mode', () => {
|
|
90
|
+
const loggerName = `[${faker.random.word()}]`;
|
|
91
|
+
const _textToLog: fc.Arbitrary<string> = toArbitrary(() => faker.random.word());
|
|
81
92
|
|
|
82
93
|
let iteration = 0;
|
|
83
94
|
fc.assert(
|
|
84
95
|
fc.property(_textToLog, (textToLog) => {
|
|
85
|
-
if (iteration % 2 === 0) setMode(null);
|
|
86
|
-
const logger = createLogger(faker.random.word());
|
|
87
|
-
if (iteration % 2 === 1) setMode(null);
|
|
88
96
|
|
|
97
|
+
if (iteration % 2 === 0) setMode('console');
|
|
98
|
+
const logger = createLogger(loggerName);
|
|
99
|
+
if (iteration % 2 === 1) setMode('console');
|
|
89
100
|
const methodName = loggerMethods[iteration % 3];
|
|
90
101
|
logger[methodName](textToLog);
|
|
91
102
|
|
|
92
|
-
|
|
103
|
+
expect(getMode()).toBe('console');
|
|
104
|
+
expect(consoleMocks[methodName]).toHaveBeenCalledWith(loggerName, textToLog);
|
|
105
|
+
consoleMocks[methodName].mockClear();
|
|
93
106
|
|
|
94
|
-
expect(getMode()).toBeNull();
|
|
95
|
-
expect(spyLogger).not.toHaveBeenCalled();
|
|
96
107
|
++iteration;
|
|
97
108
|
}), {
|
|
98
109
|
numRuns: loggerMethods.length * 2,
|
|
99
110
|
});
|
|
100
111
|
});
|
|
101
112
|
|
|
102
|
-
it('use logger with
|
|
113
|
+
it('use logger with custom mode', () => {
|
|
103
114
|
const loggerName = `[${faker.random.word()}]`;
|
|
104
115
|
const _textToLog: fc.Arbitrary<string> = toArbitrary(() => faker.random.word());
|
|
105
116
|
|
|
106
117
|
let iteration = 0;
|
|
107
118
|
fc.assert(
|
|
108
119
|
fc.property(_textToLog, (textToLog) => {
|
|
109
|
-
|
|
110
|
-
if (iteration % 2 === 0) setMode('console');
|
|
120
|
+
if (iteration % 2 === 0) setMode(customLoggerGetter);
|
|
111
121
|
const logger = createLogger(loggerName);
|
|
112
|
-
if (iteration % 2 === 1) setMode(
|
|
122
|
+
if (iteration % 2 === 1) setMode(customLoggerGetter);
|
|
123
|
+
|
|
113
124
|
const methodName = loggerMethods[iteration % 3];
|
|
114
125
|
logger[methodName](textToLog);
|
|
115
126
|
|
|
116
|
-
const
|
|
127
|
+
const impl = customLogger[methodName];
|
|
117
128
|
|
|
118
|
-
expect(getMode()).toBe(
|
|
119
|
-
expect(
|
|
129
|
+
expect(getMode()).toBe(customLoggerGetter);
|
|
130
|
+
expect(impl).toHaveBeenCalledWith(loggerName, textToLog);
|
|
131
|
+
impl.mockClear();
|
|
120
132
|
++iteration;
|
|
121
133
|
}), {
|
|
122
134
|
numRuns: loggerMethods.length * 2,
|
|
123
135
|
});
|
|
124
136
|
});
|
|
125
137
|
|
|
126
|
-
it('use logger with
|
|
138
|
+
it('use logger with override mode #override', () => {
|
|
139
|
+
|
|
127
140
|
const loggerName = `[${faker.random.word()}]`;
|
|
128
141
|
const _textToLog: fc.Arbitrary<string> = toArbitrary(() => faker.random.word());
|
|
129
142
|
|
|
143
|
+
expect(Getter.getValue(customLoggerGetter as Getter<ILogger>)).toBe(customLogger);
|
|
144
|
+
|
|
145
|
+
setMode('console');
|
|
146
|
+
|
|
130
147
|
let iteration = 0;
|
|
131
148
|
fc.assert(
|
|
132
149
|
fc.property(_textToLog, (textToLog) => {
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
|
|
150
|
+
const loggerDisabled = createLogger(loggerName, false);
|
|
151
|
+
const loggerCustom = createLogger(loggerName, customLoggerGetter);
|
|
152
|
+
|
|
153
|
+
const methodName = loggerMethods[iteration % 3];
|
|
154
|
+
loggerDisabled[methodName](textToLog);
|
|
155
|
+
expect(consoleMocks[methodName]).not.toHaveBeenCalled();
|
|
156
|
+
|
|
157
|
+
loggerCustom[methodName](textToLog);
|
|
158
|
+
|
|
159
|
+
expect(consoleMocks[methodName]).not.toHaveBeenCalled();
|
|
160
|
+
|
|
161
|
+
const impl = customLogger[methodName];
|
|
162
|
+
expect(impl).toHaveBeenCalledWith(loggerName, textToLog);
|
|
163
|
+
impl.mockClear();
|
|
164
|
+
|
|
165
|
+
++iteration;
|
|
166
|
+
}), {
|
|
167
|
+
numRuns: loggerMethods.length,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
expect(getMode()).toBe('console');
|
|
171
|
+
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('batches loggers', () => {
|
|
175
|
+
|
|
176
|
+
const loggerName = `[${faker.random.word()}]`;
|
|
177
|
+
const _textToLog: fc.Arbitrary<string> = toArbitrary(() => faker.random.word());
|
|
178
|
+
|
|
179
|
+
setMode(false);
|
|
180
|
+
|
|
181
|
+
let iteration = 0;
|
|
182
|
+
fc.assert(
|
|
183
|
+
fc.property(_textToLog, (textToLog) => {
|
|
184
|
+
const logger = batchLoggers(
|
|
185
|
+
createLogger(loggerName, 'console'),
|
|
186
|
+
createLogger(loggerName, customLoggerGetter),
|
|
187
|
+
);
|
|
136
188
|
|
|
137
189
|
const methodName = loggerMethods[iteration % 3];
|
|
138
190
|
logger[methodName](textToLog);
|
|
139
191
|
|
|
140
|
-
|
|
192
|
+
expect(consoleMocks[methodName]).toHaveBeenCalledWith(loggerName, textToLog);
|
|
193
|
+
const impl = customLogger[methodName];
|
|
194
|
+
expect(impl).toHaveBeenCalledWith(loggerName, textToLog);
|
|
195
|
+
impl.mockClear();
|
|
141
196
|
|
|
142
|
-
expect(getMode()).toBe(customLogger);
|
|
143
|
-
expect(spyLogger).toHaveBeenCalledWith(loggerName, textToLog);
|
|
144
197
|
++iteration;
|
|
145
198
|
}), {
|
|
146
|
-
numRuns: loggerMethods.length
|
|
199
|
+
numRuns: loggerMethods.length,
|
|
147
200
|
});
|
|
201
|
+
|
|
202
|
+
expect(getMode()).toBe(false);
|
|
203
|
+
|
|
148
204
|
});
|
|
149
205
|
|
|
150
206
|
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ILogger } from './abstractions';
|
|
2
|
+
|
|
3
|
+
export function batchLoggers(...loggers: ILogger[]): ILogger {
|
|
4
|
+
return {
|
|
5
|
+
log: (...args) => loggers.forEach(l => l.log(...args)),
|
|
6
|
+
warn: (...args) => loggers.forEach(l => l.warn(...args)),
|
|
7
|
+
error: (...args) => loggers.forEach(l => l.error(...args)),
|
|
8
|
+
};
|
|
9
|
+
}
|
package/src/logger/console.ts
CHANGED
|
@@ -4,12 +4,7 @@ import { NamedLogger } from './named';
|
|
|
4
4
|
export const CONSOLE: ILogger = console;
|
|
5
5
|
|
|
6
6
|
export class ConsoleLogger extends NamedLogger {
|
|
7
|
-
|
|
8
7
|
protected get implementation() { return CONSOLE; }
|
|
9
|
-
|
|
10
|
-
constructor(name?: string, enabled = true) {
|
|
11
|
-
super(name, enabled);
|
|
12
|
-
}
|
|
13
8
|
}
|
|
14
9
|
|
|
15
10
|
export class BufferedConsoleLogger implements ILogger {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as FS from 'fs';
|
|
2
|
+
import * as Util from 'util';
|
|
3
|
+
import { ILogger } from './abstractions';
|
|
4
|
+
import { Getter } from '../types';
|
|
5
|
+
|
|
6
|
+
export class FileLoggerNode implements ILogger {
|
|
7
|
+
private readonly _buffer: string[];
|
|
8
|
+
|
|
9
|
+
constructor(readonly fileName: Getter<string>, bufferMode = false) {
|
|
10
|
+
this._buffer = bufferMode ? [] : null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** @example Path.resolve(__dirname, `../run.${new Date().toISOString()}.log`) */
|
|
14
|
+
private get logFilePath() { return Getter.getValue(this.fileName); }
|
|
15
|
+
|
|
16
|
+
log = (...args: any[]) => {
|
|
17
|
+
this.appendToFile(...args);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
warn(...args: any[]) {
|
|
21
|
+
this.appendToFile(...args);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
error(...args: any[]) {
|
|
25
|
+
this.appendToFile(...args);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public flush() {
|
|
29
|
+
if (!this._buffer) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
FS.writeFileSync(this.logFilePath, this._buffer.join(''));
|
|
34
|
+
this._buffer.length = 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private appendToFile(..._args: any[]) {
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
const str = Util.format.apply(null, arguments) + '\n';
|
|
40
|
+
if (this._buffer) {
|
|
41
|
+
this._buffer.push(str);
|
|
42
|
+
} else {
|
|
43
|
+
FS.appendFileSync(this.logFilePath, str);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/logger/index.ts
CHANGED
|
@@ -1,44 +1,36 @@
|
|
|
1
|
+
import { Getter } from '../types';
|
|
1
2
|
import { ILogger, LoggerFunction } from './abstractions';
|
|
2
3
|
import { CONSOLE, ConsoleLogger } from './console';
|
|
3
|
-
import {
|
|
4
|
+
import { ProxyLogger } from './proxy';
|
|
5
|
+
import { batchLoggers } from './batch';
|
|
6
|
+
import { removeItem } from '../math';
|
|
4
7
|
|
|
5
8
|
export { NamedLogger } from './named';
|
|
6
|
-
export { ILogger, LoggerFunction };
|
|
7
|
-
export { ConsoleLogger };
|
|
9
|
+
export { ILogger, LoggerFunction, ConsoleLogger, batchLoggers };
|
|
8
10
|
|
|
9
11
|
// TBD Introduce more logger types ?
|
|
10
12
|
export type LoggerTypes = 'console';
|
|
11
|
-
export type LoggerFactory = (() => ILogger);
|
|
12
13
|
|
|
13
|
-
let Mode: LoggerTypes | false |
|
|
14
|
+
let Mode: LoggerTypes | false | Getter<ILogger> = process.env.COMMON_UTILS_LOGGER as LoggerTypes || false;
|
|
14
15
|
|
|
15
16
|
const proxies: ProxyLogger[] = [];
|
|
16
17
|
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
case false: {
|
|
24
|
-
return EMPTY_LOGGER;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
default: {
|
|
28
|
-
if (typeof Mode === 'function') {
|
|
29
|
-
return Mode();
|
|
30
|
-
}
|
|
18
|
+
export function createLogger(name: string, mode: typeof Mode = undefined): ILogger {
|
|
19
|
+
const result = _createImplementation(mode);
|
|
20
|
+
const proxy = new ProxyLogger(result, name);
|
|
21
|
+
proxies.push(proxy);
|
|
22
|
+
return proxy;
|
|
23
|
+
}
|
|
31
24
|
|
|
32
|
-
|
|
25
|
+
export function detachLogger(instance: ILogger, terminate = false) {
|
|
26
|
+
const item = removeItem(proxies, instance as ProxyLogger);
|
|
27
|
+
if (item) {
|
|
28
|
+
if (terminate) {
|
|
29
|
+
item.disable();
|
|
33
30
|
}
|
|
31
|
+
return true;
|
|
34
32
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
export function createLogger(name: string, forceDisable = false): ILogger {
|
|
38
|
-
const result = _createImplementation();
|
|
39
|
-
const proxy = new ProxyLogger(result, name, !forceDisable);
|
|
40
|
-
proxies.push(proxy);
|
|
41
|
-
return proxy;
|
|
33
|
+
return false;
|
|
42
34
|
}
|
|
43
35
|
|
|
44
36
|
export function setMode(mode: typeof Mode) {
|
|
@@ -57,6 +49,23 @@ export function setMode(mode: typeof Mode) {
|
|
|
57
49
|
|
|
58
50
|
export function getMode() { return Mode; }
|
|
59
51
|
|
|
60
|
-
const logger: ILogger = createLogger(
|
|
52
|
+
const logger: ILogger = createLogger(null, false);
|
|
61
53
|
|
|
62
54
|
export default logger;
|
|
55
|
+
|
|
56
|
+
function _createImplementation(overrideMode: typeof Mode = undefined): ILogger {
|
|
57
|
+
const mode = overrideMode !== undefined ? overrideMode : Mode;
|
|
58
|
+
switch (mode) {
|
|
59
|
+
case 'console': {
|
|
60
|
+
return CONSOLE;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
case false: {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
default: {
|
|
68
|
+
return Getter.getValue(mode as Getter<ILogger>);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
package/src/logger/named.ts
CHANGED
|
@@ -28,15 +28,15 @@ export abstract class NamedLogger implements ILogger, ILoggerSwitchable {
|
|
|
28
28
|
|
|
29
29
|
this.log = this._name
|
|
30
30
|
? (...args) => this.implementation.log(this._name, ...args)
|
|
31
|
-
:
|
|
31
|
+
: this.implementation.log;
|
|
32
32
|
|
|
33
33
|
this.warn = this._name
|
|
34
34
|
? (...args) => this.implementation.warn(this._name, ...args)
|
|
35
|
-
:
|
|
35
|
+
: this.implementation.warn;
|
|
36
36
|
|
|
37
37
|
this.error = this._name
|
|
38
38
|
? (...args) => this.implementation.error(this._name, ...args)
|
|
39
|
-
:
|
|
39
|
+
: this.implementation.error;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
disable() {
|
package/src/logger/proxy.ts
CHANGED
|
@@ -13,8 +13,8 @@ export class ProxyLogger extends NamedLogger {
|
|
|
13
13
|
|
|
14
14
|
private _logger: ILogger = null;
|
|
15
15
|
|
|
16
|
-
constructor(logger: ILogger, name
|
|
17
|
-
super(name,
|
|
16
|
+
constructor(logger: ILogger, name: string) {
|
|
17
|
+
super(name, logger != null);
|
|
18
18
|
this._logger = logger;
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -64,6 +64,45 @@ describe('math/arrays', () => {
|
|
|
64
64
|
expect(arrays.arrayFirstResult([1, 2, 3], i => i == 2 ? 'pass' : false)).toBe('pass');
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
+
it('arraysCompare', () => {
|
|
68
|
+
expect(arrays.arraysCompare(null, null)).toBeNull();
|
|
69
|
+
expect(arrays.arraysCompare([], null)).toBeNull();
|
|
70
|
+
|
|
71
|
+
const result = (missing, extra, diff) => ({ missing, extra, diff });
|
|
72
|
+
|
|
73
|
+
expect(arrays.arraysCompare([], [])).toStrictEqual(result([], [], 0));
|
|
74
|
+
expect(arrays.arraysCompare([1], [])).toStrictEqual(result([1], [], 1));
|
|
75
|
+
expect(arrays.arraysCompare([1, 2], [1])).toStrictEqual(result([2], [], 1));
|
|
76
|
+
expect(arrays.arraysCompare([1], [1])).toStrictEqual(result([], [], 0));
|
|
77
|
+
expect(arrays.arraysCompare([], [1])).toStrictEqual(result([], [1], 1));
|
|
78
|
+
expect(arrays.arraysCompare([1, 2, 3], [3, 2, 1])).toStrictEqual(result([1, 3], [], 2));
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('arraysCompareDistinct', () => {
|
|
82
|
+
expect(arrays.arraysCompareDistinct(null, null)).toBeNull();
|
|
83
|
+
expect(arrays.arraysCompareDistinct([], null)).toBeNull();
|
|
84
|
+
|
|
85
|
+
const result = (missing, extra, diff) => ({ missing, extra, diff });
|
|
86
|
+
|
|
87
|
+
expect(arrays.arraysCompareDistinct([], [])).toStrictEqual(result([], [], 0));
|
|
88
|
+
expect(arrays.arraysCompareDistinct([1], [])).toStrictEqual(result([1], [], 1));
|
|
89
|
+
expect(arrays.arraysCompareDistinct([1, 2], [1])).toStrictEqual(result([2], [], 1));
|
|
90
|
+
expect(arrays.arraysCompareDistinct([1], [1])).toStrictEqual(result([], [], 0));
|
|
91
|
+
expect(arrays.arraysCompareDistinct([], [1])).toStrictEqual(result([], [1], 1));
|
|
92
|
+
expect(arrays.arraysCompareDistinct([1, 2], [2, 1, 1])).toStrictEqual(result([], [], 0));
|
|
93
|
+
expect(arrays.arraysCompareDistinct([1, 2, 3], [3, 2, 1])).toStrictEqual(result([], [], 0));
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('arrayDistinct', () => {
|
|
97
|
+
expect(arrays.arrayDistinct(null)).toStrictEqual([]);
|
|
98
|
+
expect(arrays.arrayDistinct([])).toStrictEqual([]);
|
|
99
|
+
expect(arrays.arrayDistinct([1])).toStrictEqual([1]);
|
|
100
|
+
expect(arrays.arrayDistinct([1, 2, 3])).toStrictEqual([1, 2, 3]);
|
|
101
|
+
expect(arrays.arrayDistinct([1, '2', 3])).toStrictEqual([1, '2', 3]);
|
|
102
|
+
expect(arrays.arrayDistinct([1, 1, 1])).toStrictEqual([1]);
|
|
103
|
+
expect(arrays.arrayDistinct(['1', '1', '1'])).toStrictEqual(['1']);
|
|
104
|
+
});
|
|
105
|
+
|
|
67
106
|
it('normalize', () => {
|
|
68
107
|
expect(arrays.normalize([])).toHaveLength(0);
|
|
69
108
|
|
|
@@ -85,8 +124,12 @@ describe('math/arrays', () => {
|
|
|
85
124
|
});
|
|
86
125
|
|
|
87
126
|
it('shuffle', () => {
|
|
127
|
+
expect(arrays.shuffle(null)).toStrictEqual([]);
|
|
128
|
+
expect(arrays.shuffle(null, true)).toStrictEqual([]);
|
|
129
|
+
|
|
88
130
|
const arr1 = [1, 2, 3], arr2 = arr1.slice();
|
|
89
131
|
arrays.shuffle(arr2);
|
|
132
|
+
arrays.shuffle(arr2, true);
|
|
90
133
|
expect(arr2).toHaveLength(arr1.length);
|
|
91
134
|
arr2.forEach(i => {
|
|
92
135
|
expect(arr1).toContain(i);
|
|
@@ -138,6 +181,16 @@ describe('math/arrays', () => {
|
|
|
138
181
|
expect(arrays.findIndexLeast(2, [3, 2, 1])).toBe(0);
|
|
139
182
|
expect(arrays.findIndexLeast(2, [3, 2, 1], true)).toBe(2);
|
|
140
183
|
expect(arrays.findIndexLeast(2, [1, 2, 3])).toBe(2);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('removeItem', () => {
|
|
187
|
+
const check = (input: any[], remove: any, output: any[]) => {
|
|
188
|
+
arrays.removeItem(input, remove);
|
|
189
|
+
expect(input).toStrictEqual(output);
|
|
190
|
+
};
|
|
141
191
|
|
|
192
|
+
check([1, 2, 3], 1, [2, 3]);
|
|
193
|
+
check([1, 2, 3], item => item === 1, [2, 3]);
|
|
194
|
+
check([1, 2, 3], '1', [1, 2, 3]);
|
|
142
195
|
});
|
|
143
196
|
});
|
package/src/math/arrays.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Comparator, Predicate } from '../types';
|
|
1
2
|
import { random } from './calc';
|
|
2
3
|
|
|
3
4
|
export function arrayCompareG<T>(arr: ReadonlyArray<T>, cond: (current: T, previous: T) => boolean): T {
|
|
@@ -81,6 +82,71 @@ export function arrayFirstResult<T, V>(arr: ReadonlyArray<T>, mapper: (o: T) =>
|
|
|
81
82
|
return false;
|
|
82
83
|
}
|
|
83
84
|
|
|
85
|
+
export function arraysCompare<T>(base: readonly T[], target: readonly T[], comparator?: Comparator<T>) {
|
|
86
|
+
if (!base || !target) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const compare = comparator || Comparator.Default;
|
|
91
|
+
const result = {
|
|
92
|
+
missing: [] as T[],
|
|
93
|
+
extra: [] as T[],
|
|
94
|
+
diff: 0,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
for (let i = 0; i < base.length; ++i) {
|
|
98
|
+
const baseItem = base[i];
|
|
99
|
+
const targetItem = target[i];
|
|
100
|
+
if (compare(baseItem, targetItem)) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
result.missing.push(baseItem);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (let i = base.length; i < target.length; ++i) {
|
|
108
|
+
result.extra.push(target[i]);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
result.diff = result.missing.length + result.extra.length;
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function arraysCompareDistinct<T>(base: readonly T[], target: readonly T[]) {
|
|
116
|
+
if (!base || !target) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const baseSet = new Set(base);
|
|
121
|
+
const targetSet = new Set(target);
|
|
122
|
+
const result = {
|
|
123
|
+
missing: [] as T[],
|
|
124
|
+
extra: [] as T[],
|
|
125
|
+
diff: 0,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
for (const item of baseSet) {
|
|
129
|
+
if (!targetSet.has(item)) {
|
|
130
|
+
result.missing.push(item);
|
|
131
|
+
} else {
|
|
132
|
+
// reduce iterations for 'extra'
|
|
133
|
+
targetSet.delete(item);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
for (const item of targetSet) {
|
|
138
|
+
// all items left in 'target' is missing in 'base'
|
|
139
|
+
result.extra.push(item);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
result.diff = result.missing.length + result.extra.length;
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function arrayDistinct<T>(arr: readonly T[]) {
|
|
147
|
+
return Array.from(new Set(arr || []));
|
|
148
|
+
}
|
|
149
|
+
|
|
84
150
|
export function normalize(arr: number[]): number[] {
|
|
85
151
|
if (arr.length === 0) {
|
|
86
152
|
return arr;
|
|
@@ -172,3 +238,16 @@ export function findIndexLeast(num: number, arr: number[], sort = false) {
|
|
|
172
238
|
|
|
173
239
|
return arr.findIndex(i => i > num);
|
|
174
240
|
}
|
|
241
|
+
|
|
242
|
+
type NonFunction<T> = T extends Function ? never : T;
|
|
243
|
+
|
|
244
|
+
export function removeItem<T>(array: T[], item: NonFunction<T> | Predicate<T>): T {
|
|
245
|
+
const index = typeof item === 'function'
|
|
246
|
+
? array.findIndex(item as Predicate<T>)
|
|
247
|
+
: array.indexOf(item);
|
|
248
|
+
if (index < 0) {
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return array.splice(index, 1)[0];
|
|
253
|
+
}
|
|
@@ -20,7 +20,7 @@ export class TransitionObserver<T> implements IDisposable {
|
|
|
20
20
|
private _promise: Promise<T> = null;
|
|
21
21
|
private _promiseReject: (err?: any) => any = null;
|
|
22
22
|
|
|
23
|
-
private logger: ILogger = createLogger('',
|
|
23
|
+
private logger: ILogger = createLogger('', false);
|
|
24
24
|
|
|
25
25
|
constructor(getter?: () => T) {
|
|
26
26
|
if (getter) {
|
|
@@ -115,7 +115,7 @@ export class TransitionObserver<T> implements IDisposable {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
enableLogging(name: string) {
|
|
118
|
-
this.logger = createLogger(name,
|
|
118
|
+
this.logger = createLogger(name, name ? undefined : false);
|
|
119
119
|
return this;
|
|
120
120
|
}
|
|
121
121
|
|
package/src/types.ts
CHANGED
|
@@ -3,3 +3,24 @@ export { DeepPartial } from './deepPartial';
|
|
|
3
3
|
export type DeepReadonly<T> = {
|
|
4
4
|
readonly [P in keyof T]: DeepReadonly<T[P]>;
|
|
5
5
|
};
|
|
6
|
+
|
|
7
|
+
export type Getter<T> = (() => T) | T | null;
|
|
8
|
+
|
|
9
|
+
export namespace Getter {
|
|
10
|
+
export function getValue<T>(getter: Getter<T>): T {
|
|
11
|
+
if (getter == null) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
if (typeof getter === 'function') {
|
|
15
|
+
return (getter as () => T)();
|
|
16
|
+
}
|
|
17
|
+
return getter;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type Predicate<T> = (value: T) => boolean;
|
|
22
|
+
export type Comparator<T, C = boolean> = (v1: T, v2: T) => C;
|
|
23
|
+
|
|
24
|
+
export namespace Comparator {
|
|
25
|
+
export const Default: Comparator<any> = (a, b) => a === b;
|
|
26
|
+
}
|