volt 0.9.6 → 0.9.7.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/CHANGELOG.md +26 -0
  4. data/Gemfile +6 -1
  5. data/README.md +2 -0
  6. data/Rakefile +1 -0
  7. data/app/volt/models/active_volt_instance.rb +8 -6
  8. data/app/volt/models/user.rb +11 -2
  9. data/app/volt/models/volt_app_property.rb +8 -0
  10. data/app/volt/tasks/query_tasks.rb +23 -31
  11. data/app/volt/tasks/store_tasks.rb +2 -2
  12. data/app/volt/tasks/volt_admin_tasks.rb +24 -0
  13. data/docs/UPGRADE_GUIDE.md +6 -0
  14. data/lib/volt.rb +19 -12
  15. data/lib/volt/boot.rb +1 -0
  16. data/lib/volt/cli.rb +19 -8
  17. data/lib/volt/cli/console.rb +0 -1
  18. data/lib/volt/cli/generators.rb +14 -3
  19. data/lib/volt/cli/migrate.rb +26 -0
  20. data/lib/volt/config.rb +17 -4
  21. data/lib/volt/controllers/http_controller.rb +12 -0
  22. data/lib/volt/data_stores/base_adaptor_client.rb +2 -2
  23. data/lib/volt/data_stores/base_adaptor_server.rb +2 -0
  24. data/lib/volt/data_stores/data_store.rb +20 -14
  25. data/lib/volt/extra_core/class.rb +28 -14
  26. data/lib/volt/extra_core/hash.rb +5 -0
  27. data/lib/volt/extra_core/string.rb +3 -1
  28. data/lib/volt/helpers/time.rb +9 -43
  29. data/lib/volt/helpers/time/calculations.rb +204 -0
  30. data/lib/volt/helpers/time/distance.rb +63 -0
  31. data/lib/volt/helpers/time/duration.rb +71 -0
  32. data/lib/volt/helpers/time/local_calculations.rb +49 -0
  33. data/lib/volt/helpers/time/local_volt_time.rb +23 -0
  34. data/lib/volt/helpers/time/numeric.rb +59 -0
  35. data/lib/volt/helpers/time/volt_time.rb +170 -0
  36. data/lib/volt/models.rb +5 -0
  37. data/lib/volt/models/array_model.rb +33 -6
  38. data/lib/volt/models/associations.rb +146 -23
  39. data/lib/volt/models/buffer.rb +38 -41
  40. data/lib/volt/models/cursor.rb +15 -0
  41. data/lib/volt/models/errors.rb +11 -0
  42. data/lib/volt/models/field_helpers.rb +108 -68
  43. data/lib/volt/models/helpers/array_model.rb +4 -0
  44. data/lib/volt/models/helpers/base.rb +8 -1
  45. data/lib/volt/models/helpers/change_helpers.rb +31 -12
  46. data/lib/volt/models/helpers/defaults.rb +15 -0
  47. data/lib/volt/models/location.rb +20 -6
  48. data/lib/volt/models/migrations/migration.rb +23 -0
  49. data/lib/volt/models/migrations/migration_runner.rb +146 -0
  50. data/lib/volt/models/model.rb +38 -1
  51. data/lib/volt/models/permissions.rb +8 -1
  52. data/lib/volt/models/persistors/array_store.rb +87 -8
  53. data/lib/volt/models/persistors/base.rb +19 -0
  54. data/lib/volt/models/persistors/model_store.rb +1 -1
  55. data/lib/volt/models/persistors/page.rb +4 -1
  56. data/lib/volt/models/persistors/query/query_identifier.rb +102 -0
  57. data/lib/volt/models/persistors/query/query_listener.rb +57 -12
  58. data/lib/volt/models/root_models/root_models.rb +19 -0
  59. data/lib/volt/models/url.rb +11 -2
  60. data/lib/volt/models/validations/validations.rb +5 -2
  61. data/lib/volt/models/validators/type_validator.rb +11 -0
  62. data/lib/volt/models/validators/unique_validator.rb +2 -2
  63. data/lib/volt/page/bindings/attribute_binding.rb +23 -1
  64. data/lib/volt/page/targets/attribute_section.rb +7 -0
  65. data/lib/volt/page/targets/binding_document/component_node.rb +44 -18
  66. data/lib/volt/page/targets/binding_document/tag_node.rb +41 -0
  67. data/lib/volt/page/tasks.rb +16 -8
  68. data/lib/volt/queries/live_query.rb +109 -0
  69. data/lib/volt/queries/live_query_pool.rb +58 -0
  70. data/lib/volt/queries/live_subquery.rb +0 -0
  71. data/lib/volt/queries/query_association_splitter.rb +31 -0
  72. data/lib/volt/queries/query_diff.rb +100 -0
  73. data/lib/volt/queries/query_runner.rb +110 -0
  74. data/lib/volt/queries/query_subscription.rb +80 -0
  75. data/lib/volt/queries/query_subscription_pool.rb +37 -0
  76. data/lib/volt/reactive/eventable.rb +8 -0
  77. data/lib/volt/reactive/reactive_array.rb +0 -4
  78. data/lib/volt/router/routes.rb +81 -31
  79. data/lib/volt/server/message_bus/base_message_bus.rb +9 -3
  80. data/lib/volt/server/message_bus/peer_to_peer.rb +6 -6
  81. data/lib/volt/server/message_bus/peer_to_peer/server_tracker.rb +1 -1
  82. data/lib/volt/server/middleware/default_middleware_stack.rb +12 -8
  83. data/lib/volt/server/rack/component_paths.rb +31 -4
  84. data/lib/volt/server/rack/http_content_types.rb +62 -0
  85. data/lib/volt/server/rack/http_resource.rb +1 -1
  86. data/lib/volt/server/rack/index_files.rb +8 -1
  87. data/lib/volt/server/rack/opal_files.rb +16 -1
  88. data/lib/volt/server/rack/sprockets_helpers_setup.rb +32 -1
  89. data/lib/volt/server/socket_connection_handler.rb +16 -7
  90. data/lib/volt/server/template_handlers/sprockets_component_handler.rb +5 -3
  91. data/lib/volt/spec/capybara.rb +4 -3
  92. data/lib/volt/spec/setup.rb +5 -0
  93. data/lib/volt/tasks/dispatcher.rb +3 -1
  94. data/lib/volt/utils/data_transformer.rb +4 -4
  95. data/lib/volt/utils/ejson.rb +19 -6
  96. data/lib/volt/utils/promise_extensions.rb +1 -1
  97. data/lib/volt/utils/time_opal_patch.rb +749 -0
  98. data/lib/volt/utils/time_patch.rb +11 -4
  99. data/lib/volt/version.rb +1 -1
  100. data/lib/volt/volt/app.rb +19 -11
  101. data/lib/volt/volt/properties.rb +24 -0
  102. data/lib/volt/volt/server_setup/app.rb +30 -7
  103. data/lib/volt/volt/users.rb +15 -3
  104. data/spec/apps/kitchen_sink/Gemfile +5 -1
  105. data/spec/apps/kitchen_sink/app/main/config/routes.rb +1 -0
  106. data/spec/apps/kitchen_sink/app/main/controllers/save_controller.rb +1 -1
  107. data/spec/apps/kitchen_sink/app/main/controllers/server/simple_http_controller.rb +4 -0
  108. data/spec/apps/kitchen_sink/app/main/controllers/todos_controller.rb +4 -2
  109. data/spec/apps/kitchen_sink/app/main/models/post.rb +0 -1
  110. data/spec/apps/kitchen_sink/app/main/models/todo.rb +4 -0
  111. data/spec/apps/kitchen_sink/app/main/views/mailers/reset_password.html +10 -0
  112. data/spec/apps/kitchen_sink/app/main/views/todos/index.html +2 -0
  113. data/spec/apps/kitchen_sink/config/app.rb +2 -0
  114. data/spec/apps/migrations/config/db/migrations/1445111704_migration1.rb +7 -0
  115. data/spec/apps/migrations/config/db/migrations/1445113517_migration2.rb +7 -0
  116. data/spec/apps/migrations/config/db/migrations/1445115200_migration3.rb +7 -0
  117. data/spec/extra_core/class_spec.rb +10 -0
  118. data/spec/helpers/distance_spec.rb +35 -0
  119. data/spec/helpers/duration_spec.rb +160 -0
  120. data/spec/helpers/volt_time_spec.rb +275 -0
  121. data/spec/integration/callbacks_spec.rb +2 -1
  122. data/spec/integration/http_endpoints_spec.rb +4 -0
  123. data/spec/integration/save_spec.rb +1 -1
  124. data/spec/integration/todos_spec.rb +7 -5
  125. data/spec/models/array_model_spec.rb +17 -3
  126. data/spec/models/associations_spec.rb +48 -1
  127. data/spec/models/field_helpers_spec.rb +7 -3
  128. data/spec/models/migrations/migration_runner_spec.rb +69 -0
  129. data/spec/models/model_spec.rb +42 -8
  130. data/spec/models/permissions_spec.rb +20 -8
  131. data/spec/models/persistors/array_store_spec.rb +18 -0
  132. data/spec/models/persistors/page_spec.rb +15 -10
  133. data/spec/models/persistors/store_spec.rb +13 -3
  134. data/spec/models/url_spec.rb +4 -3
  135. data/spec/models/user_spec.rb +6 -3
  136. data/spec/models/user_validation_spec.rb +3 -3
  137. data/spec/models/validations_spec.rb +4 -0
  138. data/spec/models/validators/block_validations_spec.rb +9 -5
  139. data/spec/models/validators/email_validator_spec.rb +2 -0
  140. data/spec/models/validators/lifecycle_callbacks_spec.rb +86 -0
  141. data/spec/models/validators/unique_validator_spec.rb +1 -0
  142. data/spec/page/path_string_renderer_spec.rb +5 -0
  143. data/spec/queries/live_query_spec.rb +16 -0
  144. data/spec/queries/query_association_splitter_spec.rb +14 -0
  145. data/spec/queries/query_diff_spec.rb +132 -0
  146. data/spec/queries/query_identifier_spec.rb +98 -0
  147. data/spec/queries/query_runner_spec.rb +63 -0
  148. data/spec/queries/query_tracker_spec.rb +141 -0
  149. data/spec/router/routes_spec.rb +52 -21
  150. data/spec/server/middleware/rack_content_types_spec.rb +78 -0
  151. data/spec/server/rack/asset_files_spec.rb +38 -30
  152. data/spec/spec_helper.rb +8 -0
  153. data/spec/utils/ejson_spec.rb +9 -8
  154. data/spec/utils/ejson_volt_time_spec.rb +65 -0
  155. data/templates/migration/migration.rb.tt +9 -0
  156. data/templates/newgem/gitignore.tt +1 -0
  157. data/templates/project/Gemfile.tt +19 -2
  158. data/templates/project/README.md.tt +6 -1
  159. data/templates/project/app/main/config/dependencies.rb +6 -0
  160. data/templates/project/config/app.rb.tt +18 -4
  161. data/volt.gemspec +2 -2
  162. metadata +73 -16
  163. data/app/volt/tasks/live_query/live_query_pool.rb +0 -48
  164. data/app/volt/tasks/live_query/query_tracker.rb +0 -92
  165. data/spec/tasks/live_query_spec.rb +0 -18
  166. data/spec/tasks/query_tasks.rb +0 -7
  167. data/spec/tasks/query_tracker_spec.rb +0 -145
