lanes 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/client/lanes/Config.coffee +1 -1
  4. data/client/lanes/access/LoginDialog.cjsx +1 -1
  5. data/client/lanes/access/Roles.coffee +1 -1
  6. data/client/lanes/access/User.coffee +2 -2
  7. data/client/lanes/access/screens/user-management/UserManagement.cjsx +1 -1
  8. data/client/lanes/components/calendar/styles.scss +1 -1
  9. data/client/lanes/components/grid/Body.cjsx +5 -2
  10. data/client/lanes/components/grid/EditingMixin.cjsx +3 -0
  11. data/client/lanes/components/grid/Editor.cjsx +3 -11
  12. data/client/lanes/components/grid/Grid.cjsx +22 -12
  13. data/client/lanes/components/grid/Selections.cjsx +4 -1
  14. data/client/lanes/components/grid/Toolbar.cjsx +1 -1
  15. data/client/lanes/components/record-finder/RecordFinder.cjsx +2 -2
  16. data/client/lanes/components/select-field/SelectField.cjsx +19 -16
  17. data/client/lanes/components/select-field/styles.scss +1 -1
  18. data/client/lanes/components/shared/FieldMixin.cjsx +2 -2
  19. data/client/lanes/components/shared/Input.cjsx +2 -13
  20. data/client/lanes/components/shared/InputFieldMixin.cjsx +15 -8
  21. data/client/lanes/components/shared/NetworkActivityOverlay.cjsx +1 -1
  22. data/client/lanes/components/shared/NumberInput.cjsx +4 -12
  23. data/client/lanes/components/shared/ToggleField.cjsx +0 -2
  24. data/client/lanes/components/shared/fields.scss +9 -0
  25. data/client/lanes/components/shared/styles.scss +2 -1
  26. data/client/lanes/components/toolbar/Toolbar.cjsx +1 -1
  27. data/client/lanes/lib/HotReload.coffee +2 -2
  28. data/client/lanes/lib/development.coffee +1 -1
  29. data/client/lanes/lib/loader.coffee +3 -3
  30. data/client/lanes/models/AssociationMap.coffee +1 -1
  31. data/client/lanes/models/AssociationProxy.coffee +1 -0
  32. data/client/lanes/models/Base.coffee +7 -10
  33. data/client/lanes/models/Collection.coffee +3 -6
  34. data/client/lanes/models/JobStatus.coffee +1 -1
  35. data/client/lanes/models/PubSub.coffee +51 -33
  36. data/client/lanes/models/Query.coffee +1 -1
  37. data/client/lanes/models/Sync.coffee +1 -1
  38. data/client/lanes/models/User.coffee +3 -3
  39. data/client/lanes/models/mixins/FileSupport.coffee +3 -3
  40. data/client/lanes/models/query/ArrayResult.coffee +3 -6
  41. data/client/lanes/models/query/CollectionResult.coffee +5 -3
  42. data/client/lanes/react/Component.coffee +2 -2
  43. data/client/lanes/react/DefaultComponentNotFound.cjsx +2 -2
  44. data/client/lanes/react/Screen.coffee +1 -1
  45. data/client/lanes/react/Viewport.coffee +1 -1
  46. data/client/lanes/react/mixins/Access.coffee +1 -1
  47. data/client/lanes/react/mixins/Data.coffee +9 -5
  48. data/client/lanes/screens/Commands.coffee +1 -1
  49. data/client/lanes/screens/UserPreferences.cjsx +1 -1
  50. data/client/lanes/testing/BeforeEach.coffee +7 -0
  51. data/client/lanes/vendor/base.js.erb +5 -0
  52. data/client/lanes/vendor/calendar.js.erb +5 -0
  53. data/client/lanes/vendor/commons.js.erb +5 -0
  54. data/client/lanes/vendor/{base.js → development/base.js} +37776 -40850
  55. data/client/lanes/vendor/development/calendar.js +1667 -0
  56. data/client/lanes/vendor/development/commons.js +39085 -0
  57. data/client/lanes/vendor/development/helpers.js +578 -0
  58. data/client/lanes/vendor/{toggle.js → development/toggle.js} +22 -82
  59. data/client/lanes/vendor/development/widgets.js +8975 -0
  60. data/client/lanes/vendor/production/base.js +63239 -0
  61. data/client/lanes/vendor/production/calendar.js +1667 -0
  62. data/client/lanes/vendor/production/commons.js +38505 -0
  63. data/client/lanes/vendor/production/toggle.js +285 -0
  64. data/client/lanes/vendor/production/widgets.js +8975 -0
  65. data/client/lanes/vendor/{calendar.scss → styles/calendar.scss} +6 -0
  66. data/client/lanes/vendor/{toggle.scss → styles/toggle.scss} +0 -0
  67. data/client/lanes/vendor/{widgets.scss → styles/widgets.scss} +2 -2
  68. data/client/lanes/vendor/toggle.js.erb +5 -0
  69. data/client/lanes/vendor/widgets.js.erb +5 -0
  70. data/lib/lanes/api/default_routes.rb +3 -3
  71. data/lib/lanes/api/routing.rb +1 -1
  72. data/lib/lanes/configuration.rb +8 -14
  73. data/lib/lanes/environment.rb +3 -0
  74. data/lib/lanes/extension/definition.rb +4 -0
  75. data/lib/lanes/system_settings.rb +21 -6
  76. data/lib/lanes/version.rb +1 -1
  77. data/npm-build/base.js +9 -4
  78. data/npm-build/build +9 -0
  79. data/npm-build/development.js +3 -1
  80. data/npm-build/package.json +34 -34
  81. data/npm-build/update-dayz +1 -1
  82. data/npm-build/webpack.config.js +36 -20
  83. data/spec/command-reference-files/initial/Gemfile +1 -1
  84. data/spec/command-reference-files/screen/config/screens.rb +1 -1
  85. data/spec/lanes/components/grid/RowEditorSpec.coffee +3 -1
  86. data/spec/lanes/components/select-field/SelectFieldSpec.coffee +33 -28
  87. data/spec/lanes/models/AssociationProxySpec.coffee +36 -37
  88. data/spec/lanes/models/BaseSpec.coffee +0 -32
  89. data/spec/lanes/models/CollectionSpec.coffee +0 -10
  90. data/spec/lanes/models/PubSubSpec.coffee +63 -13
  91. data/spec/lanes/screens/DefinitionsSpec.coffee +2 -2
  92. metadata +23 -20
  93. data/client/lanes/vendor/calendar.js +0 -17301
  94. data/client/lanes/vendor/commons.js +0 -19722
  95. data/client/lanes/vendor/development.js +0 -5471
  96. data/client/lanes/vendor/grid.js +0 -15384
  97. data/client/lanes/vendor/grid.scss +0 -928
  98. data/client/lanes/vendor/rw-widgets.eot +0 -0
  99. data/client/lanes/vendor/rw-widgets.svg +0 -18
  100. data/client/lanes/vendor/rw-widgets.ttf +0 -0
  101. data/client/lanes/vendor/rw-widgets.woff +0 -0
  102. data/client/lanes/vendor/widgets.js +0 -23204
  103. data/npm-build/compile.coffee +0 -19
  104. data/spec/lanes/models/ServerCacheSpec.coffee +0 -65
