lanes 0.0.5 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/Gemfile +0 -1
- data/README.md +2 -0
- data/client/lanes/data/Bootstrap.coffee +2 -2
- data/client/lanes/data/Collection.coffee +4 -0
- data/client/lanes/data/Config.coffee +0 -5
- data/client/lanes/data/Model.coffee +236 -150
- data/client/lanes/data/PubSub.coffee +6 -12
- data/client/lanes/data/Sync.coffee +1 -0
- data/client/lanes/extension/Extensions.coffee +4 -2
- data/client/lanes/lib/MakeBaseClass.coffee +1 -1
- data/client/lanes/minimal.js +11 -0
- data/client/lanes/minimal.scss.erb +12 -0
- data/client/lanes/screens/Base.coffee +1 -2
- data/client/lanes/screens/Instance.coffee +52 -0
- data/client/lanes/vendor/packaged.js +1 -2
- data/client/lanes/views/Base.coffee +12 -10
- data/client/lanes/workspace.scss.erb +3 -0
- data/client/lanes/workspace/index.js +2 -12
- data/docs/command.md +111 -0
- data/docs/model.md +188 -0
- data/docs/todo-example-part-1.md +71 -0
- data/docs/view.md +275 -0
- data/{spec/client/jasmine_examples/PlayerSpec.js → docs/welcome.md} +0 -0
- data/lanes.gemspec +3 -1
- data/lib/lanes/api/helper_methods.rb +8 -0
- data/lib/lanes/api/javascript_processor.rb +14 -10
- data/lib/lanes/api/pub_sub.rb +7 -7
- data/lib/lanes/api/request_wrapper.rb +1 -0
- data/lib/lanes/api/root.rb +2 -7
- data/lib/lanes/api/sprockets_compressor.rb +6 -2
- data/lib/lanes/api/sprockets_extension.rb +25 -9
- data/lib/lanes/api/test_specs.rb +13 -9
- data/lib/lanes/command.rb +16 -6
- data/lib/lanes/command/app.rb +11 -5
- data/lib/lanes/command/generate_model.rb +4 -3
- data/lib/lanes/command/generate_screen.rb +2 -1
- data/lib/lanes/command/generate_view.rb +1 -1
- data/lib/lanes/command/named_command.rb +5 -4
- data/lib/lanes/command/templates/Gemfile +1 -2
- data/lib/lanes/command/templates/client/data/Model.coffee +3 -3
- data/lib/lanes/command/templates/client/{namespace-extension.js → index.js} +0 -0
- data/lib/lanes/command/templates/client/screens/Screen.coffee +1 -3
- data/lib/lanes/command/templates/client/{styles/styles.scss → styles.scss} +0 -0
- data/lib/lanes/command/templates/client/views/View.coffee +1 -3
- data/lib/lanes/command/templates/config/lanes.rb +1 -1
- data/lib/lanes/command/templates/gitignore +1 -0
- data/lib/lanes/command/templates/lib/namespace/screen.rb +1 -1
- data/lib/lanes/command/templates/public/.gitkeep +0 -0
- data/lib/lanes/command/templates/spec/client/Screen.coffee +7 -0
- data/lib/lanes/command/templates/spec/client/views/ViewSpec.coffee +2 -2
- data/lib/lanes/concerns/all.rb +1 -1
- data/lib/lanes/concerns/sanitize_fields.rb +32 -0
- data/lib/lanes/concerns/set_attribute_data.rb +4 -4
- data/lib/lanes/db.rb +7 -8
- data/lib/lanes/extension.rb +37 -3
- data/lib/lanes/guard_tasks.rb +2 -2
- data/lib/lanes/model.rb +2 -2
- data/lib/lanes/screens.rb +1 -0
- data/lib/lanes/spec_helper.rb +17 -6
- data/{spec → lib/lanes}/testing_models.rb +1 -1
- data/lib/lanes/version.rb +1 -1
- data/npm-build/compile.coffee +1 -6
- data/public/javascripts/jasmine_examples/Player.js +22 -0
- data/public/javascripts/jasmine_examples/Song.js +7 -0
- data/spec/api/javascript_processor_spec.rb +6 -3
- data/spec/concerns/api_path_spec.rb +1 -1
- data/spec/concerns/association_extensions_spec.rb +7 -3
- data/spec/concerns/attr_accessor_with_default_spec.rb +1 -1
- data/spec/concerns/code_identifier_spec.rb +1 -1
- data/spec/concerns/export_associations_spec.rb +1 -1
- data/spec/concerns/export_methods_spec.rb +1 -14
- data/spec/concerns/export_scope_spec.rb +7 -9
- data/spec/concerns/exported_limits_spec.rb +1 -1
- data/spec/concerns/pub_sub_spec.rb +1 -1
- data/spec/concerns/set_attribute_data_spec.rb +16 -24
- data/spec/configuration_spec.rb +1 -1
- data/spec/helpers/lanes-helpers.coffee +61 -0
- data/spec/lanes/data/ModelSpec.coffee +152 -0
- data/spec/lanes/data/PubSubSpec.coffee +21 -0
- data/spec/{client/view → lanes/views}/BaseSpec.coffee +6 -26
- data/spec/numbers_spec.rb +1 -1
- data/spec/strings_spec.rb +1 -1
- data/views/index.erb +3 -10
- data/views/specs.erb +4 -1
- metadata +62 -16
- data/client/lanes/plugins/trigger.coffee +0 -15
- data/client/lanes/workspace/Instance.es6 +0 -64
- data/lib/lanes/concerns/sanitize_api_data.rb +0 -15
- data/spec/api/user_spec.rb +0 -52
- data/spec/fixtures/lanes/users.yml +0 -13
- data/spec/locked_fields_spec.rb +0 -27
- data/spec/role_collection_spec.rb +0 -19
- data/spec/user_role_spec.rb +0 -7
- data/spec/user_spec.rb +0 -53
@@ -1,45 +1,37 @@
|
|
1
|
-
|
1
|
+
require "lanes/spec_helper"
|
2
2
|
|
3
3
|
class SetAttributeDataTest < Lanes::TestCase
|
4
4
|
|
5
5
|
include TestingModels
|
6
|
+
def setup
|
7
|
+
@user = DummyUser.new
|
8
|
+
end
|
6
9
|
|
7
10
|
def test_attribute_access
|
8
11
|
tm = TestModel.new
|
9
|
-
assert tm.setting_attribute_is_allowed?(:name,
|
10
|
-
assert tm.can_write_attributes?({},
|
12
|
+
assert tm.setting_attribute_is_allowed?(:name, @user), "can't access :name"
|
13
|
+
assert tm.can_write_attributes?({}, @user), "Can't write to TestModel"
|
11
14
|
data = { name: 'CASH', number: '1200' }
|
12
|
-
assert_equal( data, TestModel.new.set_attribute_data(data) )
|
15
|
+
assert_equal( data, TestModel.new.set_attribute_data(data,@user) )
|
13
16
|
end
|
14
17
|
|
15
18
|
def test_blacklisting
|
16
|
-
assert TestModel.new.setting_attribute_is_allowed?(:number
|
19
|
+
assert TestModel.new.setting_attribute_is_allowed?(:number,@user)
|
17
20
|
TestModel.send :blacklist_attributes, :number
|
18
21
|
assert_includes TestModel.blacklisted_attributes, :number
|
19
|
-
refute TestModel.new.setting_attribute_is_allowed?(:number,
|
20
|
-
record = TestModel.from_attribute_data({ name: 'CASH', number: '1234'})
|
22
|
+
refute TestModel.new.setting_attribute_is_allowed?(:number, @user), "Allowed setting blacklisted attribute"
|
23
|
+
record = TestModel.from_attribute_data({ name: 'CASH', number: '1234'}, @user)
|
21
24
|
assert_nil record.number
|
22
25
|
end
|
23
26
|
|
24
27
|
def test_whitelisting
|
25
|
-
refute TestModel.new.setting_attribute_is_allowed?('updated_at',
|
28
|
+
refute TestModel.new.setting_attribute_is_allowed?('updated_at', @user)
|
26
29
|
TestModel.send :whitelist_attributes, :updated_at
|
27
|
-
assert TestModel.new.setting_attribute_is_allowed?('updated_at',
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_recursive_cleaning_belongs_to
|
31
|
-
assert TestModel.has_exported_association?( :bt, admin )
|
32
|
-
data = { name: 'testing', bt: { description: 'childish', secret_field: 'dr evil' } }
|
33
|
-
record = TestModel.new
|
34
|
-
cleaned = record.set_attribute_data(data)
|
35
|
-
assert_equal( { name: 'testing', bt:{ description: 'childish' } }, cleaned)
|
36
|
-
assert record.bt
|
37
|
-
assert_equal 'childish', record.bt.description
|
38
|
-
assert_nil record.bt.secret_field
|
30
|
+
assert TestModel.new.setting_attribute_is_allowed?('updated_at', @user)
|
39
31
|
end
|
40
32
|
|
41
33
|
def test_recursive_cleaning_has_many
|
42
|
-
assert TestModel.has_exported_association?( :hm,
|
34
|
+
assert TestModel.has_exported_association?( :hm, @user )
|
43
35
|
data = {
|
44
36
|
name: 'testing',
|
45
37
|
hm: [
|
@@ -47,7 +39,7 @@ class SetAttributeDataTest < Lanes::TestCase
|
|
47
39
|
{ description: 'childish-2', secret_field: 'dr evil' }
|
48
40
|
]}
|
49
41
|
record = TestModel.new
|
50
|
-
cleaned_data = record.set_attribute_data(data)
|
42
|
+
cleaned_data = record.set_attribute_data(data,@user)
|
51
43
|
assert_equal 2, record.hm.length
|
52
44
|
assert_equal cleaned_data, {:name=>"testing", :hm=>[{:description=>"childish-1"}, {:description=>"childish-2"}]}
|
53
45
|
assert_saves record
|
@@ -56,10 +48,10 @@ class SetAttributeDataTest < Lanes::TestCase
|
|
56
48
|
def test_sending_to_method
|
57
49
|
tm = TestModel.new
|
58
50
|
def tm.meaning_of_life=(var); @setting = var end
|
59
|
-
tm.set_attribute_data({ meaning_of_life: 42 })
|
51
|
+
tm.set_attribute_data({ meaning_of_life: 42 }, @user)
|
60
52
|
assert_nil tm.instance_variable_get(:@setting)
|
61
53
|
TestModel.send :whitelist_attributes, :meaning_of_life
|
62
|
-
tm.set_attribute_data({ meaning_of_life: 42 })
|
54
|
+
tm.set_attribute_data({ meaning_of_life: 42 }, @user)
|
63
55
|
assert_equal 42, tm.instance_variable_get(:@setting)
|
64
56
|
end
|
65
57
|
|
data/spec/configuration_spec.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
Lanes.namespace 'Testing'
|
2
|
+
|
3
|
+
class Lanes.Testing.View extends Lanes.Views.Base
|
4
|
+
template: "<p>hi</p"
|
5
|
+
events: { "click #mylink": 'onClick' }
|
6
|
+
onClick: Lanes.emptyFn
|
7
|
+
|
8
|
+
Lanes.Vendor.MessageBus = {
|
9
|
+
subscribe: jasmine.createSpy('subscribe')
|
10
|
+
unsubscribe: jasmine.createSpy('unsubscribe')
|
11
|
+
start: Lanes.emptyFn
|
12
|
+
}
|
13
|
+
|
14
|
+
class Lanes.Testing.Model extends Lanes.Data.Model
|
15
|
+
api_path: "test"
|
16
|
+
props:
|
17
|
+
id: 'number',
|
18
|
+
name: ['string', true],
|
19
|
+
html: 'string',
|
20
|
+
url: 'string',
|
21
|
+
something: 'string',
|
22
|
+
fireDanger: 'string'
|
23
|
+
|
24
|
+
session:
|
25
|
+
active: 'boolean'
|
26
|
+
|
27
|
+
derived:
|
28
|
+
classes:
|
29
|
+
deps: ['something', 'fireDanger', 'active'],
|
30
|
+
fn: -> this.something + this.active;
|
31
|
+
|
32
|
+
class Lanes.Testing.Collection extends Lanes.Data.Collection
|
33
|
+
model: Lanes.Testing.Model
|
34
|
+
|
35
|
+
syncResponse = (method,model,options)->
|
36
|
+
if options.success && syncReply.success
|
37
|
+
options.success(model, syncReply, {})
|
38
|
+
if options.failure && !syncReply.success
|
39
|
+
options.failure(model, syncReply, {})
|
40
|
+
|
41
|
+
syncReply = {}
|
42
|
+
|
43
|
+
window.syncSucceedWith = (data)->
|
44
|
+
syncReply.success = true
|
45
|
+
syncReply.data = data
|
46
|
+
|
47
|
+
beforeEach ->
|
48
|
+
|
49
|
+
syncReply = {
|
50
|
+
success: true
|
51
|
+
message: ''
|
52
|
+
data: {}
|
53
|
+
}
|
54
|
+
|
55
|
+
Lanes.Testing.syncSpy = jasmine.createSpy('sync').and.callFake(syncResponse)
|
56
|
+
Lanes.Testing.syncSpy.lastOptions = ->
|
57
|
+
this.calls.mostRecent().args[2]
|
58
|
+
Lanes.Data.Model::sync = Lanes.Testing.syncSpy
|
59
|
+
Lanes.Data.Collection::sync = Lanes.Testing.syncSpy
|
60
|
+
|
61
|
+
|
@@ -0,0 +1,152 @@
|
|
1
|
+
|
2
|
+
describe "Model Suite", ->
|
3
|
+
Model = undefined
|
4
|
+
Collection = undefined
|
5
|
+
class Color
|
6
|
+
constructor: -> super
|
7
|
+
props: { id: 'integer', rgb: 'string' }
|
8
|
+
Lanes.Data.Model.extend(Color)
|
9
|
+
|
10
|
+
makeModel = (props,args={})->
|
11
|
+
_.extend(Model.prototype, props)
|
12
|
+
Lanes.Data.Model.extend(Model)
|
13
|
+
Collection::model = Model
|
14
|
+
Lanes.Data.Collection.extend(Collection)
|
15
|
+
collection = new Collection
|
16
|
+
return collection.add(new Model(args))
|
17
|
+
|
18
|
+
beforeEach ->
|
19
|
+
class TestModel
|
20
|
+
constructor: -> super
|
21
|
+
Model = TestModel
|
22
|
+
class TestCollection
|
23
|
+
constructor: -> super
|
24
|
+
Collection = TestCollection
|
25
|
+
|
26
|
+
|
27
|
+
it "tracks unsaved attributes", ->
|
28
|
+
model = makeModel({
|
29
|
+
session:
|
30
|
+
foo: 'string'
|
31
|
+
bar: 'integer'
|
32
|
+
props:
|
33
|
+
saved: 'string'
|
34
|
+
}, {bar: 'baz'})
|
35
|
+
expect(model.isDirty()).toBeFalse()
|
36
|
+
model.foo = 'baz' # session prop
|
37
|
+
expect(model.isDirty()).toBeFalse()
|
38
|
+
expect(model.unsavedData()).toBeEmptyObject()
|
39
|
+
model.set( saved: 'true' )
|
40
|
+
expect(model.isDirty()).toBeTrue()
|
41
|
+
|
42
|
+
|
43
|
+
it "can tell if it has attributes", ->
|
44
|
+
model = makeModel({
|
45
|
+
session:
|
46
|
+
foo: 'string'
|
47
|
+
props:
|
48
|
+
bar: 'string'
|
49
|
+
})
|
50
|
+
expect(model.hasAttribute('missing')).toBeFalse()
|
51
|
+
expect(model.hasAttribute('foo')).toBeTrue()
|
52
|
+
expect(model.hasAttribute('bar')).toBeTrue()
|
53
|
+
|
54
|
+
it "provides data for saving", ->
|
55
|
+
# model with other types of data, but should only save "props"
|
56
|
+
model = makeModel({
|
57
|
+
associations:
|
58
|
+
color:{ model: Color }
|
59
|
+
session:
|
60
|
+
unsaved: 'string'
|
61
|
+
props:
|
62
|
+
id: 'integer'
|
63
|
+
foo: 'string'
|
64
|
+
bar: 'string'
|
65
|
+
derived:
|
66
|
+
atest:
|
67
|
+
fn: -> 'blarg'
|
68
|
+
|
69
|
+
})
|
70
|
+
model.set( id: 10, unsaved: 'falsify', color: { rgb: '99FFFF' } )
|
71
|
+
|
72
|
+
expect( model.dataForSave() ).toEqual( id: 10, color: { rgb: '99FFFF' } )
|
73
|
+
model.foo = 'a value'
|
74
|
+
a=model.changeMonitor.changedAttributes()
|
75
|
+
expect( model.dataForSave() ).toEqual( id: 10, foo: 'a value', color: { rgb: '99FFFF' } )
|
76
|
+
|
77
|
+
it "can be saved", ->
|
78
|
+
model = makeModel({
|
79
|
+
props:
|
80
|
+
id: 'integer'
|
81
|
+
foo: 'string'
|
82
|
+
bar: 'string'
|
83
|
+
|
84
|
+
}, { foo: 'one, two, three'} )
|
85
|
+
expect(model.isDirty()).toBeTrue()
|
86
|
+
expect(model.unsavedData()).toEqual( foo: 'one, two, three' )
|
87
|
+
model.save()
|
88
|
+
expect(model.sync).toHaveBeenCalledWith('create', model, jasmine.any(Object))
|
89
|
+
model.id=11
|
90
|
+
expect(model.isNew()).toBeFalse()
|
91
|
+
model.sync.calls.reset()
|
92
|
+
syncSucceedWith({
|
93
|
+
foo: 'a new foo value'
|
94
|
+
})
|
95
|
+
model.save()
|
96
|
+
expect(model.sync).toHaveBeenCalledWith('patch', model, jasmine.any(Object))
|
97
|
+
expect(model.foo).toEqual('a new foo value')
|
98
|
+
|
99
|
+
it "can be fetched",->
|
100
|
+
model = makeModel({
|
101
|
+
props:
|
102
|
+
{ id: 'integer', foo: 'string' }
|
103
|
+
})
|
104
|
+
syncSucceedWith({
|
105
|
+
foo: 'foo value'
|
106
|
+
})
|
107
|
+
model.fetch()
|
108
|
+
expect(model.sync).toHaveBeenCalledWith('read', model, jasmine.any(Object))
|
109
|
+
expect(model.foo).toEqual('foo value')
|
110
|
+
options = model.sync.lastOptions()
|
111
|
+
expect(options).toHaveTrue('ignoreUnsaved')
|
112
|
+
expect(options).toHaveNumberWithinRange('limit',1,1)
|
113
|
+
|
114
|
+
|
115
|
+
it "can be destroyed", ->
|
116
|
+
model = makeModel({
|
117
|
+
props: { id: 'integer' }
|
118
|
+
},{ id: 1 })
|
119
|
+
collection = model.collection
|
120
|
+
expect(collection.length).toEqual(1)
|
121
|
+
model.destroy()
|
122
|
+
expect(model.sync)
|
123
|
+
.toHaveBeenCalledWith('delete', model, jasmine.any(Object))
|
124
|
+
expect(collection.length).toEqual(0)
|
125
|
+
|
126
|
+
it "sets associations", ->
|
127
|
+
model = makeModel({
|
128
|
+
associations:
|
129
|
+
color:{ model: Color }
|
130
|
+
props: { id: 'integer', foo: 'string' }
|
131
|
+
},{ id: 1 })
|
132
|
+
expect(model.color).toBeObject()
|
133
|
+
model.set(color: { rgb: '99FFFF' })
|
134
|
+
expect(model.color.rgb).toEqual('99FFFF')
|
135
|
+
model.setFromResponse(color:{ rgb: 'FFA500' })
|
136
|
+
expect(model.color.rgb).toEqual('FFA500')
|
137
|
+
|
138
|
+
it "can fetch associations", ->
|
139
|
+
model = makeModel({
|
140
|
+
associations:
|
141
|
+
color:{ model: Color }
|
142
|
+
props: { id: 'integer', foo: 'string' }
|
143
|
+
},{ id: 1 })
|
144
|
+
model.withAssociations('color')
|
145
|
+
expect(model.sync).toHaveBeenCalledWith('read', model, jasmine.any(Object))
|
146
|
+
options = model.sync.lastOptions()
|
147
|
+
expect(options.include).toEqual(['color'])
|
148
|
+
|
149
|
+
it "assigns an inverse collection property", ->
|
150
|
+
model = makeModel({})
|
151
|
+
expect(Model::Collection).toEqual(Collection)
|
152
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
describe "PubSub Suite", ->
|
3
|
+
|
4
|
+
it "checks in/out a model when it binds to a view", ->
|
5
|
+
view = new Lanes.Testing.View
|
6
|
+
model = new Lanes.Testing.Model(id:1)
|
7
|
+
spyOn(Lanes.Data.PubSub,'add').and.callThrough()
|
8
|
+
spyOn(Lanes.Data.PubSub,'remove')
|
9
|
+
view.model = model
|
10
|
+
expect(Lanes.Data.PubSub.add).toHaveBeenCalledWith(model)
|
11
|
+
expect(Lanes.Vendor.MessageBus.subscribe)
|
12
|
+
.toHaveBeenCalledWith("/test/1", jasmine.any(Function))
|
13
|
+
view.unset('model')
|
14
|
+
expect(Lanes.Data.PubSub.remove).toHaveBeenCalledWith(model)
|
15
|
+
|
16
|
+
it "can retrieve a model after checkin", ->
|
17
|
+
model = new Lanes.Testing.Model(id: 11, name:'bar')
|
18
|
+
Lanes.Data.PubSub.add(model)
|
19
|
+
checkin = Lanes.Data.PubSub.instanceFor(Lanes.Testing.Model, 11)
|
20
|
+
expect(checkin).toEqual(model)
|
21
|
+
|
@@ -1,23 +1,4 @@
|
|
1
1
|
|
2
|
-
class Model extends Lanes.Data.Model
|
3
|
-
props:
|
4
|
-
id: 'number',
|
5
|
-
name: ['string', true],
|
6
|
-
html: 'string',
|
7
|
-
url: 'string',
|
8
|
-
something: 'string',
|
9
|
-
fireDanger: 'string'
|
10
|
-
|
11
|
-
session:
|
12
|
-
active: 'boolean'
|
13
|
-
|
14
|
-
derived:
|
15
|
-
classes:
|
16
|
-
deps: ['something', 'fireDanger', 'active'],
|
17
|
-
fn: -> this.something + this.active;
|
18
|
-
|
19
|
-
class Collection extends Lanes.Data.Collection
|
20
|
-
model: Model
|
21
2
|
|
22
3
|
describe "BaseView Suite", ->
|
23
4
|
View = undefined
|
@@ -40,7 +21,6 @@ describe "BaseView Suite", ->
|
|
40
21
|
view.render()
|
41
22
|
expect(spy).toHaveBeenCalled()
|
42
23
|
|
43
|
-
|
44
24
|
it "renders a template string", ->
|
45
25
|
view = makeView({
|
46
26
|
template: "<p>hi</p"
|
@@ -64,7 +44,7 @@ describe "BaseView Suite", ->
|
|
64
44
|
expect(spy).toHaveBeenCalledWith(jasmine.any(Object),22)
|
65
45
|
|
66
46
|
it "updates from bindings", ->
|
67
|
-
model = new Model({ name: "Bob" })
|
47
|
+
model = new Lanes.Testing.Model({ name: "Bob" })
|
68
48
|
view = makeView({
|
69
49
|
bindings: {
|
70
50
|
"model.name": { hook: 'link' }
|
@@ -85,7 +65,7 @@ describe "BaseView Suite", ->
|
|
85
65
|
constructor: -> super
|
86
66
|
session: { answer: 'string' }
|
87
67
|
Lanes.Views.Base.extend(LowerView)
|
88
|
-
model = new Model
|
68
|
+
model = new Lanes.Testing.Model
|
89
69
|
view = makeView({
|
90
70
|
subviews:
|
91
71
|
lower:
|
@@ -108,7 +88,7 @@ describe "BaseView Suite", ->
|
|
108
88
|
constructor: -> super
|
109
89
|
bindings: { "model.name": { type: "text" } }
|
110
90
|
Lanes.Views.Base.extend(LowerView)
|
111
|
-
collection = new Collection
|
91
|
+
collection = new Lanes.Testing.Collection
|
112
92
|
view = makeView({
|
113
93
|
subviews:
|
114
94
|
lower:
|
@@ -141,7 +121,7 @@ describe "BaseView Suite", ->
|
|
141
121
|
it "invokes model events", ->
|
142
122
|
nameSpy = jasmine.createSpy()
|
143
123
|
urlSpy = jasmine.createSpy()
|
144
|
-
model = new Model
|
124
|
+
model = new Lanes.Testing.Model
|
145
125
|
view = makeView({
|
146
126
|
modelEvents:
|
147
127
|
'change:name': nameSpy
|
@@ -159,8 +139,8 @@ describe "BaseView Suite", ->
|
|
159
139
|
collectionEvents:
|
160
140
|
all: 'onEvent'
|
161
141
|
onEvent: eventSpy
|
162
|
-
initialize: -> this.collection = new Collection
|
142
|
+
initialize: -> this.collection = new Lanes.Testing.Collection
|
163
143
|
})
|
164
144
|
expect(eventSpy).not.toHaveBeenCalled()
|
165
|
-
view.collection.add(new Model)
|
145
|
+
view.collection.add(new Lanes.Testing.Model)
|
166
146
|
expect(eventSpy).toHaveBeenCalled()
|
data/spec/numbers_spec.rb
CHANGED
data/spec/strings_spec.rb
CHANGED
data/views/index.erb
CHANGED
@@ -5,21 +5,14 @@
|
|
5
5
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui"/>
|
7
7
|
<title><%= Lanes.config.app_title %></title>
|
8
|
-
<%=
|
9
|
-
<%=
|
8
|
+
<%= lanes_javascript_tag %>
|
9
|
+
<%= lanes_stylesheet_tag %>
|
10
10
|
<script type="text/javascript">
|
11
|
-
|
12
|
-
csrf_token: "<%= csrf_token %>",
|
13
|
-
view: "<%= Lanes.config.root_view %>",
|
14
|
-
root_path: "<%= lanes_api_url %>"
|
15
|
-
}, <%= client_bootstrap_data %> );
|
11
|
+
Lanes.renderScreenTo('body', <%= client_bootstrap_data %> );
|
16
12
|
</script>
|
17
13
|
</head>
|
18
14
|
|
19
15
|
<body>
|
20
16
|
|
21
|
-
<div class="lanes-root">
|
22
|
-
</div>
|
23
|
-
|
24
17
|
</body>
|
25
18
|
</html>
|