@@ -1,19 +1,24 @@
1
1
  require 'spec_helper'
2
2
 
3
- module Volt
4
- module Persistors
5
- describe Page do
6
- describe '#where' do
7
- it 'searches for records in the page collection with the given values' do
8
- juan = Volt::Model.new(name: 'Juan', city: 'Quito', age: 13)
9
- pedro = Volt::Model.new(name: 'Pedro', city: 'Quito', age: 15)
10
- jose = Volt::Model.new(name: 'Jose', city: 'Quito', age: 13)
3
+ unless RUBY_PLATFORM == 'opal'
4
+ # TODO: this should run fine under opal
11
5
 
12
- page = described_class.new [jose, juan, pedro]
6
+ module Volt
7
+ module Persistors
8
+ describe Page do
9
+ describe '#where' do
10
+ it 'searches for records in the page collection with the given values' do
11
+ juan = Volt::Model.new(name: 'Juan', city: 'Quito', age: 13)
12
+ pedro = Volt::Model.new(name: 'Pedro', city: 'Quito', age: 15)
13
+ jose = Volt::Model.new(name: 'Jose', city: 'Quito', age: 13)
13
14
 
14
- expect(page.where age: 13, city: 'Quito').to match_array [juan, jose]
15
+ the_page._items = [jose, juan, pedro]
16
+
17
+ expect(the_page._items.where(age: 13, city: 'Quito')).to match_array [juan, jose]
18
+ end
15
19
  end
