Skip to content

Commit 7aa25b5

Browse files
authored
Merge pull request #38 from pradeepkaswan/test/add-swap-source-tests
test: add unit tests for Swap source (closes #33)
2 parents adc7bd5 + e6830e5 commit 7aa25b5

File tree

2 files changed

+122
-72
lines changed

2 files changed

+122
-72
lines changed

src/sources/swap-source.test.ts

Lines changed: 113 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,28 @@ import { Swap, swap } from './swap-source';
66

77
describe('Swap Event Adapter', () => {
88

9-
it('Swaps a value in an element with a static string', () => {
10-
const oldValue = 'old data';
11-
const newValue = 'new data';
9+
it('Swaps a value from an element with a static string', () => {
10+
const oldValue = 'old data';
11+
const newValue = 'new data';
1212

13-
const el = MockElement({
13+
const el = MockElement({
1414
tagName: 'INPUT',
15-
type: 'text',
16-
value: oldValue,
17-
});
15+
type: 'text',
16+
value: oldValue,
17+
});
1818

19-
const eventData = MockEvent('input', {
20-
target: el as HTMLInputElement
21-
});
19+
const eventData = MockEvent('input', {
20+
target: el as HTMLInputElement
21+
});
2222

23-
const handlerSpy = jest.fn();
24-
const source = Swap(newValue)(handlerSpy);
25-
source.next(eventData);
23+
const handlerSpy = jest.fn();
24+
const source = Swap(newValue, handlerSpy);
2625

27-
expect(handlerSpy).toHaveBeenCalledWith(oldValue);
28-
expect(el.value).toEqual(newValue);
29-
});
26+
source.next(eventData);
27+
28+
expect(handlerSpy).toHaveBeenCalledWith(oldValue);
29+
expect(el.value).toEqual(newValue);
30+
})
3031

3132
it('Swaps a value in an element using a function', () => {
3233
const oldValue = 'old data';
@@ -44,7 +45,8 @@ describe('Swap Event Adapter', () => {
4445
const replaceFn = (v: string) => v.toUpperCase();
4546

4647
const handlerSpy = jest.fn();
47-
const source = Swap(replaceFn)(handlerSpy);
48+
const source = Swap(undefined, handlerSpy);
49+
4850
source.next(eventData);
4951

5052
expect(handlerSpy).toHaveBeenCalledWith(oldValue);
@@ -76,51 +78,98 @@ describe('Swap Event Adapter', () => {
7678

7779
describe('swap Event Operator', () => {
7880

79-
it('Swaps and emits a value from an element with static string', () => {
80-
const oldValue = 'old data';
81-
const newValue = 'new data';
82-
83-
const el = MockElement({
84-
tagName: 'INPUT',
85-
type: 'text',
86-
value: oldValue,
87-
});
88-
89-
const eventData = MockEvent('input', {
90-
target: el as HTMLInputElement
91-
});
92-
93-
const handlerSpy = jest.fn();
94-
const pipeline = new Subject<typeof eventData>().pipe(swap(newValue)) as Observable<string> & Subject<typeof eventData>;
95-
pipeline.subscribe(x => handlerSpy(x));
96-
pipeline.next(eventData);
97-
98-
expect(handlerSpy).toHaveBeenCalledWith(oldValue);
99-
expect(el.value).toEqual(newValue);
100-
});
101-
102-
it('Swaps and emits a value from an element using function', () => {
103-
const oldValue = 'old data';
104-
105-
const el = MockElement({
106-
tagName: 'INPUT',
107-
type: 'text',
108-
value: oldValue,
109-
});
110-
111-
const eventData = MockEvent('input', {
112-
target: el as HTMLInputElement
113-
});
114-
115-
const replaceFn = (v: string) => v.toUpperCase();
116-
117-
const handlerSpy = jest.fn();
118-
const pipeline = new Subject<typeof eventData>().pipe(swap(replaceFn)) as Observable<string> & Subject<typeof eventData>;
119-
pipeline.subscribe(x => handlerSpy(x));
120-
pipeline.next(eventData);
121-
122-
expect(handlerSpy).toHaveBeenCalledWith(oldValue);
123-
expect(el.value).toEqual('OLD DATA');
124-
});
81+
it('Swaps and emits a value from an element with a static string', () => {
82+
const oldValue = 'old data';
83+
const newValue = 'new data';
84+
85+
const el = MockElement({
86+
tagName: 'INPUT',
87+
type: 'text',
88+
value: oldValue,
89+
});
90+
91+
const eventData = MockEvent('input', {
92+
target: el as HTMLInputElement
93+
});
94+
95+
const handlerSpy = jest.fn();
96+
const pipeline = new Subject<typeof eventData>().pipe(swap(newValue)) as Observable<string> & Subject<typeof eventData>;
97+
98+
pipeline.subscribe(x => handlerSpy(x));
99+
pipeline.next(eventData);
100+
101+
expect(handlerSpy).toHaveBeenCalledWith(oldValue);
102+
expect(el.value).toEqual(newValue);
103+
});
104+
105+
it('Swaps and emits a value from an element with empty string', () => {
106+
const oldValue = 'old data';
107+
108+
const el = MockElement({
109+
tagName: 'INPUT',
110+
type: 'text',
111+
value: oldValue,
112+
});
113+
114+
const eventData = MockEvent('input', {
115+
target: el as HTMLInputElement
116+
});
117+
const handlerSpy = jest.fn();
118+
const pipeline = new Subject<typeof eventData>().pipe(swap('')) as Observable<string> & Subject<typeof eventData>;
119+
120+
pipeline.subscribe(x => handlerSpy(x));
121+
pipeline.next(eventData);
122+
123+
expect(handlerSpy).toHaveBeenCalledWith(oldValue);
124+
expect(el.value).toEqual('');
125+
});
126+
127+
128+
129+
it('Swaps a value using a function that generates new value from old', () => {
130+
const oldValue = 'test';
131+
const replacementFn = (v: string) => `${v}_modified`;
132+
const el = MockElement({
133+
tagName: 'INPUT',
134+
type: 'text',
135+
value: oldValue,
136+
});
137+
const eventData = MockEvent('input', {
138+
target: el as HTMLInputElement
139+
});
140+
const handlerSpy = jest.fn();
141+
const pipeline = new Subject<typeof eventData>().pipe(swap(replacementFn)) as Observable<string> & Subject<typeof eventData>;
142+
143+
pipeline.subscribe(x => handlerSpy(x));
144+
pipeline.next(eventData);
145+
146+
expect(handlerSpy).toHaveBeenCalledWith(oldValue);
147+
expect(el.value).toEqual('test_modified');
148+
});
149+
150+
it('Handles multiple swap operations in sequence', () => {
151+
const values = ['first', 'second', 'third'];
152+
const el = MockElement({
153+
tagName: 'INPUT',
154+
type: 'text',
155+
value: values[0],
156+
});
157+
const handlerSpy = jest.fn();
158+
const pipeline = new Subject<Event>().pipe(swap('replacement')) as Observable<string> & Subject<Event>;
159+
160+
pipeline.subscribe(x => handlerSpy(x));
161+
162+
values.forEach(val => {
163+
el.value = val;
164+
const eventData = MockEvent('input', { target: el as HTMLInputElement });
165+
pipeline.next(eventData);
166+
});
167+
168+
expect(handlerSpy).toHaveBeenCalledTimes(3);
169+
expect(handlerSpy).toHaveBeenNthCalledWith(1, 'first');
170+
expect(handlerSpy).toHaveBeenNthCalledWith(2, 'second');
171+
expect(handlerSpy).toHaveBeenNthCalledWith(3, 'third');
172+
expect(el.value).toEqual('replacement');
173+
});
174+
});
125175

126-
});

src/sources/swap-source.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ import { curry } from '../utils/curry';
77
import { EventListenerFunction } from '../types/dom';
88

99
/**
10-
* An Event Source Operator that "cuts" the value of the underlying <input> element
11-
* and resets it to the provided value or empty otherwise
12-
* @param handler A handler function or observer to send events to
13-
* @returns EventSource<string>
10+
* An Event Operator that swaps the value of the underlying <input> element
11+
* with the provided replacement (or empty string by default) and emits the previous value.
12+
* This operator mutates the element's value as a side effect.
13+
* @param replacement A string or function used to compute the new value
14+
* @returns OperatorFunction<Event, string>
1415
*/
1516
export const swap = <E extends Event>(replacement: string | Function) =>
1617
map((e: E) => {
@@ -22,10 +23,10 @@ export const swap = <E extends Event>(replacement: string | Function) =>
2223
;
2324

2425
/**
25-
* An Event Source that "cuts" the value of the underlying &lt;input&gt; element
26-
* and resets it to the provided value or empty otherwise
27-
* @param replacement A new value to swap the current element's value with
28-
* @param source A handler function or observer to send events to
26+
* An Event Adapter that swaps the value of the underlying &lt;input&gt; element
27+
* with the provided replacement (or empty string by default) and emits the previous value to the given target.
28+
* @param replacement A new value or function to compute the element's next value
29+
* @param source A handler function or observer to send emitted values to
2930
* @returns EventSource<string>
3031
*/
3132
export const Swap =

0 commit comments

Comments
 (0)