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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/CHANGELOG.md +26 -0
- data/Gemfile +6 -1
- data/README.md +2 -0
- data/Rakefile +1 -0
- data/app/volt/models/active_volt_instance.rb +8 -6
- data/app/volt/models/user.rb +11 -2
- data/app/volt/models/volt_app_property.rb +8 -0
- data/app/volt/tasks/query_tasks.rb +23 -31
- data/app/volt/tasks/store_tasks.rb +2 -2
- data/app/volt/tasks/volt_admin_tasks.rb +24 -0
- data/docs/UPGRADE_GUIDE.md +6 -0
- data/lib/volt.rb +19 -12
- data/lib/volt/boot.rb +1 -0
- data/lib/volt/cli.rb +19 -8
- data/lib/volt/cli/console.rb +0 -1
- data/lib/volt/cli/generators.rb +14 -3
- data/lib/volt/cli/migrate.rb +26 -0
- data/lib/volt/config.rb +17 -4
- data/lib/volt/controllers/http_controller.rb +12 -0
- data/lib/volt/data_stores/base_adaptor_client.rb +2 -2
- data/lib/volt/data_stores/base_adaptor_server.rb +2 -0
- data/lib/volt/data_stores/data_store.rb +20 -14
- data/lib/volt/extra_core/class.rb +28 -14
- data/lib/volt/extra_core/hash.rb +5 -0
- data/lib/volt/extra_core/string.rb +3 -1
- data/lib/volt/helpers/time.rb +9 -43
- data/lib/volt/helpers/time/calculations.rb +204 -0
- data/lib/volt/helpers/time/distance.rb +63 -0
- data/lib/volt/helpers/time/duration.rb +71 -0
- data/lib/volt/helpers/time/local_calculations.rb +49 -0
- data/lib/volt/helpers/time/local_volt_time.rb +23 -0
- data/lib/volt/helpers/time/numeric.rb +59 -0
- data/lib/volt/helpers/time/volt_time.rb +170 -0
- data/lib/volt/models.rb +5 -0
- data/lib/volt/models/array_model.rb +33 -6
- data/lib/volt/models/associations.rb +146 -23
- data/lib/volt/models/buffer.rb +38 -41
- data/lib/volt/models/cursor.rb +15 -0
- data/lib/volt/models/errors.rb +11 -0
- data/lib/volt/models/field_helpers.rb +108 -68
- data/lib/volt/models/helpers/array_model.rb +4 -0
- data/lib/volt/models/helpers/base.rb +8 -1
- data/lib/volt/models/helpers/change_helpers.rb +31 -12
- data/lib/volt/models/helpers/defaults.rb +15 -0
- data/lib/volt/models/location.rb +20 -6
- data/lib/volt/models/migrations/migration.rb +23 -0
- data/lib/volt/models/migrations/migration_runner.rb +146 -0
- data/lib/volt/models/model.rb +38 -1
- data/lib/volt/models/permissions.rb +8 -1
- data/lib/volt/models/persistors/array_store.rb +87 -8
- data/lib/volt/models/persistors/base.rb +19 -0
- data/lib/volt/models/persistors/model_store.rb +1 -1
- data/lib/volt/models/persistors/page.rb +4 -1
- data/lib/volt/models/persistors/query/query_identifier.rb +102 -0
- data/lib/volt/models/persistors/query/query_listener.rb +57 -12
- data/lib/volt/models/root_models/root_models.rb +19 -0
- data/lib/volt/models/url.rb +11 -2
- data/lib/volt/models/validations/validations.rb +5 -2
- data/lib/volt/models/validators/type_validator.rb +11 -0
- data/lib/volt/models/validators/unique_validator.rb +2 -2
- data/lib/volt/page/bindings/attribute_binding.rb +23 -1
- data/lib/volt/page/targets/attribute_section.rb +7 -0
- data/lib/volt/page/targets/binding_document/component_node.rb +44 -18
- data/lib/volt/page/targets/binding_document/tag_node.rb +41 -0
- data/lib/volt/page/tasks.rb +16 -8
- data/lib/volt/queries/live_query.rb +109 -0
- data/lib/volt/queries/live_query_pool.rb +58 -0
- data/lib/volt/queries/live_subquery.rb +0 -0
- data/lib/volt/queries/query_association_splitter.rb +31 -0
- data/lib/volt/queries/query_diff.rb +100 -0
- data/lib/volt/queries/query_runner.rb +110 -0
- data/lib/volt/queries/query_subscription.rb +80 -0
- data/lib/volt/queries/query_subscription_pool.rb +37 -0
- data/lib/volt/reactive/eventable.rb +8 -0
- data/lib/volt/reactive/reactive_array.rb +0 -4
- data/lib/volt/router/routes.rb +81 -31
- data/lib/volt/server/message_bus/base_message_bus.rb +9 -3
- data/lib/volt/server/message_bus/peer_to_peer.rb +6 -6
- data/lib/volt/server/message_bus/peer_to_peer/server_tracker.rb +1 -1
- data/lib/volt/server/middleware/default_middleware_stack.rb +12 -8
- data/lib/volt/server/rack/component_paths.rb +31 -4
- data/lib/volt/server/rack/http_content_types.rb +62 -0
- data/lib/volt/server/rack/http_resource.rb +1 -1
- data/lib/volt/server/rack/index_files.rb +8 -1
- data/lib/volt/server/rack/opal_files.rb +16 -1
- data/lib/volt/server/rack/sprockets_helpers_setup.rb +32 -1
- data/lib/volt/server/socket_connection_handler.rb +16 -7
- data/lib/volt/server/template_handlers/sprockets_component_handler.rb +5 -3
- data/lib/volt/spec/capybara.rb +4 -3
- data/lib/volt/spec/setup.rb +5 -0
- data/lib/volt/tasks/dispatcher.rb +3 -1
- data/lib/volt/utils/data_transformer.rb +4 -4
- data/lib/volt/utils/ejson.rb +19 -6
- data/lib/volt/utils/promise_extensions.rb +1 -1
- data/lib/volt/utils/time_opal_patch.rb +749 -0
- data/lib/volt/utils/time_patch.rb +11 -4
- data/lib/volt/version.rb +1 -1
- data/lib/volt/volt/app.rb +19 -11
- data/lib/volt/volt/properties.rb +24 -0
- data/lib/volt/volt/server_setup/app.rb +30 -7
- data/lib/volt/volt/users.rb +15 -3
- data/spec/apps/kitchen_sink/Gemfile +5 -1
- data/spec/apps/kitchen_sink/app/main/config/routes.rb +1 -0
- data/spec/apps/kitchen_sink/app/main/controllers/save_controller.rb +1 -1
- data/spec/apps/kitchen_sink/app/main/controllers/server/simple_http_controller.rb +4 -0
- data/spec/apps/kitchen_sink/app/main/controllers/todos_controller.rb +4 -2
- data/spec/apps/kitchen_sink/app/main/models/post.rb +0 -1
- data/spec/apps/kitchen_sink/app/main/models/todo.rb +4 -0
- data/spec/apps/kitchen_sink/app/main/views/mailers/reset_password.html +10 -0
- data/spec/apps/kitchen_sink/app/main/views/todos/index.html +2 -0
- data/spec/apps/kitchen_sink/config/app.rb +2 -0
- data/spec/apps/migrations/config/db/migrations/1445111704_migration1.rb +7 -0
- data/spec/apps/migrations/config/db/migrations/1445113517_migration2.rb +7 -0
- data/spec/apps/migrations/config/db/migrations/1445115200_migration3.rb +7 -0
- data/spec/extra_core/class_spec.rb +10 -0
- data/spec/helpers/distance_spec.rb +35 -0
- data/spec/helpers/duration_spec.rb +160 -0
- data/spec/helpers/volt_time_spec.rb +275 -0
- data/spec/integration/callbacks_spec.rb +2 -1
- data/spec/integration/http_endpoints_spec.rb +4 -0
- data/spec/integration/save_spec.rb +1 -1
- data/spec/integration/todos_spec.rb +7 -5
- data/spec/models/array_model_spec.rb +17 -3
- data/spec/models/associations_spec.rb +48 -1
- data/spec/models/field_helpers_spec.rb +7 -3
- data/spec/models/migrations/migration_runner_spec.rb +69 -0
- data/spec/models/model_spec.rb +42 -8
- data/spec/models/permissions_spec.rb +20 -8
- data/spec/models/persistors/array_store_spec.rb +18 -0
- data/spec/models/persistors/page_spec.rb +15 -10
- data/spec/models/persistors/store_spec.rb +13 -3
- data/spec/models/url_spec.rb +4 -3
- data/spec/models/user_spec.rb +6 -3
- data/spec/models/user_validation_spec.rb +3 -3
- data/spec/models/validations_spec.rb +4 -0
- data/spec/models/validators/block_validations_spec.rb +9 -5
- data/spec/models/validators/email_validator_spec.rb +2 -0
- data/spec/models/validators/lifecycle_callbacks_spec.rb +86 -0
- data/spec/models/validators/unique_validator_spec.rb +1 -0
- data/spec/page/path_string_renderer_spec.rb +5 -0
- data/spec/queries/live_query_spec.rb +16 -0
- data/spec/queries/query_association_splitter_spec.rb +14 -0
- data/spec/queries/query_diff_spec.rb +132 -0
- data/spec/queries/query_identifier_spec.rb +98 -0
- data/spec/queries/query_runner_spec.rb +63 -0
- data/spec/queries/query_tracker_spec.rb +141 -0
- data/spec/router/routes_spec.rb +52 -21
- data/spec/server/middleware/rack_content_types_spec.rb +78 -0
- data/spec/server/rack/asset_files_spec.rb +38 -30
- data/spec/spec_helper.rb +8 -0
- data/spec/utils/ejson_spec.rb +9 -8
- data/spec/utils/ejson_volt_time_spec.rb +65 -0
- data/templates/migration/migration.rb.tt +9 -0
- data/templates/newgem/gitignore.tt +1 -0
- data/templates/project/Gemfile.tt +19 -2
- data/templates/project/README.md.tt +6 -1
- data/templates/project/app/main/config/dependencies.rb +6 -0
- data/templates/project/config/app.rb.tt +18 -4
- data/volt.gemspec +2 -2
- metadata +73 -16
- data/app/volt/tasks/live_query/live_query_pool.rb +0 -48
- data/app/volt/tasks/live_query/query_tracker.rb +0 -92
- data/spec/tasks/live_query_spec.rb +0 -18
- data/spec/tasks/query_tasks.rb +0 -7
- data/spec/tasks/query_tracker_spec.rb +0 -145
|
@@ -4,6 +4,7 @@ describe 'todos app', type: :feature, sauce: true do
|
|
|
4
4
|
ENTER_KEY = ENV["BROWSER"] == 'phantom' ? :Enter : :return
|
|
5
5
|
it 'should add a todo and remove it' do
|
|
6
6
|
visit '/todos'
|
|
7
|
+
store._todos
|
|
7
8
|
|
|
8
9
|
fill_in 'newtodo', with: 'Todo 1'
|
|
9
10
|
find('#newtodo').native.send_keys(ENTER_KEY)
|
|
@@ -18,15 +19,16 @@ describe 'todos app', type: :feature, sauce: true do
|
|
|
18
19
|
|
|
19
20
|
# Make sure it deleted
|
|
20
21
|
if ENV['BROWSER'] == 'phantom'
|
|
21
|
-
|
|
22
|
+
visit '/todos'
|
|
22
23
|
else
|
|
23
|
-
|
|
24
|
+
page.driver.browser.navigate.refresh
|
|
24
25
|
end
|
|
25
26
|
expect(page).to_not have_content('Todo 1')
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
it 'should update a todo check state and persist' do
|
|
29
30
|
visit '/todos'
|
|
31
|
+
store._todos
|
|
30
32
|
|
|
31
33
|
fill_in 'newtodo', with: 'Todo 1'
|
|
32
34
|
find('#newtodo').native.send_keys(ENTER_KEY)
|
|
@@ -36,11 +38,11 @@ describe 'todos app', type: :feature, sauce: true do
|
|
|
36
38
|
find("input[type='checkbox']").click
|
|
37
39
|
|
|
38
40
|
if ENV['BROWSER'] == 'phantom'
|
|
39
|
-
|
|
41
|
+
visit '/todos'
|
|
40
42
|
else
|
|
41
|
-
|
|
43
|
+
page.evaluate_script('document.location.reload()')
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
expect(find("input[type='checkbox']").checked?).to eq(true)
|
|
45
47
|
end
|
|
46
|
-
end
|
|
48
|
+
end
|
|
@@ -4,8 +4,11 @@ require 'spec_helper'
|
|
|
4
4
|
# ArrayModel specs here.
|
|
5
5
|
describe Volt::ArrayModel do
|
|
6
6
|
unless RUBY_PLATFORM == 'opal'
|
|
7
|
+
class Post < Volt::Model
|
|
8
|
+
end
|
|
9
|
+
|
|
7
10
|
it 'should return a Promise for empty? on store' do
|
|
8
|
-
expect(store.
|
|
11
|
+
expect(store.posts.empty?.class).to eq(Promise)
|
|
9
12
|
end
|
|
10
13
|
end
|
|
11
14
|
|
|
@@ -39,12 +42,23 @@ describe Volt::ArrayModel do
|
|
|
39
42
|
expect(array.to_a.flatten.size).to eq(6)
|
|
40
43
|
end
|
|
41
44
|
|
|
45
|
+
it 'should not equal another array model with the same content' do
|
|
46
|
+
a = Volt::ArrayModel.new([])
|
|
47
|
+
b = Volt::ArrayModel.new([])
|
|
48
|
+
|
|
49
|
+
expect(a == b).to eq(false)
|
|
50
|
+
expect(a == a).to eq(true)
|
|
51
|
+
end
|
|
52
|
+
|
|
42
53
|
unless RUBY_PLATFORM == 'opal'
|
|
54
|
+
class Item < Volt::Model
|
|
55
|
+
end
|
|
56
|
+
|
|
43
57
|
it 'should return a promise for store on .length, .size, and .count' do
|
|
44
|
-
store.
|
|
58
|
+
store.items << {name: 'One'}
|
|
45
59
|
|
|
46
60
|
[:size, :count, :length].each do |method_name|
|
|
47
|
-
val = store.
|
|
61
|
+
val = store.items.send(method_name)
|
|
48
62
|
expect(val.class).to eq(Promise)
|
|
49
63
|
expect(val.sync).to eq(1)
|
|
50
64
|
end
|
|
@@ -3,7 +3,6 @@ require 'spec_helper'
|
|
|
3
3
|
class ::Person < Volt::Model
|
|
4
4
|
has_many :addresses
|
|
5
5
|
end
|
|
6
|
-
|
|
7
6
|
class ::Address < Volt::Model
|
|
8
7
|
belongs_to :person
|
|
9
8
|
has_one :zip_info
|
|
@@ -30,6 +29,7 @@ describe Volt::Associations do
|
|
|
30
29
|
it 'should associate via belongs_to' do
|
|
31
30
|
address = store.addresses.first.sync
|
|
32
31
|
|
|
32
|
+
# binding.pry
|
|
33
33
|
expect(address.person_id).to eq(@person.id)
|
|
34
34
|
expect(address.person.sync.id).to eq(@person.id)
|
|
35
35
|
end
|
|
@@ -90,5 +90,52 @@ describe Volt::Associations do
|
|
|
90
90
|
expect(bob.addresses[0].sync.person_id).to eq(bob.id)
|
|
91
91
|
expect(bob.id).to_not eq(nil)
|
|
92
92
|
end
|
|
93
|
+
|
|
94
|
+
it 'should raise an exception when defining an association with an already used name' do
|
|
95
|
+
expect do
|
|
96
|
+
Class.new(Volt::Model) do
|
|
97
|
+
set_collection_name :temp1
|
|
98
|
+
has_many :ones
|
|
99
|
+
has_many :ones
|
|
100
|
+
end
|
|
101
|
+
end.to raise_error(/An association is already defined for `ones`/)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it 'should track association data' do
|
|
105
|
+
expect(AddressBelongToOption.associations[:someone]).to eq(
|
|
106
|
+
{
|
|
107
|
+
:type=>:belongs_to,
|
|
108
|
+
:collection=>:people,
|
|
109
|
+
:foreign_key=>:id,
|
|
110
|
+
:local_key=>:some_weird_id,
|
|
111
|
+
:to_many=>false
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
expect(Person.associations[:addresses]).to eq(
|
|
116
|
+
{
|
|
117
|
+
:type=>:has_many,
|
|
118
|
+
:to_many=>true,
|
|
119
|
+
:collection=>:addresses,
|
|
120
|
+
:foreign_key=>:person_id,
|
|
121
|
+
:local_key=>:id
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
expect(Address.associations[:zip_info]).to eq({
|
|
125
|
+
:type=>:has_one,
|
|
126
|
+
:to_many=>false,
|
|
127
|
+
:collection=>:zip_infos,
|
|
128
|
+
:foreign_key=>:address_id,
|
|
129
|
+
:local_key=>:id
|
|
130
|
+
})
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# it 'should let you assign belongs_to' do
|
|
134
|
+
# bob = ::Person.new
|
|
135
|
+
|
|
136
|
+
# address = ::Address.new
|
|
137
|
+
|
|
138
|
+
# expect(address.person).to eq(nil)
|
|
139
|
+
# end
|
|
93
140
|
end
|
|
94
141
|
end
|
|
@@ -27,7 +27,7 @@ describe 'field helpers' do
|
|
|
27
27
|
it 'should raise an error when an invalid cast type is provided' do
|
|
28
28
|
expect do
|
|
29
29
|
ExampleModelWithField2.field :awesome, Range
|
|
30
|
-
end.to raise_error(FieldHelpers::InvalidFieldClass)
|
|
30
|
+
end.to raise_error(Volt::FieldHelpers::InvalidFieldClass)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it 'should convert numeric strings to Fixnum when Fixnum is specified as a type restriction' do
|
|
@@ -41,12 +41,16 @@ describe 'field helpers' do
|
|
|
41
41
|
buf.value = 'cats'
|
|
42
42
|
expect(buf.value).to eq('cats')
|
|
43
43
|
|
|
44
|
+
fail_called = false
|
|
44
45
|
buf.validate!.fail do |error|
|
|
45
|
-
|
|
46
|
+
fail_called = true
|
|
47
|
+
expect(error).to eq({'value' => ['must be a number']})
|
|
46
48
|
end
|
|
49
|
+
|
|
50
|
+
expect(fail_called).to eq(true)
|
|
47
51
|
end
|
|
48
52
|
|
|
49
53
|
it 'should track the fields on the model class' do
|
|
50
|
-
expect(ExampleModelWithField.
|
|
54
|
+
expect(ExampleModelWithField.fields).to eq({:name=>[nil, {}], :value=>[[Numeric, NilClass], {}]})
|
|
51
55
|
end
|
|
52
56
|
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
unless RUBY_PLATFORM == 'opal'
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'volt/models/migrations/migration_runner'
|
|
4
|
+
|
|
5
|
+
describe Volt::MigrationRunner do
|
|
6
|
+
let(:migration_app_path) { File.expand_path("#{File.dirname(__FILE__)}/../../apps/migrations") }
|
|
7
|
+
let(:migration_folder) { File.expand_path("#{migration_app_path}/config/db/migrations") }
|
|
8
|
+
let(:runner) { Volt::MigrationRunner.new }
|
|
9
|
+
after do
|
|
10
|
+
# Migration runner changes the db, but doesn't touch store, so cleanup
|
|
11
|
+
# manually after.
|
|
12
|
+
cleanup_db
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'should run migrations that have not been run yet' do
|
|
16
|
+
expect(runner.has_version?(1445111704)).to eq(false)
|
|
17
|
+
|
|
18
|
+
runner.run_migration("#{migration_folder}/1445111704_migration1.rb", :up)
|
|
19
|
+
|
|
20
|
+
expect(runner.has_version?(1445111704)).to eq(true)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'should migrate up and down' do
|
|
24
|
+
count = runner.all_versions.size
|
|
25
|
+
expect(count).to eq(0)
|
|
26
|
+
|
|
27
|
+
expect(Volt).to receive(:root).and_return(migration_app_path).at_least(:once)
|
|
28
|
+
|
|
29
|
+
runner.run(:up)
|
|
30
|
+
|
|
31
|
+
count = runner.all_versions.size
|
|
32
|
+
expect(count).to eq(3)
|
|
33
|
+
|
|
34
|
+
runner.run(:down)
|
|
35
|
+
|
|
36
|
+
count = runner.all_versions.size
|
|
37
|
+
expect(count).to eq(0)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'should migrate up until a number' do
|
|
41
|
+
count = runner.all_versions.size
|
|
42
|
+
expect(count).to eq(0)
|
|
43
|
+
|
|
44
|
+
expect(Volt).to receive(:root).and_return(migration_app_path).at_least(:once)
|
|
45
|
+
|
|
46
|
+
runner.run(:up, 1445113517)
|
|
47
|
+
|
|
48
|
+
count = runner.all_versions.size
|
|
49
|
+
expect(count).to eq(2)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'should migrate down to a version number' do
|
|
53
|
+
count = runner.all_versions.size
|
|
54
|
+
expect(count).to eq(0)
|
|
55
|
+
|
|
56
|
+
expect(Volt).to receive(:root).and_return(migration_app_path).at_least(:once)
|
|
57
|
+
|
|
58
|
+
runner.run(:up)
|
|
59
|
+
|
|
60
|
+
count = runner.all_versions.size
|
|
61
|
+
expect(count).to eq(3)
|
|
62
|
+
|
|
63
|
+
runner.run(:down, 1445113517)
|
|
64
|
+
|
|
65
|
+
count = runner.all_versions.size
|
|
66
|
+
expect(count).to eq(1)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
data/spec/models/model_spec.rb
CHANGED
|
@@ -12,12 +12,21 @@ end
|
|
|
12
12
|
class SubItem < Item
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
class Todo < Volt::Model
|
|
16
|
+
# field :label, String
|
|
17
|
+
end
|
|
18
|
+
|
|
15
19
|
class TestAssignsMethod < Volt::Model
|
|
16
20
|
def name=(val)
|
|
17
21
|
self._name = val
|
|
18
22
|
end
|
|
19
23
|
end
|
|
20
24
|
|
|
25
|
+
class TempModel < Volt::Model
|
|
26
|
+
temporary
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
|
|
21
30
|
describe Volt::Model do
|
|
22
31
|
it 'delegates unary operator to its attributes' do
|
|
23
32
|
model = Volt::Model.new
|
|
@@ -569,8 +578,8 @@ describe Volt::Model do
|
|
|
569
578
|
|
|
570
579
|
if RUBY_PLATFORM != 'opal'
|
|
571
580
|
it 'should update other queries on the server when a new model is created' do
|
|
572
|
-
query1 = store.
|
|
573
|
-
query2 = store.
|
|
581
|
+
query1 = store.todos
|
|
582
|
+
query2 = store.todos.limit(1)
|
|
574
583
|
|
|
575
584
|
count = 0
|
|
576
585
|
|
|
@@ -579,7 +588,7 @@ describe Volt::Model do
|
|
|
579
588
|
|
|
580
589
|
expect(count).to eq(0)
|
|
581
590
|
|
|
582
|
-
query1
|
|
591
|
+
query1.create({ label: 'One' })
|
|
583
592
|
|
|
584
593
|
count = 0
|
|
585
594
|
query2.all.each { |v| count += 1 }
|
|
@@ -605,7 +614,7 @@ describe Volt::Model do
|
|
|
605
614
|
it 'fails if attempting to destroy while parentless' do
|
|
606
615
|
model = Volt::Model.new(test: "yeah")
|
|
607
616
|
expect { model.destroy }.to raise_error(RuntimeError,
|
|
608
|
-
|
|
617
|
+
'Model does not have a parent and cannot be deleted.')
|
|
609
618
|
end
|
|
610
619
|
end
|
|
611
620
|
|
|
@@ -619,10 +628,31 @@ describe Volt::Model do
|
|
|
619
628
|
end
|
|
620
629
|
end
|
|
621
630
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
631
|
+
describe "Wrapping" do
|
|
632
|
+
it 'creates sub-arrays with correct classes' do
|
|
633
|
+
model = Volt::Model.new
|
|
634
|
+
model._items << {}
|
|
635
|
+
expect(model._items).to be_instance_of Items
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
it 'creates sub-hashes when using nested hashes' do
|
|
639
|
+
model = Volt::Model.new({name: 'Bob', stuff: {arm: true, leg: true}})
|
|
640
|
+
|
|
641
|
+
expect(model._name).to eq('Bob')
|
|
642
|
+
expect(model._stuff._arm).to eq(true)
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
it 'should wrap subcollections on new' do
|
|
646
|
+
model = Volt::Model.new(name: 'Bob', items: [{name: 'Item 1'}, {name: 'Item 2'}])
|
|
647
|
+
|
|
648
|
+
expect(model._items[1]._name).to eq('Item 2')
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
it 'should new off of a collection' do
|
|
652
|
+
item = the_page._items.new({name: 'Bob'})
|
|
653
|
+
expect(item._name).to eq('Bob')
|
|
654
|
+
expect(item.class).to eq(Item)
|
|
655
|
+
end
|
|
626
656
|
end
|
|
627
657
|
|
|
628
658
|
it 'assigns the superclass\'s custom ArrayModel if it exists' do
|
|
@@ -630,4 +660,8 @@ describe Volt::Model do
|
|
|
630
660
|
model._sub_items << {}
|
|
631
661
|
expect(model._sub_items).to be_instance_of Items
|
|
632
662
|
end
|
|
663
|
+
|
|
664
|
+
it 'should allow a temporary flag to be set' do
|
|
665
|
+
expect(TempModel.is_temporary).to eq(true)
|
|
666
|
+
end
|
|
633
667
|
end
|
|
@@ -91,9 +91,21 @@ describe 'model permissions' do
|
|
|
91
91
|
# end
|
|
92
92
|
|
|
93
93
|
if RUBY_PLATFORM != 'opal'
|
|
94
|
+
class TestDenyReadName < Volt::Model
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
class TestDenyDelete < Volt::Model
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
class TestUpdateReadCheck < Volt::Model
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
class TestPromisePermission < Volt::Model
|
|
104
|
+
end
|
|
105
|
+
|
|
94
106
|
describe 'read permissions' do
|
|
95
107
|
it 'should deny read on a field' do
|
|
96
|
-
model = store.
|
|
108
|
+
model = store.test_deny_read_names.buffer
|
|
97
109
|
model._name = 'Jimmy'
|
|
98
110
|
model._other = 'should be visible'
|
|
99
111
|
|
|
@@ -102,7 +114,7 @@ describe 'model permissions' do
|
|
|
102
114
|
# Clear the identity map, so we can load up a fresh copy
|
|
103
115
|
model.save_to.persistor.clear_identity_map
|
|
104
116
|
|
|
105
|
-
reloaded = store.
|
|
117
|
+
reloaded = store.test_deny_read_names.first.sync
|
|
106
118
|
|
|
107
119
|
expect(reloaded._name).to eq(nil)
|
|
108
120
|
expect(reloaded._other).to eq('should be visible')
|
|
@@ -110,13 +122,13 @@ describe 'model permissions' do
|
|
|
110
122
|
end
|
|
111
123
|
|
|
112
124
|
it 'should prevent delete if denied' do
|
|
113
|
-
model = store.
|
|
125
|
+
model = store.test_deny_deletes.buffer
|
|
114
126
|
|
|
115
127
|
model.save!.then do
|
|
116
128
|
# Saved
|
|
117
129
|
count = 0
|
|
118
130
|
|
|
119
|
-
store.
|
|
131
|
+
store.test_deny_deletes.delete(model).fail do |err|
|
|
120
132
|
# deleted
|
|
121
133
|
count += 1
|
|
122
134
|
|
|
@@ -129,7 +141,7 @@ describe 'model permissions' do
|
|
|
129
141
|
end
|
|
130
142
|
|
|
131
143
|
it 'should not check the read permissions when updating (so that all fields are present for the permissions check)' do
|
|
132
|
-
model = store.
|
|
144
|
+
model = store.test_update_read_checks.append(name: 'Ryan').sync
|
|
133
145
|
|
|
134
146
|
expect(model.new?).to eq(false)
|
|
135
147
|
|
|
@@ -144,7 +156,7 @@ describe 'model permissions' do
|
|
|
144
156
|
end
|
|
145
157
|
|
|
146
158
|
it 'should not check read permissions on buffer save on server' do
|
|
147
|
-
model = store.
|
|
159
|
+
model = store.test_update_read_checks.buffer
|
|
148
160
|
|
|
149
161
|
model._name = 'Ryan'
|
|
150
162
|
|
|
@@ -164,7 +176,7 @@ describe 'model permissions' do
|
|
|
164
176
|
end
|
|
165
177
|
|
|
166
178
|
it 'should not check read on delete, so all fields are available to the permissions block' do
|
|
167
|
-
model = store.
|
|
179
|
+
model = store.test_update_read_checks.append(name: 'Ryan').sync
|
|
168
180
|
|
|
169
181
|
expect(model.read_check).to eq(nil)
|
|
170
182
|
|
|
@@ -174,7 +186,7 @@ describe 'model permissions' do
|
|
|
174
186
|
end
|
|
175
187
|
|
|
176
188
|
it 'should allow permission blocks to return a promise' do
|
|
177
|
-
promise = store.
|
|
189
|
+
promise = store.test_promise_permissions.create({})
|
|
178
190
|
|
|
179
191
|
expect(promise.resolved?).to eq(false)
|
|
180
192
|
expect(promise.rejected?).to eq(false)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
unless RUBY_PLATFORM == 'opal'
|
|
4
|
+
describe Volt::Persistors::ArrayStore do
|
|
5
|
+
it 'should make a Cursor using :where_with_block when passing a block to where' do
|
|
6
|
+
cursor = store._users.where({name: 'Bob'}) {|v| v.location == 'Bozeman' }
|
|
7
|
+
|
|
8
|
+
expect(cursor.options[:query]).to eq(
|
|
9
|
+
[
|
|
10
|
+
[
|
|
11
|
+
"where_with_block",
|
|
12
|
+
{:name=>"Bob"},
|
|
13
|
+
["c", ["c", "ident", "location"], "==", "Bozeman"]]
|
|
14
|
+
]
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|