16
20
  end
17
21
  end
18
22
  end
23
+
19
24
  end
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'volt/models'
3
3
 
4
+
4
5
  describe Volt::Persistors::Store do
5
6
  it 'should tell the persistor when the model has changed' do
6
7
  persistor = double('volt/persistor')
@@ -38,22 +39,31 @@ describe Volt::Persistors::Store do
38
39
  end
39
40
 
40
41
  unless RUBY_PLATFORM == 'opal'
42
+ class ::Nester < Volt::Model
43
+ end
44
+
41
45
  before do
42
- model = store._nesters.create(name: 'One').sync
46
+ model = store.nesters.create(name: 'One').sync
43
47
  model._subone = {name: 'Two'}
44
48
  end
45
49
 
46
50
  it 'should reload a model with nested hash models' do
47
- model2 = store._nesters.first.sync
51
+ model2 = store.nesters.first.sync
48
52
 
49
53
  expect(model2.to_h.without(:id, :subone)).to eq(name: 'One')
50
54
  expect(model2._subone.to_h.without(:id)).to eq(name: 'Two')
51
55
  end
52
56
 
53
57
  it 'should reload nested hash models with the same parent persistor' do
54
- model = store._nesters.first.sync
58
+ model = store.nesters.first.sync
55
59
  expect(model.persistor).to eq(model._subone.persistor)
