summaryrefslogtreecommitdiff
path: root/thirdparty/preact/test/browser/linked-state.js
blob: 03db2a7b8a33db71ffa0844c03a54485c89f44db (plain)
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
import { Component } from '../../src/preact';
import { createLinkedState } from '../../src/linked-state';

describe('linked-state', () => {
	class TestComponent extends Component {	}
	let testComponent, linkFunction;

	before( () => {
		testComponent = new TestComponent();
		sinon.spy(TestComponent.prototype, 'setState');
	});

	describe('createLinkedState without eventPath argument', () => {

		before( () => {
			linkFunction = createLinkedState(testComponent,'testStateKey');
			expect(linkFunction).to.be.a('function');
		});

		beforeEach( () => {
			TestComponent.prototype['setState'].reset();
		});

		it('should use value attribute on text input when no eventPath is supplied', () => {
			let element = document.createElement('input');
			element.type= 'text';
			element.value = 'newValue';

			linkFunction({
				currentTarget: element,
				target: element
			});

			expect(TestComponent.prototype.setState).to.have.been.calledOnce;
			expect(TestComponent.prototype.setState).to.have.been.calledWith({'testStateKey': 'newValue'});

			linkFunction.call(element);

			expect(TestComponent.prototype.setState).to.have.been.calledTwice;
			expect(TestComponent.prototype.setState.secondCall).to.have.been.calledWith({'testStateKey': 'newValue'});
		});

		it('should use checked attribute on checkbox input when no eventPath is supplied', () => {
			let checkboxElement = document.createElement('input');
			checkboxElement.type= 'checkbox';
			checkboxElement.checked = true;

			linkFunction({
				currentTarget: checkboxElement,
				target: checkboxElement
			});

			expect(TestComponent.prototype.setState).to.have.been.calledOnce;
			expect(TestComponent.prototype.setState).to.have.been.calledWith({'testStateKey': true});
		});

		it('should use checked attribute on radio input when no eventPath is supplied', () => {
			let radioElement = document.createElement('input');
			radioElement.type= 'radio';
			radioElement.checked = true;

			linkFunction({
				currentTarget: radioElement,
				target: radioElement
			});

			expect(TestComponent.prototype.setState).to.have.been.calledOnce;
			expect(TestComponent.prototype.setState).to.have.been.calledWith({'testStateKey': true});
		});


		it('should set dot notated state key appropriately', () => {
			linkFunction = createLinkedState(testComponent,'nested.state.key');
			let element = document.createElement('input');
			element.type= 'text';
			element.value = 'newValue';

			linkFunction({
				currentTarget: element,
				target: element
			});

			expect(TestComponent.prototype.setState).to.have.been.calledOnce;
			expect(TestComponent.prototype.setState).to.have.been.calledWith({nested: {state: {key: 'newValue'}}});
		});

	});

	describe('createLinkedState with eventPath argument', () => {

		before( () => {
			linkFunction = createLinkedState(testComponent,'testStateKey', 'nested.path');
			expect(linkFunction).to.be.a('function');
		});

		beforeEach( () => {
			TestComponent.prototype['setState'].reset();
		});

		it('should give precedence to nested.path on event over nested.path on component', () => {
			let event = {nested: {path: 'nestedPathValueFromEvent'}};
			let component = {_component: {nested: {path: 'nestedPathValueFromComponent'}}};

			linkFunction.call(component, event);

			expect(TestComponent.prototype.setState).to.have.been.calledOnce;
			expect(TestComponent.prototype.setState).to.have.been.calledWith({'testStateKey': 'nestedPathValueFromEvent'});
		});
	});
});