@@ -28,10 +28,11 @@ RenderEdit = (q, value) ->
28
28
  editor = Lanes.Test.Utils.findRenderedComponentWithType(
29
29
  grid, Lanes.Components.Grid.RowEditor
30
30
  )
31
- _.dom(editor).qs('.field:nth-of-type(2) input').setValue(value)
31
+ _.dom(editor).qs('.field:nth-of-type(2) input').change(target: {value})
32
32
  res({grid, editor})
33
33
 
34
34
 
35
+
35
36
  CommonSpecs = ->
36
37
 
37
38
  it 'sets the props', (done) ->
@@ -53,6 +54,7 @@ CommonSpecs = ->
53
54
  done()
54
55
 
55
56
  it 'does not update when edit is canceled', (done) ->
57
+ expect( @query.results.rowAt(1)[1] ).toEqual('TEST2')
56
58
  RenderEdit(@query, 'CANCKED').then ({editor}) =>
57
59
  _.dom(editor).qs('.btn.cancel').click()
58
60
  expect( @query.results.rowAt(1)[1] ).toEqual('TEST2')
@@ -42,58 +42,63 @@ describe "Lanes.Components.SelectField", ->
42
42
  editOnly: true, collection: @brands })
43
43
  expect(_.dom(sf).qs('input[type=text]').value).toEqual('Ford Motor Co.')
