volt 0.9.6 → 0.9.7.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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