56
60
  end
61
+
62
+ it 'should raise an error when accessing an model class on store (using sql)' do
63
+ expect do
64
+ store.wrong_models
65
+ end.to raise_error
66
+ end
57
67
  end
58
68
 
59
69
  unless RUBY_PLATFORM == 'opal'
@@ -6,14 +6,15 @@ describe Volt::URL do
6
6
 
7
7
  let(:fake_location) do
8
8
  double(
9
- 'Location',
9
+ 'Volt::Location',
10
10
  host: 'voltframework.com',
11
- protocol: 'http:'
11
+ protocol: 'http:',
12
+ scheme: 'http'
12
13
  )
13
14
  end
14
15
 
15
16
  before do
16
- allow(Location).to receive(:new).and_return fake_location
17
+ allow(Volt::Location).to receive(:new).and_return fake_location
17
18
  subject.parse uri
18
19
  end
19
20
 
@@ -43,7 +43,7 @@ describe Volt::User do
43
43
  describe 'when it is a Volt server' do
44
44
  before do
45
45
  allow(BCrypt::Password).to receive(:create).with('test')
46
- .and_return 'hashed-password'
46
+ .and_return 'hashed-password'
47
47
  end
48
48
 
49
49
  it 'encrypts password' do
@@ -60,7 +60,7 @@ describe Volt::User do
60
60
  end