44
44
 
45
- it 'uses a custom data source', ->
45
+ it 'uses a custom data source', (done) ->
46
46
  sf = LT.renderComponent(LC.SelectField, props:{
47
47
  model: @car, name: 'brand', editOnly: true
48
- getSelection: -> { label: 'Toyota', id: 4 }
48
+ value: 4, choices: [{ label: 'Toyota', id: 4 }]
49
49
  })
50
- expect(_.dom(sf).qs('input[type=text]').value).toEqual('Toyota')
50
+ _.defer ->
51
+ expect(_.dom(sf).qs('input[type=text]').value).toEqual('Toyota')
52
+ done()
51
53
 
52
54
  it 'sets value when changed', ->
53
55
  @car.set(brand: @brands.at(1))
54
56
  sf = LT.renderComponent(LC.SelectField, props:{
55
- model: @car, name: 'brand', labelField: 'name', editOnly: true, collection: @brands
57
+ model: @car, name: 'brand', labelField: 'name',
58
+ fetchOnSelect: false, editOnly: true, choices: @brands.models
56
59
  })
57
60
  _.dom(sf).qs('.rw-select').click()
58
- _.dom(sf).qs('li.rw-list-option:last-child').click()
61
+ _.dom(sf).qs('.rw-list li:last-child').click()
59
62
  expect(@car.brand.code).toEqual('DODGE')
60
63
 
61
- it 'can select multiple values', ->
64
+ it 'can select multiple values', (done) ->
62
65
  sf = LT.renderComponent(LC.SelectField, props:{
63
- multi: true, model: @car, name: 'carTypes',
64
- labelField: 'name', editOnly: true, collection: @brands
66
+ queryModel: Car,
67
+ multiSelect: true, model: @car, name: 'carTypes', fetchOnSelect: false
68
+ labelField: 'name', editOnly: true, choices: @brands.models
65
69
  })
66
- spyOn(@brands, 'fetch').and.callThrough()
67
- _.dom(sf).qs('.rw-input').focus()
68
- expect(@brands.fetch).toHaveBeenCalled()
69
70
 
70
- expect( _.dom(sf).qsa('.rw-list-option').length ).toEqual(@brands.length)
71
- _.dom(sf).qs('.rw-list-option:nth-child(1)').click()
72
71
  _.dom(sf).qs('.rw-input').focus()
73
- _.dom(sf).qs('.rw-list-option:nth-child(3)').click()
74
- expect(_.pluck(@car.carTypes, 'id')).toEqual([1, 3])
72
+ _.defer =>
73
+ expect( _.dom(sf).qsa('.rw-list li').length ).toEqual(@brands.length)
74
+ _.dom(sf).qs('.rw-list-option:nth-child(1)').click()
75
+ _.dom(sf).qs('.rw-input').focus()
76
+ _.dom(sf).qs('.rw-list-option:nth-child(2)').click()
77
+ expect(_.map(@car.carTypes, 'id')).toEqual([1, 3])
78
+ done()
79
+
80
+ it 'renders label for single values', ->
81
+ @car.set(brand: @brands.last())
82
+ sf = LT.renderComponent(LC.SelectField, props:{
83
+ model: @car, name: 'brand', labelField: 'name',
84
+ choices: @brands.models
85
+ })
86
+ expect(_.dom(sf).qs('.value').text).toEqual('Chrysler/Dodge')
75
87
 
