coolerator.vision 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.4
1
+ 0.2.5
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{coolerator.vision}
8
- s.version = "0.2.4"
8
+ s.version = "0.2.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Corey Innis"]
12
- s.date = %q{2009-11-13}
12
+ s.date = %q{2009-11-16}
13
13
  s.description = %q{A Rails plugin}
14
14
  s.email = %q{corey@coolerator.net}
15
15
  s.extra_rdoc_files = [
@@ -1,5 +1,4 @@
1
1
  (function($) {
2
- // VERSION 0.1.0
3
2
  // $.noConflict();
4
3
 
5
4
  Coolerator = {
@@ -1,57 +1,107 @@
1
1
  (function($) {
2
2
  $.extend(Coolerator, {
3
3
  Filters : {
4
- global : [],
5
- scoped : {},
4
+ count : function count() {
5
+ return __count__;
6
+ },
6
7
 
7
- get : function get(scope) {
8
- return $.merge($.makeArray(this.global), $.makeArray(this.scoped[scope]));
9
- }
10
- },
8
+ clear : function clear() {
9
+ __database__ = {};
10
+ __count__ = 0;
11
+ },
11
12
 
12
- Filter : function Filter() {
13
- var scope = ['*'];
14
- var filter = this;
13
+ prepare : function prepare() {
14
+ if(2 !== arguments.length) {
15
+ throw("InvalidArgumentException");
16
+ }
15
17
 
16
- if(arguments.length) {
17
- var first = arguments[0];
18
+ var view = arguments[0];
19
+ var scope = arguments[1];
18
20
 
19
- if('object' === typeof first) {
20
- scope = $.isArray(first.scope) ? first.scope : [first.scope || '*'];
21
+ if('object' !== typeof view || 'string' !== typeof scope) {
22
+ throw("InvalidArgumentException");
23
+ }
24
+
25
+ $.each(view, function prepare_views(name, content) {
26
+ view[name] = $(content);
27
+ });
21
28
 
22
- filter = {
23
- label : first.label,
24
- before : (first.before || function no_op() {}),
25
- after : (first.after || function no_op() {})
26
- };
29
+ var filters = retrieve(scope);
30
+ function before() {
31
+ $.each(filters, function(i, filter) {
32
+ filter.before(view);
33
+ });
34
+
35
+ return { after : after };
27
36
  }
28
- else {
29
- scope = arguments;
37
+
38
+ function after() {
39
+ $.each(filters, function(i, filter) {
40
+ filter.after(view);
41
+ });
42
+
43
+ return { before : before };
30
44
  }
45
+
46
+ return {
47
+ before : before,
48
+ after : after
49
+ };
31
50
  }
51
+ },
32
52
 
33
- $.each(scope, function(i, selector) {
34
- if(selector === '*') {
35
- Coolerator.Filters.global.push(filter);
36
- }
37
- else {
38
- Coolerator.Filters.scoped[selector || '*'] = $.merge(Coolerator.Filters.scoped[selector || '*'] || [], [filter]);
39
- }
53
+ Filter : function Filter() {
54
+ var scopes = arguments.length ? arguments : ['*'];
55
+ var filter = {
56
+ before : no_op,
57
+ after : no_op
58
+ }
59
+
60
+ $.each(scopes, function(i, scope) {
61
+ store(scope, filter);
40
62
  });
41
- }
42
- });
43
63
 
44
- $.extend(Coolerator.Filter.prototype, {
45
- before : function before(fn) {
46
- if('function' == typeof fn) {
47
- this.before = fn;
64
+ function before(fn) {
65
+ filter.before = fn;
66
+ return { after : after };
48
67
  }
49
- },
50
68
 
51
- after : function after(fn) {
52
- if('function' == typeof fn) {
53
- this.after = fn;
69
+ function after(fn) {
70
+ filter.after = fn;
71
+ return { before : before };
54
72
  }
73
+
74
+ return {
75
+ before : before,
76
+ after : after
77
+ };
55
78
  }
56
79
  });
80
+
81
+
82
+ // private...................................................................
83
+
84
+ var __count__ = 0;
85
+ var __database__ = {};
86
+
87
+ function no_op() {}
88
+
89
+ function store(scope, filter) {
90
+ if('object' === typeof scope) {
91
+ filter = scope;
92
+ scope = '*';
93
+ }
94
+
95
+ __database__[scope] = __database__[scope] || [];
96
+ __database__[scope].push(filter);
97
+ __count__ += 1;
98
+ }
99
+
100
+ function retrieve(scope) {
101
+ if('*' === scope) {
102
+ return __database__['*'] || [];
103
+ }
104
+
105
+ return $.merge(__database__['*'] || [], __database__[scope] || []);
106
+ }
57
107
  })(jQuery);
@@ -1,85 +1,83 @@
1
1
  (function($) {
2
+ var __database__ = {
3
+ collections : {},
4
+ instances : {}
5
+ };
6
+
2
7
  $.extend(Coolerator, {
3
- Views : {},
8
+ Views : {
9
+ get : function get(classifier) {
10
+ if( ! classifier || /\s+/.test(classifier)) {
11
+ throw("InvalidArgumentException");
12
+ }
13
+
14
+ return __database__.collections[classifier];
15
+ }
16
+ },
4
17
 
5
18
  View : function View(classifier) {
19
+ if( ! classifier || /\s+/.test(classifier)) {
20
+ throw("InvalidArgumentException");
21
+ }
22
+
6
23
  this.classifier = classifier;
7
24
 
8
- $.extend(this, {
9
- instance : {
10
- content : function content(builder, attributes) {
11
- var html_attributes = attributes.classifier ? { 'class' : attributes.classifier } : {};
25
+ __database__.collections[this.classifier] = this;
26
+ __database__.instances [this.classifier] = {
27
+ content : function content(builder, attributes) {
28
+ var html_attributes = attributes.classifier ? { 'class' : attributes.classifier } : {};
12
29
 
13
- with(builder) {
14
- div(html_attributes);
15
- }
16
- },
30
+ with(builder) {
31
+ div(html_attributes);
32
+ }
33
+ },
17
34
 
18
- methods : {
19
- initialize : function initialize() {
20
- if(this.content) {
21
- this.html(this.content);
22
- }
35
+ methods : {
36
+ initialize : function initialize() {
37
+ if(this.content) {
38
+ this.html(this.content);
23
39
  }
24
40
  }
25
41
  }
26
- });
27
-
28
- Coolerator.Views[classifier] = this;
42
+ };
29
43
  }
30
44
  });
31
45
 
32
46
  $.extend(Coolerator.View.prototype, {
33
- cache : {},
47
+ subscribe : function subscribe(fn) {
48
+ Coolerator.Registrar.subscribe(this, fn);
49
+ },
34
50
 
35
51
  extend : function extend(extension) {
36
- var self = this;
52
+ var instance = extension.instance || {};
53
+ var existing = __database__.instances[this.classifier];
54
+ delete extension.instance;
37
55
 
38
- $.each(extension.instance.methods, function(name, fn) {
39
- if(self.instance.methods[name]) {
40
- var superb = self.instance.methods[name];
56
+ $.each(instance.methods || {}, function(name, fn) {
57
+ var superb = existing.methods[name];
58
+
59
+ if(superb) {
41
60
  function sup() {
42
61
  var args = $.makeArray(arguments);
43
62
  superb.apply(args.shift(), args);
44
63
  }
64
+
45
65
  $.extend(fn, { 'super' : sup });
46
66
  }
47
67
  });
48
68
 
49
- $.extend(true, this.instance, extension.instance);
50
- if(extension.collection) {
51
- $.extend(true, this, extension.collection.methods, extension.collection.configuration);
52
- }
53
- },
54
-
55
- subscribe : function subscribe(callback) {
56
- var self = this;
57
- callback = callback.toString().match(Coolerator.REGEX.FUNCTION_BODY)[1];
58
- callback = new Function('registrar', 'with(registrar) { ' + callback + ' } ;');
59
-
60
- Coolerator.Registrar.subscribe(self, callback);
69
+ $.extend(true, __database__.instances[this.classifier], instance);
70
+ $.extend(true, this, extension);
61
71
  },
62
72
 
63
73
  build : function build(attributes) {
64
- if(this.cache.instance) {
65
- return this.cache.instance;
66
- }
67
-
68
- var result = Prez.build(this.instance, $.extend({ collection: this, classifier : this.classifier }, (attributes || {})));
69
-
70
- // TODO: consider making a call to view.subscribe
71
- function subscribe(callback) {
72
- if(callback) {
73
- callback = callback.toString().match(Coolerator.REGEX.FUNCTION_BODY)[1];
74
- callback = new Function('registrar', 'with(registrar) { ' + callback + ' } ;');
75
- Coolerator.Registrar.subscribe(result, callback);
76
- }
77
- }
74
+ // TODO: provide a template cacheing mechanism.
78
75
 
79
- subscribe(result.subscribe);
76
+ var instance = __database__.instances[this.classifier];
77
+ var result = Prez.build(instance, $.extend({ classifier : this.classifier }, (attributes || {})));
80
78
 
81
- if(this.singleton) {
82
- this.cache.instance = result;
79
+ if(result.subscribe) {
80
+ Coolerator.Registrar.subscribe(result, result.subscribe);
83
81
  }
84
82
 
85
83
  return result;
@@ -1,20 +1,274 @@
1
1
  //= require <support/spec_helper>
2
2
 
3
3
  Screw.Unit(function(c) { with(c) {
4
+ after(function() {
5
+ Coolerator.Filters.clear();
6
+ });
7
+
8
+ describe("an example", function() {
9
+ before(function() {
10
+ Coolerator.Filter('scope/one', 'scope/two')
11
+ .before(function(view) {
12
+ $.each(view, function(key, partial) {
13
+ partial.css('border', 'yellow');
14
+ });
15
+ })
16
+ .after(function(view) {
17
+ $.each(view, function(key, partial) {
18
+ partial.css('border', 'green');
19
+ });
20
+ });
21
+ });
22
+
23
+ it("behaves", function() {
24
+ var templates = { show : '<div>content</div>' };
25
+ var filters = Coolerator.Filters.prepare(templates, 'scope/one');
26
+ expect(templates.show.jquery).to_not(be_undefined);
27
+
28
+ filters.before();
29
+ expect(templates.show.css('border')).to(match, 'yellow');
30
+
31
+ filters.after();
32
+ expect(templates.show.css('border')).to(match, 'green');
33
+ });
34
+ });
35
+
36
+ describe("Coolerator.Filters", function() {
37
+ it("is added to the Coolerator namespace", function() {
38
+ expect(typeof Coolerator.Filters).to(equal, 'object');
39
+ });
40
+
41
+ describe("methods", function() {
42
+ describe(".count", function() {
43
+ before(function() {
44
+ Coolerator.Filter({});
45
+ Coolerator.Filter({ scope : 'scope 1' });
46
+ Coolerator.Filter({ scope : 'scope 1' });
47
+ Coolerator.Filter({ scope : 'scope 2' });
48
+ });
49
+
50
+ it("returns the count of filters, regardless of scope", function() {
51
+ expect(Coolerator.Filters.count()).to(equal, 4);
52
+ });
53
+ });
54
+
55
+ describe(".clear", function() {
56
+ before(function() {
57
+ Coolerator.Filter({ label : 'clear' });
58
+ });
59
+
60
+ it("sets 'count' to 0", function() {
61
+ expect(Coolerator.Filters.count()).to(equal, 1);
62
+
63
+ Coolerator.Filters.clear();
64
+ expect(Coolerator.Filters.count()).to(equal, 0);
65
+ });
66
+ });
67
+
68
+ describe(".prepare", function() {
69
+ var view;
70
+
71
+ before(function() {
72
+ view = { show : '<div>content</div>' };
73
+ });
74
+
75
+ describe("argument handling", function() {
76
+ var filters;
77
+
78
+ context("with appropriate arguments", function() {
79
+ before(function() {
80
+ filters = Coolerator.Filters.prepare(view, '*');
81
+ });
82
+
83
+ it("converts the view 'partials' to jQuery objects", function() {
84
+ expect(view.show.jquery).to_not(be_undefined);
85
+ });
86
+
87
+ describe("the returned filter helper", function() {
88
+ it("defines #before", function() {
89
+ expect(filters.before).to_not(throw_exception);
90
+ });
91
+
92
+ it("defines #after", function() {
93
+ expect(filters.after).to_not(throw_exception);
94
+ });
95
+ });
96
+ });
97
+
98
+ context("with fewer than two", function() {
99
+ before(function() {
100
+ fn = function fn() {
101
+ Coolerator.Filters.prepare({});
102
+ };
103
+ });
104
+
105
+ it("throws an exception", function() {
106
+ expect(fn).to(throw_exception);
107
+ });
108
+ });
109
+
110
+ context("with more than two", function() {
111
+ before(function() {
112
+ fn = function fn() {
113
+ Coolerator.Filters.prepare({}, 'scope', 'something else');
114
+ };
115
+ });
116
+
117
+ it("throws an exception", function() {
118
+ expect(fn).to(throw_exception);
119
+ });
120
+ });
121
+
122
+ context("with an undefined 'view'", function() {
123
+ before(function() {
124
+ fn = function fn() {
125
+ Coolerator.Filters.prepare(undefined, 'scope');
126
+ };
127
+ });
128
+
129
+ it("throws an exception", function() {
130
+ expect(fn).to(throw_exception);
131
+ });
132
+ });
133
+
134
+ context("with an undefined 'scope'", function() {
135
+ before(function() {
136
+ fn = function fn() {
137
+ Coolerator.Filters.prepare({ show : '<div>content</div>' }, undefined);
138
+ };
139
+ });
140
+
141
+ it("throws an exception", function() {
142
+ expect(fn).to(throw_exception);
143
+ });
144
+ });
145
+ });
146
+ });
147
+ });
148
+ });
149
+
4
150
  describe("Coolerator.Filter", function() {
151
+ var filter;
152
+
5
153
  it("is added to the Coolerator namespace", function() {
6
154
  expect(typeof Coolerator.Filter).to(equal, 'function');
7
155
  });
8
156
 
9
- context("when created with a configuration object", function() {
10
- context("when the configuration :label exists", function() {
11
- var filter = new Coolerator.Filter({
12
- label : 'so cool!',
13
- scope : 'everywhere'
157
+ describe("the returned object", function() {
158
+ before(function() {
159
+ filter = Coolerator.Filter();
160
+ });
161
+
162
+ it("is defined", function() {
163
+ expect(filter).to_not(be_undefined);
164
+ });
165
+
166
+ it("defines #before", function() {
167
+ expect(filter.before).to_not(be_undefined);
168
+ });
169
+
170
+ it("defines #after", function() {
171
+ expect(filter.after).to_not(be_undefined);
172
+ });
173
+ });
174
+
175
+ describe("argument handling", function() {
176
+ var called;
177
+
178
+ before(function() {
179
+ called = {
180
+ before : false,
181
+ after : false
182
+ }
183
+ });
184
+
185
+ context("called with no scope", function() {
186
+ before(function() {
187
+ Coolerator.Filter()
188
+ .before(function(view) {
189
+ called.before = true;
190
+ })
191
+ .after(function(view) {
192
+ called.after = true;
193
+ });
194
+ });
195
+
196
+ it("adds the filter to the 'global' scope", function() {
197
+ Coolerator.Filters.prepare({}, '*')
198
+ .before()
199
+ .after();
200
+
201
+ expect(called.before).to(be_true);
202
+ expect(called.after ).to(be_true);
14
203
  });
204
+ });
205
+
206
+ context("called with a single scope", function() {
207
+ before(function() {
208
+ Coolerator.Filter('one')
209
+ .before(function(view) {
210
+ called.before = true;
211
+ })
212
+ .after(function(view) {
213
+ called.after = true;
214
+ });
215
+ });
216
+
217
+ it("adds the filter to the provided scope", function() {
218
+ Coolerator.Filters.prepare({}, 'one')
219
+ .before()
220
+ .after();
221
+
222
+ expect(called.before).to(be_true);
223
+ expect(called.after ).to(be_true);
224
+ });
225
+
226
+ it("does not add the filter to the global scope", function() {
227
+ Coolerator.Filters.prepare({}, '*')
228
+ .before()
229
+ .after();
230
+
231
+ expect(called.before).to(be_false);
232
+ expect(called.after ).to(be_false);
233
+ });
234
+ });
235
+
236
+ context("called with multiple scopes", function() {
237
+ before(function() {
238
+ Coolerator.Filter('one', 'two')
239
+ .before(function(view) {
240
+ called.before = true;
241
+ })
242
+ .after(function(view) {
243
+ called.after = true;
244
+ });
245
+ });
246
+
247
+ it("adds the filter to the first provided scope", function() {
248
+ Coolerator.Filters.prepare({}, 'one')
249
+ .before()
250
+ .after();
251
+
252
+ expect(called.before).to(be_true);
253
+ expect(called.after ).to(be_true);
254
+ });
255
+
256
+ it("adds the filter to the first provided scope", function() {
257
+ Coolerator.Filters.prepare({}, 'two')
258
+ .before()
259
+ .after();
260
+
261
+ expect(called.before).to(be_true);
262
+ expect(called.after ).to(be_true);
263
+ });
264
+
265
+ it("does not add the filter to the global scope", function() {
266
+ Coolerator.Filters.prepare({}, '*')
267
+ .before()
268
+ .after();
15
269
 
16
- it("is created with a label", function() {
17
- expect(Coolerator.Filters.get('everywhere')[0].label).to(equal, 'so cool!');
270
+ expect(called.before).to(be_false);
271
+ expect(called.after ).to(be_false);
18
272
  });
19
273
  });
20
274
  });
@@ -3,96 +3,393 @@
3
3
  Screw.Unit(function(c) { with(c) {
4
4
  describe("Coolerator.Views", function() {
5
5
  it("is added to the Coolerator namespace", function() {
6
- expect(Coolerator.Views).to_not(be_undefined);
6
+ expect(typeof Coolerator.Views).to(equal, 'object');
7
7
  });
8
8
 
9
- describe("when creating a Coolerator.View", function() {
10
- it("the View is added to the collection", function() {
11
- var view = new Coolerator.View('oh, behave!');
12
- expect(Coolerator.Views['oh, behave!']).to(equal, view);
9
+ describe("methods", function() {
10
+ describe(".get", function() {
11
+ context("with 'classifier' defined appropriately", function() {
12
+ context("when there is a match", function() {
13
+ it("returns the view", function() {
14
+ var view = new Coolerator.View('defined');
15
+ expect(Coolerator.Views.get('defined')).to(equal, view);
16
+ });
17
+ });
18
+
19
+ context("when there is no match", function() {
20
+ it("returns undefined", function() {
21
+ expect(Coolerator.Views.get('undefined')).to(be_undefined);
22
+ });
23
+ });
24
+ });
25
+
26
+ context("with 'classifier' as falsy", function() {
27
+ var fn;
28
+
29
+ it("throws an exception (with undefined)", function() {
30
+ fn = function fn() {
31
+ Coolerator.Views.get();
32
+ }
33
+ expect(fn).to(throw_exception);
34
+ });
35
+
36
+ it("throws an exception (with null)", function() {
37
+ fn = function fn() {
38
+ Coolerator.Views.get(null);
39
+ }
40
+ expect(fn).to(throw_exception);
41
+ });
42
+
43
+ it("throws an exception (with empty string)", function() {
44
+ fn = function fn() {
45
+ Coolerator.Views.get('');
46
+ }
47
+ expect(fn).to(throw_exception);
48
+ });
49
+
50
+ it("throws an exception (with 0)", function() {
51
+ fn = function fn() {
52
+ Coolerator.Views.get(0);
53
+ }
54
+ expect(fn).to(throw_exception);
55
+ });
56
+ });
13
57
  });
14
58
  });
15
59
  });
16
60
 
17
61
  describe("Coolerator.View", function() {
18
62
  it("is added to the Coolerator namespace", function() {
19
- expect(Coolerator.View).to_not(be_undefined);
63
+ expect(typeof Coolerator.View).to(equal, 'function');
20
64
  });
21
65
 
22
- describe("collection", function() {
23
- it("is optional", function() {
24
- var fn = function() {
25
- var view = new Coolerator.View('one');
66
+ describe("constructor", function() {
67
+ var fn;
26
68
 
27
- view.extend({
28
- instance : {
29
- methods : {}
30
- }
69
+ context("with 'classifier' defined appropriately", function() {
70
+ var view;
71
+
72
+ before(function() {
73
+ view = new Coolerator.View('valid');
74
+ });
75
+
76
+ describe("the returned object", function() {
77
+ it("is a Coolerator.View instance", function() {
78
+ expect(view.constructor.name).to(equal, 'View');
31
79
  });
32
- };
33
80
 
34
- expect(fn).to_not(throw_exception);
35
- });
36
- });
81
+ it("defines 'classifier' as an attribute", function() {
82
+ expect(view.classifier).to(equal, 'valid');
83
+ });
84
+ });
37
85
 
38
- describe("instance", function() {
39
- describe("methods which are implemented in super and child objects", function() {
40
- var view, other;
86
+ describe("updates to Coolerator.Views", function() {
87
+ it("stores the new view", function() {
88
+ expect(Coolerator.Views.get('valid')).to(equal, view);
89
+ });
90
+
91
+ it("overwrites an existing view of the same classifier", function() {
92
+ var over = new Coolerator.View('valid');
41
93
 
94
+ expect(Coolerator.Views.get('valid') == over).to(be_true);
95
+ expect(Coolerator.Views.get('valid') == view).to(be_false);
96
+ });
97
+ });
98
+ });
99
+
100
+ context("with 'classifier' defined with space(s)", function() {
42
101
  before(function() {
43
- other = new Coolerator.View('other');
44
- view = new Coolerator.View('child');
102
+ fn = function fn() {
103
+ return new Coolerator.View('with spaces');
104
+ }
105
+ });
45
106
 
46
- view.extend({
47
- instance : {
48
- methods : {
49
- initialize : function initialize() {}
50
- }
51
- }
52
- })
107
+ it("throws an exception", function() {
108
+ expect(fn).to(throw_exception);
109
+ });
110
+ });
111
+
112
+ context("with 'classifier' defined as falsy", function() {
113
+ it("throws an exception (with undefined)", function() {
114
+ fn = function fn() {
115
+ return new Coolerator.View();
116
+ }
117
+ expect(fn).to(throw_exception);
118
+ });
119
+
120
+ it("throws an exception (with null)", function() {
121
+ fn = function fn() {
122
+ return new Coolerator.View(null);
123
+ }
124
+ expect(fn).to(throw_exception);
53
125
  });
54
126
 
55
- it("provides a mechanism for calling #super", function() {
56
- var instance = view.build();
57
- expect(instance.initialize.super).to(equal, other.instance.methods.initialize);
127
+ it("throws an exception (with empty string)", function() {
128
+ fn = function fn() {
129
+ return new Coolerator.View('');
130
+ }
131
+ expect(fn).to(throw_exception);
132
+ });
133
+
134
+ it("throws an exception (with 0)", function() {
135
+ fn = function fn() {
136
+ return new Coolerator.View(0);
137
+ }
138
+ expect(fn).to(throw_exception);
58
139
  });
59
140
  });
141
+ });
60
142
 
61
- describe("when two or more Views implement the same method", function() {
62
- var instance1, instance2;
143
+ describe("methods", function() {
144
+ var view;
63
145
 
64
- before(function() {
65
- view1 = new Coolerator.View('one');
146
+ before(function() {
147
+ view = new Coolerator.View('subscript');
148
+ });
66
149
 
67
- view1.extend({
68
- instance : {
69
- methods : {
70
- foo : function foo() {
71
- return "foo an instance of view1";
150
+ describe("#subscribe", function() {
151
+ context("given a function", function() {
152
+ it("executes the function with 'this' as the view", function() {
153
+ view.subscribe(function() {
154
+ expect(this).to(equal, view);
155
+ });
156
+ });
157
+
158
+ it("executes the function with a Coolerator.Registar subscription", function() {
159
+ view.subscribe(function(subscription) { with(subscription) {
160
+ expect(on ).to_not(be_undefined);
161
+ expect(use).to_not(be_undefined);
162
+ }});
163
+ });
164
+
165
+ it("[PENDING] executes the function after executing #extend, so other fields are available", function() {
166
+ // this does work, but it relies on jQuery's document ready event which makes it hard to test here.
167
+ });
168
+ });
169
+ });
170
+
171
+ describe("#extend", function() {
172
+ context("given an extension with non-instance arguments", function() {
173
+ it("extends the 'collection' object (the view)", function() {
174
+ function func() {};
175
+
176
+ view.extend({
177
+ conf : 'config',
178
+ func : func
179
+ });
180
+
181
+ expect(view.conf).to(equal, 'config');
182
+ expect(view.func).to(equal, func);
183
+ });
184
+
185
+ it("does not 'step on' other views", function() {
186
+ var view1 = new Coolerator.View('one');
187
+ var view2 = new Coolerator.View('two');
188
+
189
+ view1.extend({
190
+ foo : function foo() {
191
+ return 'foo on view one';
192
+ }
193
+ });
194
+
195
+ view2.extend({
196
+ foo : function foo() {
197
+ return 'foo on view two';
198
+ }
199
+ });
200
+
201
+ expect(view1.foo()).to(equal, 'foo on view one');
202
+ expect(view2.foo()).to(equal, 'foo on view two');
203
+ });
204
+ });
205
+
206
+ context("given an extension with an instance argument", function() {
207
+ it("does not extend the 'collection' object", function() {
208
+ view.extend({
209
+ instance : {
210
+ methods : {}
211
+ }
212
+ });
213
+
214
+ expect(view.instance).to(be_undefined);
215
+ });
216
+
217
+ it("extends built instances", function() {
218
+ view.extend({
219
+ instance : {
220
+ content : function content(builder) {
221
+ builder.div('content');
222
+ },
223
+
224
+ methods : {
225
+ label : function label() {
226
+ return 'an instance';
227
+ }
72
228
  }
73
229
  }
74
- }
230
+ });
231
+
232
+ expect(view.build().label()).to(equal, 'an instance');
75
233
  });
76
234
 
77
- view2 = new Coolerator.View('two');
235
+ it("does not 'step on' other views", function() {
236
+ var view1 = new Coolerator.View('one');
237
+ var view2 = new Coolerator.View('two');
78
238
 
79
- view2.extend({
80
- instance : {
81
- methods : {
82
- foo : function foo() {
83
- return "foo an instance of view2";
84
- }
85
- }
86
- }
87
- });
239
+ view1.extend({
240
+ instance : {
241
+ methods : {
242
+ foo : function foo() {
243
+ return 'foo on view one';
244
+ }
245
+ }
246
+ }
247
+ });
88
248
 
89
- instance1 = view1.build();
90
- instance2 = view2.build();
249
+ view2.extend({
250
+ instance : {
251
+ methods : {
252
+ foo : function foo() {
253
+ return 'foo on view two';
254
+ }
255
+ }
256
+ }
257
+ });
258
+
259
+ expect(view1.build().foo()).to(equal, 'foo on view one');
260
+ expect(view2.build().foo()).to(equal, 'foo on view two');
261
+ });
262
+
263
+ describe("content (for the builder)", function() {
264
+ it("is defaulted to a simple <div />", function() {
265
+ view.extend({
266
+ instance : {}
267
+ });
268
+
269
+ var wrapper = $('<div></div>');
270
+ wrapper.html(view.build());
271
+ expect(wrapper.html()).to(equal, '<div class="subscript"></div>');
272
+ });
273
+
274
+ describe("overwriting", function() {
275
+ it("is allowed", function() {
276
+ view.extend({
277
+ instance : {
278
+ content : function content(builder) {
279
+ with(builder) {
280
+ div({ id : 'custom' });
281
+ }
282
+ }
283
+ }
284
+ });
285
+
286
+ var wrapper = $('<div></div>');
287
+ wrapper.html(view.build());
288
+ expect(wrapper.html()).to(equal, '<div id="custom"></div>');
289
+ });
290
+ });
291
+ });
292
+
293
+ describe("methods", function() {
294
+ describe("#initialize", function() {
295
+ it("is called automatically", function() {
296
+ var called = false;
297
+
298
+ view.extend({
299
+ instance : {
300
+ methods : {
301
+ initialize : function initialize() {
302
+ called = true;
303
+ }
304
+ }
305
+ }
306
+ });
307
+
308
+ view.build();
309
+ expect(called).to(be_true);
310
+ });
311
+
312
+ it("is defaulted to (optionally) write provided content to the instance", function() {
313
+ view.extend({
314
+ instance : {}
315
+ });
316
+
317
+ expect(view.build().html()).to(equal, '');
318
+ expect(view.build({ content : 'hello there' }).html()).to(equal, 'hello there');
319
+ });
320
+
321
+ describe("overwriting", function() {
322
+ before(function() {
323
+ view.extend({
324
+ instance : {
325
+ methods : {
326
+ initialize : function initialize() {
327
+ this.html('overwritten');
328
+ }
329
+ }
330
+ }
331
+ });
332
+ });
333
+
334
+ it("is allowed", function() {
335
+ var instance = view.build();
336
+ expect(instance.html()).to(equal, 'overwritten');
337
+ });
338
+
339
+ it("provides a mechanism for calling #super", function() {
340
+ var instance = view.build();
341
+ expect(typeof instance.initialize.super).to(equal, 'function');
342
+ });
343
+ });
344
+ });
345
+
346
+ describe("#subscribe", function() {
347
+ it("is called automatically, with 'this' as the instance and a Coolerator.Registar subscription as an argument", function() {
348
+ var called = false;
349
+ var callee = null;
350
+
351
+ view.extend({
352
+ instance : {
353
+ methods : {
354
+ subscribe : function subscribe(subscription) {
355
+ called = true;
356
+ callee = this;
357
+
358
+ with(subscription) {
359
+ expect(on ).to_not(be_undefined);
360
+ expect(use).to_not(be_undefined);
361
+ }
362
+ }
363
+ }
364
+ }
365
+ });
366
+
367
+ var instance = view.build();
368
+ expect(called).to(be_true);
369
+ expect(callee).to(equal, instance);
370
+ });
371
+ });
372
+ });
91
373
  });
374
+ });
375
+
376
+ describe("#build", function() {
377
+ it("returns an 'instance' of the view", function() {
378
+ view.extend({
379
+ instance : {
380
+ content : function content(builder) {
381
+ builder.div('content');
382
+ },
383
+
384
+ methods : {
385
+ label : function label() {
386
+ return 'an instance';
387
+ }
388
+ }
389
+ }
390
+ });
92
391
 
93
- it("allows them to coexist", function() {
94
- expect(instance1.foo()).to(equal, "foo an instance of view1");
95
- expect(instance2.foo()).to(equal, "foo an instance of view2");
392
+ expect(view.build().label()).to(equal, 'an instance');
96
393
  });
97
394
  });
98
395
  });
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coolerator.vision
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Corey Innis
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-13 00:00:00 -05:00
12
+ date: 2009-11-16 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency