@testgorilla/tgo-typing-test 2.0.0 → 2.0.1
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/fesm2022/testgorilla-tgo-typing-test.mjs +4691 -0
- package/fesm2022/testgorilla-tgo-typing-test.mjs.map +1 -0
- package/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.d.ts +14 -0
- package/lib/components/tgo-typing-test/tgo-typing-test.component.d.ts +54 -0
- package/lib/helpers/config.d.ts +98 -0
- package/lib/helpers/constants/default-config.d.ts +3 -0
- package/lib/helpers/controllers/input-controller.d.ts +16 -0
- package/lib/helpers/controllers/quotes-controller.d.ts +20 -0
- package/lib/helpers/observables/config-event.d.ts +5 -0
- package/lib/helpers/observables/timer-event.d.ts +4 -0
- package/lib/helpers/states/active-page.d.ts +2 -0
- package/lib/helpers/states/composition.d.ts +10 -0
- package/lib/helpers/states/page-transition.d.ts +2 -0
- package/lib/helpers/states/slow-timer.d.ts +3 -0
- package/lib/helpers/states/test-active.d.ts +2 -0
- package/lib/helpers/states/time.d.ts +3 -0
- package/lib/helpers/test/caps-warning.d.ts +5 -0
- package/lib/helpers/test/caret.d.ts +11 -0
- package/lib/helpers/test/custom-text.d.ts +16 -0
- package/lib/helpers/test/english-punctuation.d.ts +3 -0
- package/lib/helpers/test/focus.d.ts +7 -0
- package/lib/helpers/test/manual-restart-tracker.d.ts +3 -0
- package/lib/helpers/test/out-of-focus.d.ts +4 -0
- package/lib/helpers/test/replay.d.ts +20 -0
- package/lib/helpers/test/test-input.d.ts +86 -0
- package/lib/helpers/test/test-logic.d.ts +25 -0
- package/lib/helpers/test/test-state.d.ts +7 -0
- package/lib/helpers/test/test-stats.d.ts +92 -0
- package/lib/helpers/test/test-timer.d.ts +6 -0
- package/lib/helpers/test/test-ui.d.ts +27 -0
- package/lib/helpers/test/test-words.d.ts +23 -0
- package/lib/helpers/test/timer-progress.d.ts +3 -0
- package/lib/helpers/test/weak-spot.d.ts +3 -0
- package/lib/helpers/test/wordset.d.ts +7 -0
- package/lib/utils/misc.d.ts +80 -0
- package/package.json +17 -4
- package/.eslintrc.json +0 -46
- package/jest.config.ts +0 -21
- package/ng-package.json +0 -15
- package/project.json +0 -36
- package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.html +0 -30
- package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.spec.ts +0 -250
- package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.ts +0 -47
- package/src/lib/components/tgo-typing-test/tgo-typing-test.component.html +0 -72
- package/src/lib/components/tgo-typing-test/tgo-typing-test.component.spec.ts +0 -699
- package/src/lib/components/tgo-typing-test/tgo-typing-test.component.ts +0 -287
- package/src/lib/helpers/config.ts +0 -28
- package/src/lib/helpers/constants/default-config.ts +0 -103
- package/src/lib/helpers/controllers/input-controller.ts +0 -710
- package/src/lib/helpers/controllers/quotes-controller.ts +0 -183
- package/src/lib/helpers/observables/banner-event.ts +0 -18
- package/src/lib/helpers/observables/config-event.ts +0 -31
- package/src/lib/helpers/observables/timer-event.ts +0 -18
- package/src/lib/helpers/states/active-page.ts +0 -9
- package/src/lib/helpers/states/composition.ts +0 -29
- package/src/lib/helpers/states/page-transition.ts +0 -9
- package/src/lib/helpers/states/slow-timer.ts +0 -16
- package/src/lib/helpers/states/test-active.ts +0 -9
- package/src/lib/helpers/states/time.ts +0 -13
- package/src/lib/helpers/test/caps-warning.ts +0 -50
- package/src/lib/helpers/test/caret.ts +0 -92
- package/src/lib/helpers/test/custom-text.ts +0 -73
- package/src/lib/helpers/test/english-punctuation.ts +0 -38
- package/src/lib/helpers/test/focus.ts +0 -39
- package/src/lib/helpers/test/manual-restart-tracker.ts +0 -13
- package/src/lib/helpers/test/out-of-focus.ts +0 -19
- package/src/lib/helpers/test/replay.ts +0 -265
- package/src/lib/helpers/test/test-input.ts +0 -320
- package/src/lib/helpers/test/test-logic.ts +0 -1039
- package/src/lib/helpers/test/test-state.ts +0 -17
- package/src/lib/helpers/test/test-stats.ts +0 -442
- package/src/lib/helpers/test/test-timer.ts +0 -209
- package/src/lib/helpers/test/test-ui.ts +0 -370
- package/src/lib/helpers/test/test-words.ts +0 -72
- package/src/lib/helpers/test/timer-progress.ts +0 -16
- package/src/lib/helpers/test/tts.ts +0 -42
- package/src/lib/helpers/test/weak-spot.ts +0 -74
- package/src/lib/helpers/test/wordset.ts +0 -109
- package/src/lib/styles/animations.scss +0 -101
- package/src/lib/styles/caret.scss +0 -108
- package/src/lib/styles/core.scss +0 -498
- package/src/lib/styles/index.scss +0 -19
- package/src/lib/styles/inputs.scss +0 -290
- package/src/lib/styles/popups.scss +0 -1311
- package/src/lib/styles/test.scss +0 -1008
- package/src/lib/styles/z_media-queries.scss +0 -848
- package/src/lib/types/types.d.ts +0 -731
- package/src/lib/utils/misc.ts +0 -776
- package/src/test-setup.ts +0 -20
- package/tsconfig.json +0 -16
- package/tsconfig.lib.json +0 -14
- package/tsconfig.lib.prod.json +0 -9
- package/tsconfig.spec.json +0 -11
- /package/{src/assets → assets}/typing-test-languages/english.json +0 -0
- /package/{src/assets → assets}/typing-test-languages/english_punctuation.json +0 -0
- /package/{src/assets → assets}/typing-test-languages/quotes/english_version_1.json +0 -0
- /package/{src/assets → assets}/typing-test-languages/quotes/english_version_2.json +0 -0
- /package/{src/assets → assets}/typing-test-languages/quotes/filtered_sources.json +0 -0
- /package/{src/index.ts → index.d.ts} +0 -0
|
@@ -1,699 +0,0 @@
|
|
|
1
|
-
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
-
import { ElementRef, SimpleChange } from '@angular/core';
|
|
3
|
-
import { BehaviorSubject, Subject } from 'rxjs';
|
|
4
|
-
import { TgoTypingTestComponent } from './tgo-typing-test.component';
|
|
5
|
-
import * as config from '../../helpers/config';
|
|
6
|
-
import * as inputController from '../../helpers/controllers/input-controller';
|
|
7
|
-
import * as capsWarning from '../../helpers/test/caps-warning';
|
|
8
|
-
import * as caret from '../../helpers/test/caret';
|
|
9
|
-
import * as focus from '../../helpers/test/focus';
|
|
10
|
-
import * as outOfFocus from '../../helpers/test/out-of-focus';
|
|
11
|
-
import * as replay from '../../helpers/test/replay';
|
|
12
|
-
import * as TestLogic from '../../helpers/test/test-logic';
|
|
13
|
-
import * as TestUI from '../../helpers/test/test-ui';
|
|
14
|
-
import * as timerProgress from '../../helpers/test/timer-progress';
|
|
15
|
-
import * as misc from '../../utils/misc';
|
|
16
|
-
import * as TestActive from '../../helpers/states/test-active';
|
|
17
|
-
import quoteController from '../../helpers/controllers/quotes-controller';
|
|
18
|
-
import * as testTimer from '../../helpers/test/test-timer';
|
|
19
|
-
|
|
20
|
-
jest.mock('../../helpers/config');
|
|
21
|
-
jest.mock('../../helpers/controllers/input-controller');
|
|
22
|
-
jest.mock('../../helpers/test/caps-warning');
|
|
23
|
-
jest.mock('../../helpers/test/caret');
|
|
24
|
-
jest.mock('../../helpers/test/focus');
|
|
25
|
-
jest.mock('../../helpers/test/out-of-focus');
|
|
26
|
-
jest.mock('../../helpers/test/replay');
|
|
27
|
-
jest.mock('../../helpers/test/test-logic');
|
|
28
|
-
jest.mock('../../helpers/test/test-ui');
|
|
29
|
-
jest.mock('../../helpers/test/timer-progress');
|
|
30
|
-
jest.mock('../../utils/misc');
|
|
31
|
-
jest.mock('../../helpers/states/test-active');
|
|
32
|
-
jest.mock('../../helpers/controllers/quotes-controller');
|
|
33
|
-
jest.mock('../../helpers/test/test-timer');
|
|
34
|
-
|
|
35
|
-
describe('TgoTypingTestComponent', () => {
|
|
36
|
-
let component: TgoTypingTestComponent;
|
|
37
|
-
let fixture: ComponentFixture<TgoTypingTestComponent>;
|
|
38
|
-
|
|
39
|
-
const mockShowCaps$ = new BehaviorSubject<boolean>(false);
|
|
40
|
-
const mockCaretShow$ = new BehaviorSubject<boolean>(true);
|
|
41
|
-
const mockCaretAnimation$ = new BehaviorSubject<string>('smooth');
|
|
42
|
-
const mockStartTestSubject$ = new BehaviorSubject<boolean>(false);
|
|
43
|
-
const mockOutOfFocusShow$ = new BehaviorSubject<boolean>(false);
|
|
44
|
-
const mockTimeLeft$ = new BehaviorSubject<string>('180');
|
|
45
|
-
const mockCaretLeft$ = new BehaviorSubject<number>(0);
|
|
46
|
-
const mockCaretTop$ = new BehaviorSubject<number>(0);
|
|
47
|
-
const mockResultSub$ = new Subject<any>();
|
|
48
|
-
const mockQuoteNetworkError$ = new Subject<string | null>();
|
|
49
|
-
|
|
50
|
-
beforeEach(() => {
|
|
51
|
-
jest.clearAllMocks();
|
|
52
|
-
|
|
53
|
-
// Ensure timer functions are available
|
|
54
|
-
if (!global.clearInterval) {
|
|
55
|
-
(global as any).clearInterval = jest.fn();
|
|
56
|
-
}
|
|
57
|
-
jest.spyOn(global, 'setInterval').mockReturnValue(123 as any);
|
|
58
|
-
jest.spyOn(global, 'clearInterval').mockImplementation(jest.fn());
|
|
59
|
-
|
|
60
|
-
// Mock BehaviorSubjects and Observables
|
|
61
|
-
(capsWarning as any).showCaps = mockShowCaps$;
|
|
62
|
-
(caret as any).caretShow = mockCaretShow$;
|
|
63
|
-
(caret as any).caretAnimation = mockCaretAnimation$;
|
|
64
|
-
(caret as any).caretLeft = mockCaretLeft$;
|
|
65
|
-
(caret as any).caretTop = mockCaretTop$;
|
|
66
|
-
(TestLogic as any).startTestSubject = mockStartTestSubject$;
|
|
67
|
-
(outOfFocus as any).outOfFocusShow = mockOutOfFocusShow$;
|
|
68
|
-
(timerProgress as any).timeLeft = mockTimeLeft$;
|
|
69
|
-
(TestLogic as any).resultSub = mockResultSub$;
|
|
70
|
-
(misc as any).QuoteNetworkError$ = mockQuoteNetworkError$;
|
|
71
|
-
|
|
72
|
-
// Mock functions
|
|
73
|
-
jest.spyOn(TestUI, 'setResultCalculating').mockImplementation();
|
|
74
|
-
jest.spyOn(TestUI, 'setResultVisible').mockImplementation();
|
|
75
|
-
jest.spyOn(config, 'setTime').mockImplementation();
|
|
76
|
-
jest.spyOn(config, 'setPunctuation').mockImplementation();
|
|
77
|
-
jest.spyOn(config, 'setNumbers').mockImplementation();
|
|
78
|
-
jest.spyOn(config, 'setFunbox').mockImplementation();
|
|
79
|
-
jest.spyOn(config, 'setCustomTGQuotes').mockImplementation();
|
|
80
|
-
jest.spyOn(config, 'setTestVersionForSentences').mockImplementation();
|
|
81
|
-
jest.spyOn(replay, 'getReplayExport').mockReturnValue('mock-replay-data');
|
|
82
|
-
jest.spyOn(TestLogic, 'stopTest').mockImplementation();
|
|
83
|
-
jest.spyOn(TestLogic, 'restart').mockImplementation();
|
|
84
|
-
jest.spyOn(TestLogic, 'finish').mockImplementation();
|
|
85
|
-
jest.spyOn(TestLogic, 'setWordsInputElementTestLogic').mockImplementation();
|
|
86
|
-
jest.spyOn(TestActive, 'get').mockReturnValue(true);
|
|
87
|
-
jest.spyOn(quoteController, 'resetQuotes').mockImplementation();
|
|
88
|
-
jest.spyOn(testTimer, 'disableCheckIfTimeIsUp').mockImplementation();
|
|
89
|
-
|
|
90
|
-
// Mock input controller functions
|
|
91
|
-
jest.spyOn(inputController, 'setWordsInputElement').mockImplementation();
|
|
92
|
-
jest.spyOn(inputController, 'wordsInputKeyup').mockImplementation();
|
|
93
|
-
jest.spyOn(inputController, 'wordsInputBeforeinput').mockImplementation();
|
|
94
|
-
jest.spyOn(inputController, 'wordsInputInput').mockImplementation();
|
|
95
|
-
jest.spyOn(inputController, 'wordsInputFocus').mockImplementation();
|
|
96
|
-
jest.spyOn(inputController, 'wordsInputCopy').mockImplementation();
|
|
97
|
-
jest.spyOn(inputController, 'wordsInputPaste').mockImplementation();
|
|
98
|
-
jest.spyOn(inputController, 'wordsInputCompositionstart').mockImplementation();
|
|
99
|
-
jest.spyOn(inputController, 'wordsInputCompositionend').mockImplementation();
|
|
100
|
-
jest.spyOn(inputController, 'inputKeydown').mockImplementation();
|
|
101
|
-
|
|
102
|
-
// Mock caps warning functions
|
|
103
|
-
jest.spyOn(capsWarning, 'capsKeydown').mockImplementation();
|
|
104
|
-
jest.spyOn(capsWarning, 'capsKeyup').mockImplementation();
|
|
105
|
-
|
|
106
|
-
// Mock focus functions
|
|
107
|
-
jest.spyOn(focus, 'mousemove').mockImplementation();
|
|
108
|
-
jest.spyOn(focus, 'setMiddleElement').mockImplementation();
|
|
109
|
-
jest.spyOn(focus, 'setCapsWarningElement').mockImplementation();
|
|
110
|
-
|
|
111
|
-
// Mock TestUI functions
|
|
112
|
-
jest.spyOn(TestUI, 'setWordsInputElementTestUI').mockImplementation();
|
|
113
|
-
jest.spyOn(TestUI, 'setWordsWrapperElement').mockImplementation();
|
|
114
|
-
jest.spyOn(TestUI, 'setWordsElement').mockImplementation();
|
|
115
|
-
jest.spyOn(TestUI, 'wordsInputFocusOut').mockImplementation();
|
|
116
|
-
jest.spyOn(TestUI, 'wordsInputFocusTestUI').mockImplementation();
|
|
117
|
-
jest.spyOn(TestUI, 'wordsWrapperClick').mockImplementation();
|
|
118
|
-
|
|
119
|
-
TestBed.configureTestingModule({
|
|
120
|
-
imports: [TgoTypingTestComponent],
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
fixture = TestBed.createComponent(TgoTypingTestComponent);
|
|
124
|
-
component = fixture.componentInstance;
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
afterEach(() => {
|
|
128
|
-
jest.clearAllTimers();
|
|
129
|
-
jest.useRealTimers();
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
describe('when initialized', () => {
|
|
133
|
-
it('should create the component', () => {
|
|
134
|
-
expect(component).toBeDefined();
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it('should initialize with default input values', () => {
|
|
138
|
-
expect(component.time).toBe(180);
|
|
139
|
-
expect(component.punctuation).toBe(false);
|
|
140
|
-
expect(component.numbers).toBe(false);
|
|
141
|
-
expect(component.funbox).toBe('none');
|
|
142
|
-
expect(component.customTGQuotes).toBe(false);
|
|
143
|
-
expect(component.showMiniTimerAndLiveWpm).toBe(true);
|
|
144
|
-
expect(component.restartTest).toBe(false);
|
|
145
|
-
expect(component.testVersion).toBe(1);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it('should initialize BehaviorSubjects in constructor', () => {
|
|
149
|
-
expect(component.showCaps$).toBe(mockShowCaps$);
|
|
150
|
-
expect(component.showCaret$).toBe(mockCaretShow$);
|
|
151
|
-
expect(component.caretAnimation$).toBe(mockCaretAnimation$);
|
|
152
|
-
expect(component.showTimer$).toBe(mockStartTestSubject$);
|
|
153
|
-
expect(component.outOfFocusShow$).toBe(mockOutOfFocusShow$);
|
|
154
|
-
expect(component.timeLeft$).toBe(mockTimeLeft$);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it('should initialize caret position to zero', () => {
|
|
158
|
-
expect(component.caretLeft).toBe(0);
|
|
159
|
-
expect(component.caretTop).toBe(0);
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it('should initialize state to true', () => {
|
|
163
|
-
expect(component.state).toBe('true');
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
describe('#ngOnInit', () => {
|
|
168
|
-
beforeEach(() => {
|
|
169
|
-
jest.useFakeTimers();
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
afterEach(() => {
|
|
173
|
-
jest.useRealTimers();
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it('should set result calculating to false', () => {
|
|
177
|
-
component.ngOnInit();
|
|
178
|
-
|
|
179
|
-
expect(TestUI.setResultCalculating).toHaveBeenCalledWith(false);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it('should set result visible to false', () => {
|
|
183
|
-
component.ngOnInit();
|
|
184
|
-
|
|
185
|
-
expect(TestUI.setResultVisible).toHaveBeenCalledWith(false);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('should reset caret positions', () => {
|
|
189
|
-
component.caretLeft = 50;
|
|
190
|
-
component.caretTop = 100;
|
|
191
|
-
|
|
192
|
-
component.ngOnInit();
|
|
193
|
-
|
|
194
|
-
expect(component.caretLeft).toBe(0);
|
|
195
|
-
expect(component.caretTop).toBe(0);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it('should configure test settings with input values', () => {
|
|
199
|
-
component.time = 120;
|
|
200
|
-
component.punctuation = true;
|
|
201
|
-
component.numbers = true;
|
|
202
|
-
component.funbox = 'custom-funbox';
|
|
203
|
-
component.customTGQuotes = true;
|
|
204
|
-
component.testVersion = 2;
|
|
205
|
-
|
|
206
|
-
component.ngOnInit();
|
|
207
|
-
|
|
208
|
-
expect(config.setTime).toHaveBeenCalledWith(120);
|
|
209
|
-
expect(config.setPunctuation).toHaveBeenCalledWith(true);
|
|
210
|
-
expect(config.setNumbers).toHaveBeenCalledWith(true);
|
|
211
|
-
expect(config.setFunbox).toHaveBeenCalledWith('custom-funbox');
|
|
212
|
-
expect(config.setCustomTGQuotes).toHaveBeenCalledWith(true);
|
|
213
|
-
expect(config.setTestVersionForSentences).toHaveBeenCalledWith(2);
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
it('should subscribe to caretLeft changes and update component state', () => {
|
|
217
|
-
component.ngOnInit();
|
|
218
|
-
|
|
219
|
-
expect(component.state).toBe('true');
|
|
220
|
-
|
|
221
|
-
mockCaretLeft$.next(50);
|
|
222
|
-
|
|
223
|
-
expect(component.caretLeft).toBe(50);
|
|
224
|
-
expect(component.state).toBe('false');
|
|
225
|
-
|
|
226
|
-
mockCaretLeft$.next(100);
|
|
227
|
-
|
|
228
|
-
expect(component.caretLeft).toBe(100);
|
|
229
|
-
expect(component.state).toBe('true');
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it('should NOT change state when caretLeft value is the same', () => {
|
|
233
|
-
component.caretLeft = 0;
|
|
234
|
-
component.state = 'false';
|
|
235
|
-
component.ngOnInit();
|
|
236
|
-
|
|
237
|
-
mockCaretLeft$.next(0);
|
|
238
|
-
|
|
239
|
-
expect(component.state).toBe('false');
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
it('should subscribe to caretTop changes', () => {
|
|
243
|
-
component.ngOnInit();
|
|
244
|
-
|
|
245
|
-
mockCaretTop$.next(75);
|
|
246
|
-
|
|
247
|
-
expect(component.caretTop).toBe(75);
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
it('should emit replay export and result when test result is published', () => {
|
|
251
|
-
const resultSpy = jest.spyOn(component.resultEvent, 'emit');
|
|
252
|
-
const replaySpy = jest.spyOn(component.replayExport, 'emit');
|
|
253
|
-
const mockResult = { wpm: 80, accuracy: 95 };
|
|
254
|
-
|
|
255
|
-
component.ngOnInit();
|
|
256
|
-
|
|
257
|
-
mockResultSub$.next(mockResult);
|
|
258
|
-
|
|
259
|
-
expect(replay.getReplayExport).toHaveBeenCalled();
|
|
260
|
-
expect(replaySpy).toHaveBeenCalledWith('mock-replay-data');
|
|
261
|
-
expect(resultSpy).toHaveBeenCalledWith(mockResult);
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
it('should handle quote network errors', () => {
|
|
265
|
-
const errorSpy = jest.spyOn(component.errorEvent, 'emit');
|
|
266
|
-
|
|
267
|
-
component.ngOnInit();
|
|
268
|
-
|
|
269
|
-
mockQuoteNetworkError$.next('Network error occurred');
|
|
270
|
-
|
|
271
|
-
expect(errorSpy).toHaveBeenCalledWith('Network error occurred');
|
|
272
|
-
expect(TestLogic.stopTest).toHaveBeenCalled();
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
it('should NOT emit error when QuoteNetworkError is null', () => {
|
|
276
|
-
const errorSpy = jest.spyOn(component.errorEvent, 'emit');
|
|
277
|
-
|
|
278
|
-
component.ngOnInit();
|
|
279
|
-
|
|
280
|
-
mockQuoteNetworkError$.next(null);
|
|
281
|
-
|
|
282
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
283
|
-
expect(TestLogic.stopTest).not.toHaveBeenCalled();
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
it('should set up interval to emit replay export every 20 seconds', () => {
|
|
287
|
-
const replaySpy = jest.spyOn(component.replayExport, 'emit');
|
|
288
|
-
|
|
289
|
-
component.ngOnInit();
|
|
290
|
-
|
|
291
|
-
expect(replaySpy).not.toHaveBeenCalled();
|
|
292
|
-
|
|
293
|
-
jest.advanceTimersByTime(20000);
|
|
294
|
-
expect(replaySpy).toHaveBeenCalledTimes(1);
|
|
295
|
-
|
|
296
|
-
jest.advanceTimersByTime(20000);
|
|
297
|
-
expect(replaySpy).toHaveBeenCalledTimes(2);
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
it('should store subscriptions for cleanup', () => {
|
|
301
|
-
component.ngOnInit();
|
|
302
|
-
|
|
303
|
-
expect(component.subscriptions.length).toBeGreaterThan(0);
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
describe('when testExpiration$ is provided', () => {
|
|
307
|
-
it('should disable time check and subscribe to test expiration', () => {
|
|
308
|
-
const testExpiration$ = new Subject<void>();
|
|
309
|
-
component.testExpiration$ = testExpiration$;
|
|
310
|
-
|
|
311
|
-
component.ngOnInit();
|
|
312
|
-
|
|
313
|
-
expect(testTimer.disableCheckIfTimeIsUp).toHaveBeenCalled();
|
|
314
|
-
|
|
315
|
-
testExpiration$.next();
|
|
316
|
-
|
|
317
|
-
expect(TestLogic.finish).toHaveBeenCalled();
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
it('should add testExpiration subscription to subscriptions array', () => {
|
|
321
|
-
const testExpiration$ = new Subject<void>();
|
|
322
|
-
component.testExpiration$ = testExpiration$;
|
|
323
|
-
|
|
324
|
-
const initialLength = component.subscriptions.length;
|
|
325
|
-
component.ngOnInit();
|
|
326
|
-
|
|
327
|
-
expect(component.subscriptions.length).toBeGreaterThan(initialLength);
|
|
328
|
-
});
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
describe('when testExpiration$ is NOT provided', () => {
|
|
332
|
-
it('should NOT disable time check', () => {
|
|
333
|
-
component.testExpiration$ = undefined;
|
|
334
|
-
|
|
335
|
-
component.ngOnInit();
|
|
336
|
-
|
|
337
|
-
expect(testTimer.disableCheckIfTimeIsUp).not.toHaveBeenCalled();
|
|
338
|
-
});
|
|
339
|
-
});
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
describe('#ngOnChanges', () => {
|
|
343
|
-
it('should restart test when restartTest changes and is NOT first change', () => {
|
|
344
|
-
const restartSpy = jest.spyOn(component, 'restart');
|
|
345
|
-
|
|
346
|
-
component.ngOnChanges({
|
|
347
|
-
restartTest: new SimpleChange(false, true, false),
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
expect(restartSpy).toHaveBeenCalled();
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
it('should NOT restart test when restartTest is first change', () => {
|
|
354
|
-
const restartSpy = jest.spyOn(component, 'restart');
|
|
355
|
-
|
|
356
|
-
component.ngOnChanges({
|
|
357
|
-
restartTest: new SimpleChange(undefined, true, true),
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
expect(restartSpy).not.toHaveBeenCalled();
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
it('should NOT restart test when other properties change', () => {
|
|
364
|
-
const restartSpy = jest.spyOn(component, 'restart');
|
|
365
|
-
|
|
366
|
-
component.ngOnChanges({
|
|
367
|
-
time: new SimpleChange(180, 120, false),
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
expect(restartSpy).not.toHaveBeenCalled();
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
it('should handle empty changes object', () => {
|
|
374
|
-
const restartSpy = jest.spyOn(component, 'restart');
|
|
375
|
-
|
|
376
|
-
component.ngOnChanges({});
|
|
377
|
-
|
|
378
|
-
expect(restartSpy).not.toHaveBeenCalled();
|
|
379
|
-
});
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
describe('#wordsInputKeyup', () => {
|
|
383
|
-
it('should delegate to imported wordsInputKeyup function', () => {
|
|
384
|
-
const mockEvent = new KeyboardEvent('keyup', { key: 'a' });
|
|
385
|
-
|
|
386
|
-
component.wordsInputKeyup(mockEvent);
|
|
387
|
-
|
|
388
|
-
expect(inputController.wordsInputKeyup).toHaveBeenCalledWith(mockEvent);
|
|
389
|
-
});
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
describe('#wordsInputBeforeinput', () => {
|
|
393
|
-
it('should delegate to imported wordsInputBeforeinput function', () => {
|
|
394
|
-
const mockEvent = { data: 'test' };
|
|
395
|
-
|
|
396
|
-
component.wordsInputBeforeinput(mockEvent);
|
|
397
|
-
|
|
398
|
-
expect(inputController.wordsInputBeforeinput).toHaveBeenCalledWith(mockEvent);
|
|
399
|
-
});
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
describe('#wordsInputInput', () => {
|
|
403
|
-
it('should delegate to imported wordsInputInput function', () => {
|
|
404
|
-
const mockEvent = { inputType: 'insertText' };
|
|
405
|
-
|
|
406
|
-
component.wordsInputInput(mockEvent);
|
|
407
|
-
|
|
408
|
-
expect(inputController.wordsInputInput).toHaveBeenCalledWith(mockEvent);
|
|
409
|
-
});
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
describe('#wordsInputFocus', () => {
|
|
413
|
-
it('should call focus functions when test is active', () => {
|
|
414
|
-
const mockEvent = new FocusEvent('focus');
|
|
415
|
-
jest.spyOn(TestActive, 'get').mockReturnValue(true);
|
|
416
|
-
|
|
417
|
-
component.wordsInputFocus(mockEvent);
|
|
418
|
-
|
|
419
|
-
expect(inputController.wordsInputFocus).toHaveBeenCalledWith(mockEvent);
|
|
420
|
-
expect(TestUI.wordsInputFocusTestUI).toHaveBeenCalled();
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
it('should NOT call focus functions when test is NOT active', () => {
|
|
424
|
-
const mockEvent = new FocusEvent('focus');
|
|
425
|
-
jest.spyOn(TestActive, 'get').mockReturnValue(false);
|
|
426
|
-
|
|
427
|
-
component.wordsInputFocus(mockEvent);
|
|
428
|
-
|
|
429
|
-
expect(inputController.wordsInputFocus).not.toHaveBeenCalled();
|
|
430
|
-
expect(TestUI.wordsInputFocusTestUI).not.toHaveBeenCalled();
|
|
431
|
-
});
|
|
432
|
-
});
|
|
433
|
-
|
|
434
|
-
describe('#wordsInputFocusOut', () => {
|
|
435
|
-
it('should call wordsInputFocusOut when test is active', () => {
|
|
436
|
-
jest.spyOn(TestActive, 'get').mockReturnValue(true);
|
|
437
|
-
|
|
438
|
-
component.wordsInputFocusOut();
|
|
439
|
-
|
|
440
|
-
expect(TestUI.wordsInputFocusOut).toHaveBeenCalled();
|
|
441
|
-
});
|
|
442
|
-
|
|
443
|
-
it('should NOT call wordsInputFocusOut when test is NOT active', () => {
|
|
444
|
-
jest.spyOn(TestActive, 'get').mockReturnValue(false);
|
|
445
|
-
|
|
446
|
-
component.wordsInputFocusOut();
|
|
447
|
-
|
|
448
|
-
expect(TestUI.wordsInputFocusOut).not.toHaveBeenCalled();
|
|
449
|
-
});
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
describe('#wordsInputCopy', () => {
|
|
453
|
-
it('should delegate to imported wordsInputCopy function', () => {
|
|
454
|
-
const mockEvent = { type: 'copy' } as any;
|
|
455
|
-
|
|
456
|
-
component.wordsInputCopy(mockEvent);
|
|
457
|
-
|
|
458
|
-
expect(inputController.wordsInputCopy).toHaveBeenCalledWith(mockEvent);
|
|
459
|
-
});
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
describe('#wordsInputPaste', () => {
|
|
463
|
-
it('should delegate to imported wordsInputPaste function', () => {
|
|
464
|
-
const mockEvent = { type: 'paste' } as any;
|
|
465
|
-
|
|
466
|
-
component.wordsInputPaste(mockEvent);
|
|
467
|
-
|
|
468
|
-
expect(inputController.wordsInputPaste).toHaveBeenCalledWith(mockEvent);
|
|
469
|
-
});
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
describe('#wordsInputCompositionstart', () => {
|
|
473
|
-
it('should delegate to imported wordsInputCompositionstart function', () => {
|
|
474
|
-
component.wordsInputCompositionstart();
|
|
475
|
-
|
|
476
|
-
expect(inputController.wordsInputCompositionstart).toHaveBeenCalled();
|
|
477
|
-
});
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
describe('#wordsInputCompositionend', () => {
|
|
481
|
-
it('should delegate to imported wordsInputCompositionend function', () => {
|
|
482
|
-
component.wordsInputCompositionend();
|
|
483
|
-
|
|
484
|
-
expect(inputController.wordsInputCompositionend).toHaveBeenCalled();
|
|
485
|
-
});
|
|
486
|
-
});
|
|
487
|
-
|
|
488
|
-
describe('#wordsWrapperClick', () => {
|
|
489
|
-
it('should delegate to imported wordsWrapperClick function', () => {
|
|
490
|
-
component.wordsWrapperClick();
|
|
491
|
-
|
|
492
|
-
expect(TestUI.wordsWrapperClick).toHaveBeenCalled();
|
|
493
|
-
});
|
|
494
|
-
});
|
|
495
|
-
|
|
496
|
-
describe('#ngAfterViewInit', () => {
|
|
497
|
-
let mockWordsInputElement: HTMLElement;
|
|
498
|
-
let mockWordsWrapperElement: HTMLElement;
|
|
499
|
-
let mockWordsElement: HTMLElement;
|
|
500
|
-
let mockMiddleElement: HTMLElement;
|
|
501
|
-
let mockCapsWarningElement: HTMLElement;
|
|
502
|
-
|
|
503
|
-
beforeEach(() => {
|
|
504
|
-
mockWordsInputElement = document.createElement('input');
|
|
505
|
-
mockWordsWrapperElement = document.createElement('div');
|
|
506
|
-
mockWordsElement = document.createElement('div');
|
|
507
|
-
mockMiddleElement = document.createElement('div');
|
|
508
|
-
mockCapsWarningElement = document.createElement('div');
|
|
509
|
-
|
|
510
|
-
component.wordsInput = { nativeElement: mockWordsInputElement } as ElementRef;
|
|
511
|
-
component.wordsWrapper = { nativeElement: mockWordsWrapperElement } as ElementRef;
|
|
512
|
-
component.words = { nativeElement: mockWordsElement } as ElementRef;
|
|
513
|
-
component.middle = { nativeElement: mockMiddleElement } as ElementRef;
|
|
514
|
-
component.capsWarning = { nativeElement: mockCapsWarningElement } as ElementRef;
|
|
515
|
-
});
|
|
516
|
-
|
|
517
|
-
it('should set wordsInput element in input controller', () => {
|
|
518
|
-
component.ngAfterViewInit();
|
|
519
|
-
|
|
520
|
-
expect(inputController.setWordsInputElement).toHaveBeenCalledWith(mockWordsInputElement);
|
|
521
|
-
});
|
|
522
|
-
|
|
523
|
-
it('should set wordsInput element in TestUI', () => {
|
|
524
|
-
component.ngAfterViewInit();
|
|
525
|
-
|
|
526
|
-
expect(TestUI.setWordsInputElementTestUI).toHaveBeenCalledWith(mockWordsInputElement);
|
|
527
|
-
});
|
|
528
|
-
|
|
529
|
-
it('should set wordsInput element in TestLogic', () => {
|
|
530
|
-
component.ngAfterViewInit();
|
|
531
|
-
|
|
532
|
-
expect(TestLogic.setWordsInputElementTestLogic).toHaveBeenCalledWith(mockWordsInputElement);
|
|
533
|
-
});
|
|
534
|
-
|
|
535
|
-
it('should set wordsWrapper element', () => {
|
|
536
|
-
component.ngAfterViewInit();
|
|
537
|
-
|
|
538
|
-
expect(TestUI.setWordsWrapperElement).toHaveBeenCalledWith(mockWordsWrapperElement);
|
|
539
|
-
});
|
|
540
|
-
|
|
541
|
-
it('should set words element', () => {
|
|
542
|
-
component.ngAfterViewInit();
|
|
543
|
-
|
|
544
|
-
expect(TestUI.setWordsElement).toHaveBeenCalledWith(mockWordsElement);
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
it('should set middle element', () => {
|
|
548
|
-
component.ngAfterViewInit();
|
|
549
|
-
|
|
550
|
-
expect(focus.setMiddleElement).toHaveBeenCalledWith(mockMiddleElement);
|
|
551
|
-
});
|
|
552
|
-
|
|
553
|
-
it('should set caps warning element', () => {
|
|
554
|
-
component.ngAfterViewInit();
|
|
555
|
-
|
|
556
|
-
expect(focus.setCapsWarningElement).toHaveBeenCalledWith(mockCapsWarningElement);
|
|
557
|
-
});
|
|
558
|
-
|
|
559
|
-
it('should call TestLogic.restart', () => {
|
|
560
|
-
component.ngAfterViewInit();
|
|
561
|
-
|
|
562
|
-
expect(TestLogic.restart).toHaveBeenCalled();
|
|
563
|
-
});
|
|
564
|
-
});
|
|
565
|
-
|
|
566
|
-
describe('#restart', () => {
|
|
567
|
-
it('should set result calculating to false', () => {
|
|
568
|
-
component.restart();
|
|
569
|
-
|
|
570
|
-
expect(TestUI.setResultCalculating).toHaveBeenCalledWith(false);
|
|
571
|
-
});
|
|
572
|
-
|
|
573
|
-
it('should set result visible to false', () => {
|
|
574
|
-
component.restart();
|
|
575
|
-
|
|
576
|
-
expect(TestUI.setResultVisible).toHaveBeenCalledWith(false);
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
it('should reset caret positions to zero', () => {
|
|
580
|
-
component.caretLeft = 100;
|
|
581
|
-
component.caretTop = 50;
|
|
582
|
-
|
|
583
|
-
component.restart();
|
|
584
|
-
|
|
585
|
-
expect(component.caretLeft).toBe(0);
|
|
586
|
-
expect(component.caretTop).toBe(0);
|
|
587
|
-
});
|
|
588
|
-
|
|
589
|
-
it('should call TestLogic.restart', () => {
|
|
590
|
-
component.restart();
|
|
591
|
-
|
|
592
|
-
expect(TestLogic.restart).toHaveBeenCalled();
|
|
593
|
-
});
|
|
594
|
-
});
|
|
595
|
-
|
|
596
|
-
describe('#handleKeyboardDown', () => {
|
|
597
|
-
let mockEvent: KeyboardEvent;
|
|
598
|
-
let mockWordsInputElement: HTMLElement;
|
|
599
|
-
|
|
600
|
-
beforeEach(() => {
|
|
601
|
-
mockEvent = new KeyboardEvent('keydown', { key: 'a' });
|
|
602
|
-
mockWordsInputElement = document.createElement('input');
|
|
603
|
-
component.wordsInput = { nativeElement: mockWordsInputElement } as ElementRef;
|
|
604
|
-
});
|
|
605
|
-
|
|
606
|
-
it('should call capsKeydown with the event', () => {
|
|
607
|
-
component.handleKeyboardDown(mockEvent);
|
|
608
|
-
|
|
609
|
-
expect(capsWarning.capsKeydown).toHaveBeenCalledWith(mockEvent);
|
|
610
|
-
});
|
|
611
|
-
|
|
612
|
-
it('should call inputKeydown with event and true when wordsInput is focused', () => {
|
|
613
|
-
jest.spyOn(document, 'activeElement', 'get').mockReturnValue(mockWordsInputElement);
|
|
614
|
-
|
|
615
|
-
component.handleKeyboardDown(mockEvent);
|
|
616
|
-
|
|
617
|
-
expect(inputController.inputKeydown).toHaveBeenCalledWith(mockEvent, true);
|
|
618
|
-
});
|
|
619
|
-
|
|
620
|
-
it('should call inputKeydown with event and false when wordsInput is NOT focused', () => {
|
|
621
|
-
const otherElement = document.createElement('div');
|
|
622
|
-
jest.spyOn(document, 'activeElement', 'get').mockReturnValue(otherElement);
|
|
623
|
-
|
|
624
|
-
component.handleKeyboardDown(mockEvent);
|
|
625
|
-
|
|
626
|
-
expect(inputController.inputKeydown).toHaveBeenCalledWith(mockEvent, false);
|
|
627
|
-
});
|
|
628
|
-
});
|
|
629
|
-
|
|
630
|
-
describe('#handleKeyboardUp', () => {
|
|
631
|
-
it('should call capsKeyup with the event', () => {
|
|
632
|
-
const mockEvent = new KeyboardEvent('keyup', { key: 'Shift' });
|
|
633
|
-
|
|
634
|
-
component.handleKeyboardUp(mockEvent);
|
|
635
|
-
|
|
636
|
-
expect(capsWarning.capsKeyup).toHaveBeenCalledWith(mockEvent);
|
|
637
|
-
});
|
|
638
|
-
});
|
|
639
|
-
|
|
640
|
-
describe('#handleMouseMove', () => {
|
|
641
|
-
it('should call mousemove with the event', () => {
|
|
642
|
-
const mockEvent = new MouseEvent('mousemove', { clientX: 100, clientY: 200 });
|
|
643
|
-
|
|
644
|
-
component.handleMouseMove(mockEvent);
|
|
645
|
-
|
|
646
|
-
expect(focus.mousemove).toHaveBeenCalledWith(mockEvent);
|
|
647
|
-
});
|
|
648
|
-
});
|
|
649
|
-
|
|
650
|
-
describe('#ngOnDestroy', () => {
|
|
651
|
-
it('should call TestLogic.stopTest', () => {
|
|
652
|
-
component.ngOnDestroy();
|
|
653
|
-
|
|
654
|
-
expect(TestLogic.stopTest).toHaveBeenCalled();
|
|
655
|
-
});
|
|
656
|
-
|
|
657
|
-
it('should reset quotes', () => {
|
|
658
|
-
component.ngOnDestroy();
|
|
659
|
-
|
|
660
|
-
expect(quoteController.resetQuotes).toHaveBeenCalled();
|
|
661
|
-
});
|
|
662
|
-
|
|
663
|
-
it('should clear the replay interval', () => {
|
|
664
|
-
const clearIntervalSpy = jest.spyOn(global, 'clearInterval');
|
|
665
|
-
component.replayIntervalID = 123;
|
|
666
|
-
|
|
667
|
-
component.ngOnDestroy();
|
|
668
|
-
|
|
669
|
-
expect(clearIntervalSpy).toHaveBeenCalledWith(123);
|
|
670
|
-
});
|
|
671
|
-
|
|
672
|
-
it('should unsubscribe from all subscriptions', () => {
|
|
673
|
-
const unsubscribeSpy = jest.fn();
|
|
674
|
-
component.subscriptions = [
|
|
675
|
-
{ unsubscribe: unsubscribeSpy } as any,
|
|
676
|
-
{ unsubscribe: unsubscribeSpy } as any,
|
|
677
|
-
{ unsubscribe: unsubscribeSpy } as any,
|
|
678
|
-
];
|
|
679
|
-
|
|
680
|
-
component.ngOnDestroy();
|
|
681
|
-
|
|
682
|
-
expect(unsubscribeSpy).toHaveBeenCalledTimes(3);
|
|
683
|
-
});
|
|
684
|
-
});
|
|
685
|
-
|
|
686
|
-
describe('Output emitters', () => {
|
|
687
|
-
it('should have resultEvent output', () => {
|
|
688
|
-
expect(component.resultEvent).toBeDefined();
|
|
689
|
-
});
|
|
690
|
-
|
|
691
|
-
it('should have replayExport output', () => {
|
|
692
|
-
expect(component.replayExport).toBeDefined();
|
|
693
|
-
});
|
|
694
|
-
|
|
695
|
-
it('should have errorEvent output', () => {
|
|
696
|
-
expect(component.errorEvent).toBeDefined();
|
|
697
|
-
});
|
|
698
|
-
});
|
|
699
|
-
});
|