76
88
  it 'renders label for multiple values', ->
77
89
  @car.carTypes = [ @brands.at(0), @brands.at(2) ]
78
90
  sf = LT.renderComponent(LC.SelectField, props:{
79
- multi: true, model: @car, name: 'carTypes',
80
- labelField: 'name', collection: @brands
91
+ queryModel: Car, multiSelect: true, model: @car, name: 'carTypes'
92
+ labelField: 'name', choices: @brands.models
81
93
  })
82
94
  expect(_.dom(sf).qs('.value').text).toEqual('General Motors and Chrysler/Dodge')
83
95
 
96
+
84
97
  it "renders all choices", ->
85
98
  sf = LT.renderComponent(LC.SelectField, props:{
86
- model: @car, name: 'brand', labelField: 'name', editOnly: true, collection: @brands
99
+ queryModel: Car, model: @car, name: 'brand', labelField: 'name',
100
+ editOnly: true, choices: @brands.models
87
101
  })
88
102
  _.dom(sf).qs('.rw-select').click()
89
- labels = _.pluck _.dom(sf).qsa('li.rw-list-option'), 'textContent'
103
+ labels = _.map _.dom(sf).qsa('li.rw-list-option'), 'textContent'
90
104
  expect(labels).toEqual(["General Motors", "Ford Motor Co.", "Chrysler/Dodge"])
91
-
92
- it "can render a blank row", ->
93
- sf = LT.renderComponent(LC.SelectField, props:{
94
- includeBlankRow: true, model: @car, name: 'brand',
95
- labelField: 'name', editOnly: true, collection: @brands
96
- })
97
- _.dom(sf).qs('.rw-select').click()
98
- labels = _.pluck _.dom(sf).qsa('li.rw-list-option'), 'textContent'
99
- expect(labels).toEqual(["---------", "General Motors", "Ford Motor Co.", "Chrysler/Dodge"])
@@ -1,9 +1,12 @@
1
1
  describe "Lanes.Models.AssocationProxy", ->
2
2
 
3
+
3
4
  class Color
4
5
  constructor: -> super
5
6
  api_path: -> 'test'
6
7
  props: { id: 'integer', model_fk_id: 'integer', rgb: 'string' }
8
+ derived:
9
+ rgba: { fn: -> @rgb + 'ff' }
7
10
  testFunc: (arg) -> @rgb = arg
8
11
  Lanes.Models.Base.extend(Color)
9
12
 
@@ -12,66 +15,62 @@ describe "Lanes.Models.AssocationProxy", ->
12
15
  associations:
13
16
  color:{ model: Color }
14
17
  colors: { collection: Color, fk: 'model_fk_id' }
15
- props: { id: 'integer', property: 'string' }
18
+ props:
19
+ id: 'integer'
20
+ color_id: 'integer'
21
+ property: 'string'
16
22
  session: { session: 'string' }
17
- derived:
18
- dr: { fn: -> 'dr' }
19
23
  })
20
- @Proxy = Lanes.Models.AssocationProxy.construct(@Model)
24
+ @instance = new @Model
21
25
 
22
26
  it "proxies the associations with other proxies", ->
23
- instance = new @Proxy
24
- expect(instance.color.isProxy).toBe(true)
25
- expect(instance.color.id).toBeNull()
27
+ expect(@instance.color.isProxy).toBe(true)
28
+ expect(@instance.color.id).toBeUndefined()
29
+ @instance.color_id = 42
30
+ expect(@instance.color.id).toEqual(42)
31
+ expect(@instance.color.isProxy).toBe(true)
26
32
 
