8739f9af by Nicklas Ansman Giertz

Implement a few tests

1 parent a348cee6
...@@ -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() {
......
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
......