61
61
 
62
62
  it 'should allow updates without validating the password' do
63
- bob = store._users.buffer(name: 'Bob', email: 'bob@bob.com', password: '39sdjkdf932jklsd')
63
+ bob = store.users.buffer(name: 'Bob', email: 'bob@bob.com', password: '39sdjkdf932jklsd')
64
64
  bob.save!.sync
65
65
 
66
66
  Volt.as_user(bob) do
@@ -72,8 +72,11 @@ describe Volt::User do
72
72
  bob_buf.name = 'Jimmy'
73
73
 
74
74
  saved = false
75
- bob_buf.save! do
75
+
76
+ bob_buf.save!.then do
76
77
  saved = true
78
+ end.fail do |err|
79
+ puts "User save error: #{err.inspect}"
77
80
  end
78
81
 
79
82
  expect(saved).to eq(true)
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- class TestUserTodo < Volt::Model
3
+ class TestUserTodo2 < Volt::Model
4
4
  own_by_user
5
5
 
6
6
  permissions(:update) do
@@ -15,12 +15,12 @@ describe Volt::UserValidatorHelpers do
15
15
  end
16
16
 
17
17
  it 'should assign user_id when owning by a user' do
18
- todo = TestUserTodo.new
18
+ todo = TestUserTodo2.new
19
19
  expect(todo._user_id).to eq(294)
20
20
  end
21
21
 
22
22
  it 'should not allow the user_id to be changed' do
23
- todo = TestUserTodo.new
23
+ todo = TestUserTodo2.new
24
24
  expect(todo._user_id).to eq(294)
25
25
 
26
26
  todo._user_id = 500
@@ -5,6 +5,7 @@ describe Volt::Model do
5
5
 
6
6
  let(:test_model_class) do
7
7
  Class.new(Volt::Model) do
8
+ set_collection_name :test_model_classes
8
9
  validate :count, numericality: { min: 5, max: 10 }
9
10
  validate :description, length: { message: 'needs to be longer',
10
11
  length: 50 }
@@ -18,6 +19,7 @@ describe Volt::Model do
18
19
 
19
20
  let(:test_model_with_promises) do
20
21
  Class.new(Volt::Model) do
22
+ set_collection_name :test_model_with_promises
21
23
  attr_accessor :ran_promise
22
24
  validate do
23
25
  Promise.new.then do
@@ -109,6 +111,7 @@ describe Volt::Model do
109
111
 
110
112
  let(:test_model_class) do
111
113
  Class.new(Volt::Model) do