27
33
  it 'can create a real association and return it if needed', ->
28
- instance = new @Proxy
29
- expect(instance.color.isProxy).toBe(true)
30
- instance.color.rgb = 'foo'
31
- expect(instance.color.isProxy).toBeUndefined()
32
- expect(instance.color).toEqual(jasmine.any(Color))
34
+ @instance.color.rgb = 'foo'
35
+ expect(@instance.color.isProxy).toBeUndefined()
36
+ expect(@instance.color).toEqual(jasmine.any(Color))
33
37
 
34
38
  it 'can proxy derived properties', ->
35
- instance = new @Proxy
36
- expect(instance.dr).toBeNull()
39
+ expect(@instance.color.rgb).toBeNull()
37
40
 
38
41
  it 'raises error when writing to derived properties', ->
39
- instance = new @Proxy
40
- expect(->
41
- instance.dr = 'foo'
42
+ expect(=>
43
+ @instance.color.rgba = 'foo'
42
44
  ).toThrowError(TypeError)
43
45
 
44
46
  it 'instantiates and forwards function calls', ->
45
- instance = new @Proxy
46
- instance.color.testFunc('1234')
47
- expect(instance.color).toEqual(jasmine.any(Color))
48
- expect(instance.color.rgb).toEqual('1234')
47
+ @instance.color.testFunc('1234')
48
+ expect(@instance.color).toEqual(jasmine.any(Color))
49
+ expect(@instance.color.rgb).toEqual('1234')
49
50
 
50
51
  it 'intercepts dataForSave', ->
51
- instance = new @Proxy
52
- instance.color.rgb = 'mycolor'
53
- expect(instance.dataForSave()).toEqual(color: {rgb: 'mycolor'})
52
+ @instance.color.rgb = 'mycolor'
53
+ expect(@instance.color.dataForSave()).toEqual({rgb: 'mycolor'})
54
54
 
55
55
  it 'provides api_key', ->
56
- instance = new @Proxy
57
- expect(instance.api_path()).toEqual('/s')
56
+ expect(@instance.color.api_path()).toEqual('test')
58
57
 
59
58
  it 'stores events and eventually sets them on model', ->
60
59
  spy1 = jasmine.createSpy()
61
60
  spy2 = jasmine.createSpy()
62
- instance = new @Proxy
63
- instance.color.on('change:rgb', spy1)
64
- instance.color.once('change:rgb', spy2)
65
- expect(instance.color.isProxy).toBe(true)
66
- instance.color.rgb = 'newcolor'
67
- expect(instance.color.isProxy).toBeUndefined()
61
+
62
+ @instance.color.on('change:rgb', spy1)
63
+ @instance.color.once('change:rgb', spy2)
64
+ expect(@instance.color.isProxy).toBe(true)
65
+ @instance.color.rgb = 'newcolor'
66
+ expect(@instance.color.isProxy).toBeUndefined()
68
67
 
69
68
  expect(spy1).toHaveBeenCalled()
70
69
  expect(spy2).toHaveBeenCalled()
71
70
 
72
- it 'fires onreplace', ->
73
- spy = jasmine.createSpy()
74
- instance = new @Proxy
75
- instance.on('proxyreplace', spy)
76
- instance.session = 'foo'
71
+ it 'fires proxyreplace event', ->
72
+ spy = jasmine.createSpy('proxyreplace')
73
+ @instance.color.on('proxyreplace', spy)
74
+ expect(@instance.color.isProxy).toBe(true)
75
+ @instance.color.rgb = 'foo'
77
76
  expect(spy).toHaveBeenCalled()
@@ -153,35 +153,3 @@ describe "Lanes.Models.Base", ->
153
153
  expect(Lanes.Models.Sync.perform).toHaveBeenCalledWith('read', jasmine.any(Object))
154
154
  options = Lanes.Models.Sync.perform.lastOptions()
155
155
  expect(options.include).toEqual(['color'])
156
-
157
- it "can copy attributes from another model", ->
158
- Model = LT.defineModel
159
- props: { id: 'integer', title: 'string' }
160
- associations:
161
- color:{ model: Color }
162
- a = new Model({ id: 23, title: 'Foo', color: { rgb: '123456' } })
163
- b = new Model()
164
- b.copyFrom(a)
165
- expect( b.id ).toEqual(23)
166
- expect( b.title ).toEqual('Foo')
167
- expect( b.color.rgb ).toEqual('123456')
168
-
169
- it 'can copy associations', (done) ->
170
- Model = LT.defineModel
171
- props: { id: 'integer', title: 'string' }
172
- associations:
173
- color:{ model: Color }
174
- colors: { collection: Color, fk: 'model_fk_id' }
175
-
176
- model = new Model(id: 1, title: 'Foo')
177
- model.color.rgb = 'mycolor'
178
- color = model.colors.add({ rgb:'1' })
179
- color = model.colors.add({ rgb:'2' })
180
- color = model.colors.add({ rgb:'3' })
181
-
182
- copy = new Model
183
- copy.copyAssociationsFrom(model, ['color', 'colors']).then ->
184
- expect(copy.color.rgb).toEqual('mycolor')
185
- expect(copy.colors.length).toEqual(3)
186
- expect(copy.colors.pluck('rgb')).toEqual(['1', '2', '3'])
187
- done()
@@ -30,13 +30,3 @@ describe "Lanes.Models.Collection", ->
30
30
  spy.calls.reset()
31
31
  collection.reset([{ id:11, title: 'last'}])
32
32
  expect(spy).toHaveBeenCalled()
33
-
34
- it 'prevents duplicates when copying from', ->
35
- Model = Lanes.Test.defineModel
36
- props: { id: 'integer', title: 'string' }
37
- collection = new Model.Collection
38
- a = collection.add({ id: 1, title: 'first' })
39
- b = collection.add({ id: 2, title: 'second' })
40
- c = collection.add({ id: 3, title: 'third' })
41
- a.copyFrom(c)
42
- expect(collection.pluck('id')).toEqual([2, 3, 1])
@@ -1,23 +1,73 @@
1
1
  describe "Lanes.Model.PubSub", ->
2
2
 
3
+ beforeEach ->
4
+ @Model = Lanes.Test.defineModel({
5
+ props: { id: 'integer', foo: 'string' }
6
+ })
7
+ @model = new @Model({ id: 1, foo: 'bar' })
8
+ @getModelConfig = ->
9
+ Lanes.Models.PubSub.types.get('/s').records[1]
10
+
3
11
  it "checks in/out a model when it binds to a view", ->
4
12
  spyOn(Lanes.Models.PubSub, 'add').and.callThrough()
5
13
  spyOn(Lanes.Models.PubSub, 'remove')
6
- model = Lanes.Test.makeModel({
7
- props: { id: 'integer', foo: 'string' }
8
- }, { id: 1, foo: 'bar' })
9
- component = Lanes.Test.makeComponent({}, model: model)
10
- expect(Lanes.Models.PubSub.add).toHaveBeenCalledWith(model)
14
+ component = Lanes.Test.makeComponent({}, model: @model)
15
+ expect(Lanes.Models.PubSub.add).toHaveBeenCalledWith(@model)
11
16
  component.data.destroy()
12
- expect(Lanes.Models.PubSub.remove).toHaveBeenCalledWith(model)
17
+ expect(Lanes.Models.PubSub.remove).toHaveBeenCalledWith(@model)
13
18
 
14
19
  it "can retrieve a model after checkin", ->
15
- Model = Lanes.Test.defineModel({
16
- props: { id: 'integer', foo: 'string' }
17
- })
18
-
19
- record = new Model(id: 11, foo: 'bar')
20
-
20
+ record = new @Model(id: 11, foo: 'bar')
21
21
  Lanes.Models.PubSub.add(record)
22
- checkin = Lanes.Models.PubSub.instanceFor(Model, 11)
22
+ checkin = Lanes.Models.PubSub.instanceFor(@Model, 11)
23
23
  expect(checkin).toEqual(record)
24
+
25
+ it 'only adds an identical model once', ->
26
+ Lanes.Models.PubSub.add(@model)
27
+ Lanes.Models.PubSub.add(@model)
28
+ configs = @getModelConfig()
29
+ expect(configs.models.length).toEqual(1)
30
+ expect(configs.models[0].count).toEqual(2)
31
+
32
+ it 'does not cause errors to remove a non-added model', ->
33
+ expect( =>
34
+ Lanes.Models.PubSub.remove(@model)
35
+ ).not.toThrowError()
36
+
37
+
38
+ it 'removes models', ->
39
+ Lanes.Models.PubSub.add(@model)
40
+ configs = Lanes.Models.PubSub.types.get('/s').records[1].models
41
+ expect(configs.length).toEqual(1)
42
+
43
+ Lanes.Models.PubSub.remove(@model)
44
+ expect(configs[0].count).toEqual(1)
45
+ Lanes.Models.PubSub.remove(@model)
46
+ expect( Lanes.Models.PubSub.types.get('/s').records[1] ).toBeUndefined()
47
+
48
+ it 'subscribes only once when models are added', ->
49
+ Lanes.Models.PubSub.add(@model)
50
+ expect(Lanes.Models.PubSub.mb.subscribe).toHaveBeenCalledWith(
51
+ '/s/1', jasmine.any(Function)
52
+ )
53
+ Lanes.Models.PubSub.add( new @Model({ id: 1, foo: 'foo' }) )
54
+ Lanes.Models.PubSub.add( new @Model({ id: 1, foo: 'baz' }) )
55
+ expect(Lanes.Models.PubSub.mb.subscribe.calls.count()).toEqual(1)
56
+
57
+ it 'unsubcribes only when all models are removed', ->
58
+ for i in [0..2]
59
+ Lanes.Models.PubSub.add(@model)
60
+ newModel = new @Model({ id: 1, foo: 'foo' })
61
+ Lanes.Models.PubSub.add( newModel )
62
+ # note - over unsubscribed
63
+ for i in [0..3]
64
+ Lanes.Models.PubSub.remove(@model)
65
+ expect(@getModelConfig().models.length).toEqual(1)
66
+ expect(Lanes.Models.PubSub.mb.subscribe.calls.count()).toEqual(1)
67
+ expect(Lanes.Models.PubSub.mb.unsubscribe.calls.count()).toEqual(0)
68
+ Lanes.Models.PubSub.remove(newModel)
69
+
70
+ Lanes.Models.PubSub.remove(newModel)
71
+
72
+ expect(@getModelConfig()).toBeUndefined()
73
+ expect(Lanes.Models.PubSub.mb.unsubscribe.calls.count()).toEqual(1)
@@ -9,7 +9,7 @@ describe "Lanes.Screens.Definitions", ->
9
9
  testuser = Lanes.Test.makeModel({
10
10
  session:
11
11
  isLoggedIn: 'bool'
12
- canRead: -> true
12
+ hasAccess: -> true
13
13
  })
14
14
  Lanes.current_user = testuser
15
15
  Lanes.Test.DefinitionTestModel = Lanes.Test.defineModel({
@@ -26,7 +26,7 @@ describe "Lanes.Screens.Definitions", ->
26
26
  expect(Lanes.Screens.Definitions.groups.available().length).toEqual(1)
27
27
  expect( group.screens().length ).toEqual(1)
28
28
 
29
- Lanes.current_user.canRead = -> false
29
+ Lanes.current_user.hasAccess = -> false
30
30
  Lanes.current_user.isLoggedIn = false
31
31
 
32
32
  expect( group.screens().length ).toEqual(0)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lanes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Stitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-31 00:00:00.000000000 Z
11
+ date: 2016-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -820,24 +820,28 @@ files:
820
820
  - client/lanes/testing/TestObjects.coffee
821
821
  - client/lanes/testing/index.js
822
822
  - client/lanes/testing/jasmine-react.js
823
- - client/lanes/vendor/base.js
824
- - client/lanes/vendor/calendar.js
825
- - client/lanes/vendor/calendar.scss
826
- - client/lanes/vendor/commons.js
827
- - client/lanes/vendor/development.js
828
- - client/lanes/vendor/grid.js
829
- - client/lanes/vendor/grid.scss
823
+ - client/lanes/vendor/base.js.erb
824
+ - client/lanes/vendor/calendar.js.erb
825
+ - client/lanes/vendor/commons.js.erb
826
+ - client/lanes/vendor/development/base.js
827
+ - client/lanes/vendor/development/calendar.js
828
+ - client/lanes/vendor/development/commons.js
829
+ - client/lanes/vendor/development/helpers.js
830
+ - client/lanes/vendor/development/toggle.js
831
+ - client/lanes/vendor/development/widgets.js
830
832
  - client/lanes/vendor/index.js
831
833
  - client/lanes/vendor/message-bus-ajax.js
832
834
  - client/lanes/vendor/message-bus.js
833
- - client/lanes/vendor/rw-widgets.eot
834
- - client/lanes/vendor/rw-widgets.svg
835
- - client/lanes/vendor/rw-widgets.ttf
836
- - client/lanes/vendor/rw-widgets.woff
837
- - client/lanes/vendor/toggle.js
838
- - client/lanes/vendor/toggle.scss
839
- - client/lanes/vendor/widgets.js
840
- - client/lanes/vendor/widgets.scss
835
+ - client/lanes/vendor/production/base.js
836
+ - client/lanes/vendor/production/calendar.js
837
+ - client/lanes/vendor/production/commons.js
838
+ - client/lanes/vendor/production/toggle.js
839
+ - client/lanes/vendor/production/widgets.js
840
+ - client/lanes/vendor/styles/calendar.scss
841
+ - client/lanes/vendor/styles/toggle.scss
842
+ - client/lanes/vendor/styles/widgets.scss
843
+ - client/lanes/vendor/toggle.js.erb
844
+ - client/lanes/vendor/widgets.js.erb
841
845
  - client/lanes/workspace/Extension.coffee
842
846
  - client/lanes/workspace/Layout.cjsx
843
847
  - client/lanes/workspace/Modal.cjsx
@@ -973,9 +977,9 @@ files:
973
977
  - log/.gitkeep
974
978
  - npm-build/README
975
979
  - npm-build/base.js
980
+ - npm-build/build
976
981
  - npm-build/calendar.js
977
982
  - npm-build/common.js
978
- - npm-build/compile.coffee
979
983
  - npm-build/development.js
980
984
  - npm-build/grid.js
981
985
  - npm-build/package.json
@@ -1043,7 +1047,6 @@ files:
1043
1047
  - spec/lanes/models/CollectionSpec.coffee
1044
1048
  - spec/lanes/models/EnumMapSpec.coffee
1045
1049
  - spec/lanes/models/PubSubSpec.coffee
1046
- - spec/lanes/models/ServerCacheSpec.coffee
1047
1050
  - spec/lanes/models/SyncSpec.coffee
1048
1051
  - spec/lanes/models/UserSpec.coffee
1049
1052
  - spec/lanes/react/mixins/DataSpec.coffee
@@ -1143,7 +1146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1143
1146
  version: '0'
1144
1147
  requirements: []
1145
1148
  rubyforge_project:
1146
- rubygems_version: 2.4.5.1
1149
+ rubygems_version: 2.5.1
1147
1150
  signing_key:
1148
1151
  specification_version: 4
1149
1152
  summary: Lanes is a framework for easily writing single page web applications