Implement a few tests
Showing
5 changed files
with
145 additions
and
53 deletions
... | @@ -88,36 +88,28 @@ | ... | @@ -88,36 +88,28 @@ |
88 | }; | 88 | }; |
89 | 89 | ||
90 | View.prototype.build = function() { | 90 | View.prototype.build = function() { |
91 | var attribute, bindingRegExp, keypath, model, node, path, pipes, type, _i, _len, _ref, _results; | 91 | var attribute, bindingRegExp, elements, keypath, model, node, path, pipes, type, _i, _j, _len, _len1, _ref; |
92 | this.bindings = []; | 92 | this.bindings = []; |
93 | bindingRegExp = this.bindingRegExp(); | 93 | bindingRegExp = this.bindingRegExp(); |
94 | _ref = this.el.getElementsByTagName('*'); | 94 | elements = [this.el]; |
95 | _results = []; | 95 | elements.concat(Array.prototype.slice.call(this.el.getElementsByTagName('*'))); |
96 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { | 96 | for (_i = 0, _len = elements.length; _i < _len; _i++) { |
97 | node = _ref[_i]; | 97 | node = elements[_i]; |
98 | _results.push((function() { | 98 | _ref = node.attributes; |
99 | var _j, _len1, _ref1, _results1; | 99 | for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { |
100 | _ref1 = node.attributes; | 100 | attribute = _ref[_j]; |
101 | _results1 = []; | 101 | if (bindingRegExp.test(attribute.name)) { |
102 | for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { | 102 | type = attribute.name.replace(bindingRegExp, ''); |
103 | attribute = _ref1[_j]; | 103 | pipes = attribute.value.split('|').map(function(pipe) { |
104 | if (bindingRegExp.test(attribute.name)) { | 104 | return pipe.trim(); |
105 | type = attribute.name.replace(bindingRegExp, ''); | 105 | }); |
106 | pipes = attribute.value.split('|').map(function(pipe) { | 106 | path = pipes.shift().split('.'); |
107 | return pipe.trim(); | 107 | model = this.models[path.shift()]; |
108 | }); | 108 | keypath = path.join('.'); |
109 | path = pipes.shift().split('.'); | 109 | this.bindings.push(new Rivets.Binding(node, type, model, keypath, pipes)); |
110 | model = this.models[path.shift()]; | ||
111 | keypath = path.join('.'); | ||
112 | _results1.push(this.bindings.push(new Rivets.Binding(node, type, model, keypath, pipes))); | ||
113 | } else { | ||
114 | _results1.push(void 0); | ||
115 | } | ||
116 | } | 110 | } |
117 | return _results1; | 111 | } |
118 | }).call(this)); | ||
119 | } | 112 | } |
120 | return _results; | ||
121 | }; | 113 | }; |
122 | 114 | ||
123 | View.prototype.bind = function() { | 115 | View.prototype.bind = function() { | ... | ... |
spec/matchers.js
0 → 100644
1 | beforeEach(function() { | ||
2 | this.addMatchers({ | ||
3 | toHaveTheTextContent: function(expected) { | ||
4 | var el = this.actual; | ||
5 | actual = el.textContent || el.innerText; | ||
6 | this.message = function() { | ||
7 | return "Expected '" + actual + "' to be '" + expected + "'"; | ||
8 | } | ||
9 | return actual === expected; | ||
10 | } | ||
11 | }); | ||
12 | }); |
... | @@ -4,11 +4,32 @@ function Data(attributes) { | ... | @@ -4,11 +4,32 @@ function Data(attributes) { |
4 | } | 4 | } |
5 | 5 | ||
6 | Data.prototype.on = function(key, callback) { | 6 | Data.prototype.on = function(key, callback) { |
7 | this.change[key][callback] = true; | 7 | if(this.hasCallback(key, callback)) |
8 | return; | ||
9 | var ref = this.change[key] || (this.change[key] = []); | ||
10 | this.change[key].push(callback); | ||
11 | } | ||
12 | |||
13 | Data.prototype.hasCallback = function(key, callback) { | ||
14 | return indexOf(this.change[key], callback) !== -1; | ||
15 | } | ||
16 | |||
17 | indexOf = function(array, value) { | ||
18 | array || (array = []) | ||
19 | if(array.indexOf) | ||
20 | return array.indexOf(value); | ||
21 | |||
22 | for(i in array || {}) { | ||
23 | if(array[i] === value) | ||
24 | return i; | ||
25 | } | ||
26 | return -1; | ||
8 | } | 27 | } |
9 | 28 | ||
10 | Data.prototype.off = function(key, callback) { | 29 | Data.prototype.off = function(key, callback) { |
11 | delete this.change[key][callback]; | 30 | var index = indexOf(this.change[key], callback); |
31 | if(index !== -1) | ||
32 | this.change[key].splice(index, 1); | ||
12 | } | 33 | } |
13 | 34 | ||
14 | Data.prototype.set = function(attributes) { | 35 | Data.prototype.set = function(attributes) { |
... | @@ -23,15 +44,17 @@ Data.prototype.set = function(attributes) { | ... | @@ -23,15 +44,17 @@ Data.prototype.set = function(attributes) { |
23 | } | 44 | } |
24 | 45 | ||
25 | Data.prototype.get = function(key) { | 46 | Data.prototype.get = function(key) { |
26 | this.attributes[key]; | 47 | return this.attributes[key]; |
27 | } | 48 | } |
28 | 49 | ||
29 | Data.prototype.alertCallbacks = function(key) { | 50 | Data.prototype.alertCallbacks = function(key) { |
30 | if(!this.change[key]) | 51 | if(!this.change[key]) |
31 | return; | 52 | return; |
32 | 53 | ||
33 | for(callback in this.change[key]) | 54 | var key, callbacks; |
34 | callback(this.get(key)); | 55 | for(i in this.change[key]) { |
56 | this.change[key][i](this.get(key)); | ||
57 | } | ||
35 | } | 58 | } |
36 | 59 | ||
37 | window.Data = Data; | 60 | window.Data = Data; | ... | ... |
1 | rivets.configure({ | ||
2 | adapter: { | ||
3 | subscribe: function(obj, keypath, callback) { | ||
4 | obj.on(keypath, callback); | ||
5 | }, | ||
6 | read: function(obj, keypath) { | ||
7 | obj.get(keypath); | ||
8 | }, | ||
9 | publish: function(obj, keypath, value) { | ||
10 | attributes = {}; | ||
11 | attributes[keypath] = value; | ||
12 | obj.set(attributes); | ||
13 | } | ||
14 | } | ||
15 | }); | ||
16 | 1 | ||
17 | 2 | ||
18 | describe('Rivets: ', function() { | 3 | describe('Rivets', function() { |
19 | var data; | 4 | var data, bindData, el; |
20 | 5 | ||
21 | beforeEach(function() { | 6 | beforeEach(function() { |
22 | data = new Data(); | 7 | data = new Data({foo: 'bar'}); |
8 | bindData = {data: data}; | ||
9 | el = document.createElement('div'); | ||
10 | |||
11 | rivets.configure({ | ||
12 | preloadData: true, | ||
13 | adapter: { | ||
14 | subscribe: function(obj, keypath, callback) { | ||
15 | obj.on(keypath, callback); | ||
16 | }, | ||
17 | read: function(obj, keypath) { | ||
18 | return obj.get(keypath); | ||
19 | }, | ||
20 | publish: function(obj, keypath, value) { | ||
21 | attributes = {}; | ||
22 | attributes[keypath] = value; | ||
23 | obj.set(attributes); | ||
24 | } | ||
25 | } | ||
26 | }); | ||
27 | }); | ||
28 | |||
29 | describe('Adapter', function() { | ||
30 | it('should read the initial value', function() { | ||
31 | spyOn(data, 'get'); | ||
32 | el.setAttribute('data-text', 'data.foo'); | ||
33 | rivets.bind(el, bindData); | ||
34 | expect(data.get).toHaveBeenCalledWith('foo'); | ||
35 | }); | ||
36 | |||
37 | it('should read the initial value unless preloadData is false', function() { | ||
38 | rivets.configure({preloadData: false}); | ||
39 | spyOn(data, 'get'); | ||
40 | el.setAttribute('data-value', 'data.foo'); | ||
41 | rivets.bind(el, bindData); | ||
42 | expect(data.get).not.toHaveBeenCalled(); | ||
43 | }); | ||
44 | |||
45 | it('should subscribe to updates', function() { | ||
46 | spyOn(data, 'on'); | ||
47 | el.setAttribute('data-value', 'data.foo'); | ||
48 | rivets.bind(el, bindData); | ||
49 | expect(data.on).toHaveBeenCalled(); | ||
50 | }); | ||
23 | }); | 51 | }); |
24 | 52 | ||
25 | describe('Stuff', function() { | 53 | describe('Binds', function() { |
26 | it('should work', function() { | 54 | describe('Text', function() { |
27 | expect(data.get('foo')).toBe(undefined); | 55 | it('should set the text content of the element', function() { |
28 | expect(data.get('bar')).toBe('not undefined'); | 56 | el.setAttribute('data-text', 'data.foo'); |
57 | rivets.bind(el, bindData); | ||
58 | expect(el.textContent || el.innerText).toBe(data.get('foo')); | ||
59 | }); | ||
60 | |||
61 | it('should correctly handle HTML in the content', function() { | ||
62 | el.setAttribute('data-text', 'data.foo'); | ||
63 | value = '<b>Fail</b>'; | ||
64 | data.set({foo: value}); | ||
65 | rivets.bind(el, bindData); | ||
66 | expect(el.textContent || el.innerText).toBe(value); | ||
67 | }); | ||
68 | }); | ||
69 | |||
70 | describe('HTML', function() { | ||
71 | it('should set the html content of the element', function() { | ||
72 | el.setAttribute('data-html', 'data.foo'); | ||
73 | rivets.bind(el, bindData); | ||
74 | expect(el).toHaveTheTextContent(data.get('foo')); | ||
75 | }); | ||
76 | |||
77 | it('should correctly handle HTML in the content', function() { | ||
78 | el.setAttribute('data-html', 'data.foo'); | ||
79 | value = '<b>Fail</b>'; | ||
80 | data.set({foo: value}); | ||
81 | rivets.bind(el, bindData); | ||
82 | expect(el.innerHTML).toBe(value); | ||
83 | }); | ||
84 | }); | ||
85 | |||
86 | describe('Updates', function() { | ||
87 | it('should change the value', function() { | ||
88 | el.setAttribute('data-text', 'data.foo'); | ||
89 | rivets.bind(el, bindData); | ||
90 | data.set({foo: 'some new value'}); | ||
91 | expect(el).toHaveTheTextContent(data.get('foo')); | ||
92 | }); | ||
29 | }); | 93 | }); |
30 | }); | 94 | }); |
31 | }); | 95 | }); | ... | ... |
... | @@ -11,6 +11,7 @@ | ... | @@ -11,6 +11,7 @@ |
11 | 11 | ||
12 | <script type="text/javascript" src="build/rivets.js"></script> | 12 | <script type="text/javascript" src="build/rivets.js"></script> |
13 | 13 | ||
14 | <script type="text/javascript" src="spec/matchers.js"></script> | ||
14 | <script type="text/javascript" src="spec/mock.data.js"></script> | 15 | <script type="text/javascript" src="spec/mock.data.js"></script> |
15 | <script type="text/javascript" src="spec/rivets.js"></script> | 16 | <script type="text/javascript" src="spec/rivets.js"></script> |
16 | 17 | ... | ... |
-
Please register or sign in to post a comment