114
+ set_collection_name :test_model2_classes
112
115
  validate :special_field, format: [
113
116
  { with: /regex/, message: 'regex failed' },
114
117
  { with: ->(x) { x == false }, message: 'proc failed' }
@@ -169,6 +172,7 @@ describe Volt::Model do
169
172
  let(:model) { test_model_with_custom_validation.new }
170
173
  let(:test_model_with_custom_validation) do
171
174
  Class.new(Volt::Model) do
175
+ set_collection_name :test_model_with_custom_validations
172
176
  validations do
173
177
  validate :something, presence: true
174
178
  validate do
@@ -6,6 +6,7 @@ unless RUBY_PLATFORM == 'opal'
6
6
 
7
7
  let(:test_model_class) do
8
8
  Class.new(Volt::Model) do
9
+ set_collection_name :test_model3_classes
9
10
  validations do
10
11
  if _is_ready == true
11
12
  validate :name, length: 5
@@ -16,6 +17,7 @@ unless RUBY_PLATFORM == 'opal'
16
17
 
17
18
  let(:test_model_action_pass_class) do
18
19
  Class.new(Volt::Model) do
20
+ set_collection_name :test_model_action_pass_classes
19
21
  validations do |action|
20
22
  # Only validation the name on update
21
23
  if action == :update
@@ -28,24 +30,26 @@ unless RUBY_PLATFORM == 'opal'
28
30
  it 'should run conditional validations in the validations block' do
29
31
  a = test_model_class.new(name: 'Jo')
30
32
 
31
- a.validate!.sync
32
33
  expect(a.errors.size).to eq(0)
33
34
 
34
35
  a._is_ready = true
35
- a.validate!.sync
36
36
 
37
37
  expect(a.errors.size).to eq(1)
38
38
  end
39
39
 
40
+
41
+ class ::Person < Volt::Model
42
+ end
43
+
40
44
  it 'should send the action name to the validations block' do
41
45
  jo = test_model_action_pass_class.new(name: 'Jo')
42
46
 
43
- jo.validate!.sync
44
47
  expect(jo.errors.size).to eq(0)
45
48
 
46
- store._people << jo
49
+ store.people << jo
50
+
51
+ jo._name = 'Joe'
47
52
 
48
- jo.validate!.sync
49
53
  expect(jo.errors.size).to eq(1)
50
54
 
51
55
  end
@@ -5,6 +5,7 @@ describe Volt::Model do
5
5
 
6
6
  let(:test_model_class) do
7
7
  Class.new(Volt::Model) do
8
+ set_collection_name :test_model4_classes
8
9
  validate :count, numericality: { min: 5, max: 10 }
9
10
  validate :description, length: { message: 'needs to be longer',
10
11
  length: 50 }
@@ -87,6 +88,7 @@ describe Volt::Model do
87
88
 
88
89
  let(:test_model_class) do
89
90
  Class.new(Volt::Model) do
91
+ set_collection_name :test_model5_classes
90
92
  validate :special_field, format: [
91
93
  { with: /regex/, message: 'regex failed' },
92
94
  { with: ->(x) { x == false }, message: 'proc failed' }
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ class ::BeforeCallbacksTest < Volt::Model
4
+ before_validate :inc_validate_count
5
+ before_create :inc_create_count
6
+ before_save :inc_save_count
7
+ before_update :inc_update_count
8
+ attr_reader :validate_count, :create_count, :save_count, :update_count
9
+
10
+ field :name, String
11
+
12
+ def initialize(*)
13
+ @validate_count = 0
14
+ @create_count = 0
15
+ @save_count = 0
16
+ @update_count = 0
17
+ super
18
+ end
19
+
20
+ def inc_validate_count
21
+ @validate_count += 1
22
+ end
23
+
24
+ def inc_create_count
25
+ @create_count += 1
26
+ end
27
+
28
+ def inc_save_count
29
+ @save_count += 1
30
+ end
31
+
32
+ def inc_update_count
33
+ @update_count += 1
34
+ end
35
+ end
36
+
37
+
38
+ describe Volt::Models::Helpers::ChangeHelpers do
39
+ it 'should call before save before each save' do
40
+ model = the_page._before_callbacks_tests.create({name: 'One'})
41
+
42
+ expect(model.save_count).to eq(1)
43
+ end
44
+
45
+ it 'should call before_create before create' do
46
+ model = the_page._before_callbacks_tests.create({name: 'One'})
47
+
48
+ expect(model.create_count).to eq(1)
49
+ end
50
+
51
+ it 'should call before_update before update' do
52
+ model = the_page._before_callbacks_tests.create({name: 'One'})
53
+ expect(model.create_count).to eq(1)
54
+ expect(model.update_count).to eq(0)
55
+
56
+ model.name = 'New Name'
57
+ expect(model.create_count).to eq(1)
58
+ expect(model.update_count).to eq(1)
59
+
60
+ model.name = 'Another name'
61
+ expect(model.create_count).to eq(1)
62
+ expect(model.update_count).to eq(2)
63
+ expect(model.save_count).to eq(3)
64
+ end
65
+
66
+ # validation happens one extra time for the initial create
67
+ it 'should call before_validate before validate' do
68
+ model = the_page._before_callbacks_tests.create({name: 'One'})
69
+ expect(model.validate_count).to eq(2)
70
+
71
+ model.name = 'New Name'
72
+ expect(model.validate_count).to eq(3)
73
+ end
74
+
75
+ # it 'should not call anything on a buffer' do
76
+ # model = the_page._before_callbacks_tests.buffer({name: 'One'})
77
+
78
+ # model.save!
79
+
80
+ # expect(model.create_count).to eq(0)
81
+ # expect(model.update_count).to eq(0)
82
+ # expect(model.save_count).to eq(0)
83
+ # expect(model.validate_count).to eq(0)
84
+
85
+ # end
86
+ end
@@ -2,6 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  unless RUBY_PLATFORM == 'opal'
4
4
  class Fridge < Volt::Model
5
+ field :name, String
5
6
  validate :name, unique: true
6
7
  end
7
8
 
@@ -18,6 +18,11 @@ unless RUBY_PLATFORM == 'opal'
18
18
  expect(html).to eq("\n <h1>Welcome Jimmy</h1>\n\n <p>Glad you signed up!</p>\n\n")
19
19
  end
20
20
 
21
+ it 'should render with an attribute binding' do
22
+ html = Volt::PathStringRenderer.new(@volt_app, 'main/mailers/reset_password/html', { reset_url: 'http://resetthepassword.com/' }).html
23
+ expect(html).to eq("\n Reset your password <a target=\"_new\" id=\"id0\" href=\"http://resetthepassword.com/\">here</a>.\n\n <a id=\"id1\" href=\"http://resetthepassword.com/\">Reset Password</a>\n\n")
24
+ end
25
+
21
26
  it 'Raises raises ViewLookupException if full_path is nil' do
22
27
  expect do
23
28
  Volt::PathStringRenderer.new(@volt_app, '', { name: 'Jimmy' }).html
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ if RUBY_PLATFORM != 'opal'
4
+ describe 'LiveQuery' do
5
+ it 'should run a query' do
6
+ pool = double('volt/pool')
7
+ data_store = double('volt/data store')
8
+
9
+ expect(data_store).to receive(:query).with('_items', []).and_return([
10
+ { 'id' => 0, '_name' => 'one' }
11
+ ])
12
+
13
+ live_query = Volt::LiveQuery.new(volt_app, pool, data_store, '_items', {})
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ if RUBY_PLATFORM != 'opal'
4
+ describe Volt::QueryAssociationSplitter do
5
+ it 'should split a query and return the associations' do
6
+ query = [:where, {name: 'Bob'}]
7
+ includes = ['includes', [:posts, [:posts, :comments], :links]]
8
+ new_query, associations = Volt::QueryAssociationSplitter.split([query, includes])
9
+
10
+ expect(new_query).to eq([query])
11
+ expect(associations).to eq({:posts=>{:comments=>{}}, :links=>{}})
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+
3
+ if RUBY_PLATFORM != 'opal'
4
+ describe Volt::QueryDiff do
5
+ it 'should return a diff for moving records' do
6
+ a = [
7
+ {id: 1, name: 'Bob'},
8
+ {id: 2, name: 'Jim'},
9
+ {id: 3, name: 'Rob'}
10
+ ]
11
+ b = [
12
+ {id: 3, name: 'Rob'},
13
+ {id: 1, name: 'Bob'},
14
+ {id: 2, name: 'Jim'}
15
+ ]
16
+
17
+ diff = Volt::QueryDiff.new(a).run(b)
18
+
19
+ expect(diff).to eq([["m", 3, 0]])
20
+ end
21
+
22
+ it 'should return a diff moved records 2' do
23
+ a = [
24
+ {id: 1, name: 'Bob'},
25
+ {id: 2, name: 'Jim'},
26
+ {id: 3, name: 'Rob'},
27
+ {id: 4, name: 'Meg'}
28
+ ]
29
+ b = [
30
+ {id: 3, name: 'Rob'},
31
+ {id: 1, name: 'Bob'},
32
+ {id: 4, name: 'Meg'},
33
+ {id: 2, name: 'Jim'}
34
+ ]
35
+
36
+ diff = Volt::QueryDiff.new(a).run(b)
37
+
38
+ expect(diff).to eq([
39
+ ["m", 3, 0],
40
+ ["m", 4, 2]
41
+ ])
42
+ end
43
+
44
+ it 'should return a diff with removed records' do
45
+ a = [
46
+ {id: 1, name: 'Bob'},
47
+ {id: 2, name: 'Jim'},
48
+ {id: 3, name: 'Rob'}
49
+ ]
50
+ b = [
51
+ {id: 3, name: 'Rob'},
52
+ {id: 2, name: 'Jim'}
53
+ ]
54
+
55
+ diff = Volt::QueryDiff.new(a).run(b)
56
+
57
+ expect(diff).to eq([
58
+ ["r", 1],
59
+ ["m", 3, 0]
60
+ ])
61
+ end
62
+
63
+ it 'should return a diff for updated records' do
64
+ a = [
65
+ {id: 1, name: 'Bob'},
66
+ {id: 2, name: 'Jim'},
67
+ {id: 3, name: 'Rob'}
68
+ ]
69
+ b = [
70
+ {id: 2, name: 'Jim', admin: true},
71
+ {id: 1, name: 'Bobby'},
72
+ {id: 3, name: 'Rob'}
73
+ ]
74
+
75
+ diff = Volt::QueryDiff.new(a).run(b)
76
+
77
+ expect(diff).to eq(
78
+ [
79
+ ["m", 2, 0],
80
+ ["c", 1, {:id=>1, :name=>"Bobby"}],
81
+ ["c", 2, {:id=>2, :name=>"Jim", :admin=>true}]
82
+ ]
83
+ )
84
+ end
85
+
86
+ it 'should handle nested updates' do
87
+ a = [
88
+ {id: 1, name: 'Bob'},
89
+ {id: 2, name: 'Jim'},
90
+ {id: 3, name: 'Rob'}
91
+ ]
92
+ b = [
93
+ {id: 2, name: 'Jim', admin: true},
94
+ {id: 1, name: 'Bobby'},
95
+ {id: 3, name: 'Rob'}
96
+ ]
97
+
98
+ diff = Volt::QueryDiff.new(a).run(b)
99
+
100
+ expect(diff).to eq(
101
+ [
102
+ ["m", 2, 0],
103
+ ["c", 1, {:id=>1, :name=>"Bobby"}],
104
+ ["c", 2, {:id=>2, :name=>"Jim", :admin=>true}]
105
+ ]
106
+ )
107
+ end
108
+
109
+ it 'should handle complex transforms' do
110
+ a = [
111
+ {id: 1, name: 'Bob'},
112
+ {id: 2, name: 'Jim'},
113
+ {id: 3, name: 'Rob'}
114
+ ]
115
+ b = [
116
+ {id: 2, name: 'Jim', admin: true},
117
+ {id: 1, name: 'Bobby'},
118
+ {id: 3, name: 'Rob'}
119
+ ]
120
+
121
+ diff = Volt::QueryDiff.new(a).run(b)
122
+
123
+ expect(diff).to eq(
124
+ [
125
+ ["m", 2, 0],
126
+ ["c", 1, {:id=>1, :name=>"Bobby"}],
127
+ ["c", 2, {:id=>2, :name=>"Jim", :admin=>true}]
128
+ ]
129
+ )
130
+ end
131
+ end
132
+ end