volt 0.9.3.pre3 → 0.9.3.pre4
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/CHANGELOG.md +6 -2
- data/app/volt/models/user.rb +5 -0
- data/app/volt/tasks/store_tasks.rb +2 -2
- data/app/volt/tasks/user_tasks.rb +1 -1
- data/lib/volt/cli/asset_compile.rb +0 -2
- data/lib/volt/cli/generate.rb +8 -3
- data/lib/volt/cli.rb +3 -9
- data/lib/volt/controllers/actions.rb +6 -1
- data/lib/volt/controllers/http_controller.rb +16 -7
- data/lib/volt/controllers/model_controller.rb +21 -0
- data/lib/volt/models/array_model.rb +26 -3
- data/lib/volt/models/model.rb +18 -19
- data/lib/volt/models/persistors/array_store.rb +2 -10
- data/lib/volt/models/root_models/store_root.rb +17 -4
- data/lib/volt/models/validations/validations.rb +1 -1
- data/lib/volt/models/validators/unique_validator.rb +1 -1
- data/lib/volt/models.rb +1 -1
- data/lib/volt/page/bindings/attribute_binding.rb +5 -4
- data/lib/volt/page/bindings/base_binding.rb +17 -0
- data/lib/volt/page/bindings/content_binding.rb +7 -5
- data/lib/volt/page/bindings/each_binding.rb +62 -51
- data/lib/volt/page/bindings/event_binding.rb +14 -0
- data/lib/volt/page/bindings/view_binding.rb +1 -1
- data/lib/volt/reactive/computation.rb +22 -13
- data/lib/volt/reactive/dependency.rb +0 -24
- data/lib/volt/router/routes.rb +35 -0
- data/lib/volt/server/forking_server.rb +26 -3
- data/lib/volt/server/message_bus/peer_to_peer/peer_connection.rb +1 -1
- data/lib/volt/server/message_bus/peer_to_peer/server_tracker.rb +1 -1
- data/lib/volt/server/message_bus/peer_to_peer.rb +28 -21
- data/lib/volt/server/middleware/default_middleware_stack.rb +67 -0
- data/lib/volt/server/middleware/middleware_stack.rb +58 -0
- data/lib/volt/server/rack/http_request.rb +1 -1
- data/lib/volt/server/rack/http_resource.rb +7 -0
- data/lib/volt/server/rack/keep_alive.rb +20 -0
- data/lib/volt/server/socket_connection_handler.rb +10 -1
- data/lib/volt/server.rb +6 -76
- data/lib/volt/utils/promise_extensions.rb +5 -1
- data/lib/volt/utils/set_patch.rb +25 -0
- data/lib/volt/utils/timers.rb +12 -0
- data/lib/volt/version.rb +1 -1
- data/lib/volt/volt/app.rb +13 -1
- data/lib/volt/volt/server_setup/app.rb +19 -1
- data/lib/volt/volt/users.rb +11 -22
- data/lib/volt.rb +1 -0
- data/spec/apps/kitchen_sink/Gemfile +1 -1
- data/spec/apps/kitchen_sink/app/main/config/routes.rb +1 -1
- data/spec/apps/kitchen_sink/app/main/controllers/main_controller.rb +22 -0
- data/spec/apps/kitchen_sink/app/main/views/main/bindings.html +10 -0
- data/spec/apps/kitchen_sink/app/main/views/main/store_demo.html +9 -0
- data/spec/controllers/http_controller_spec.rb +27 -0
- data/spec/integration/bindings_spec.rb +29 -0
- data/spec/integration/store_spec.rb +7 -7
- data/spec/models/associations_spec.rb +1 -1
- data/spec/models/model_spec.rb +10 -0
- data/spec/models/permissions_spec.rb +7 -4
- data/spec/reactive/computation_spec.rb +33 -5
- data/spec/router/routes_spec.rb +69 -0
- data/spec/server/middleware/middleware_handler.rb +24 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/tasks/user_tasks_spec.rb +3 -2
- data/templates/project/Gemfile.tt +2 -2
- data/templates/project/config/base/index.html +5 -1
- metadata +10 -5
- data/spec/apps/kitchen_sink/app/main/views/main/store.html +0 -9
- data/templates/project/app/main/models/.empty_directory +0 -0
@@ -38,7 +38,16 @@ module Volt
|
|
38
38
|
# Messages are json and wrapped in an array
|
39
39
|
message = JSON.parse(message).first
|
40
40
|
|
41
|
-
|
41
|
+
begin
|
42
|
+
@@dispatcher.dispatch(self, message)
|
43
|
+
rescue => e
|
44
|
+
if defined?(DRb::DRbConnError) && e.is_a?(DRb::DRbConnError)
|
45
|
+
# The child process was restarting, so drb failed to send
|
46
|
+
else
|
47
|
+
# re-raise the issue
|
48
|
+
raise
|
49
|
+
end
|
50
|
+
end
|
42
51
|
end
|
43
52
|
|
44
53
|
def send_message(*args)
|
data/lib/volt/server.rb
CHANGED
@@ -7,43 +7,17 @@ require 'sass'
|
|
7
7
|
require 'volt/utils/tilt_patch'
|
8
8
|
require 'sprockets-sass'
|
9
9
|
|
10
|
-
|
11
10
|
require 'volt'
|
12
11
|
require 'volt/tasks/dispatcher'
|
13
12
|
require 'volt/tasks/task'
|
14
13
|
require 'volt/server/component_handler'
|
15
14
|
require 'volt/server/rack/component_paths'
|
16
|
-
require 'volt/server/rack/index_files'
|
17
|
-
require 'volt/server/rack/http_resource'
|
18
|
-
require 'volt/server/rack/opal_files'
|
19
|
-
require 'volt/server/rack/quiet_common_logger'
|
20
15
|
require 'volt/page/page'
|
21
16
|
|
22
|
-
require 'volt/volt/core'
|
23
17
|
require 'volt/server/websocket/websocket_handler'
|
24
18
|
require 'volt/utils/read_write_lock'
|
25
19
|
require 'volt/server/forking_server'
|
26
20
|
|
27
|
-
module Rack
|
28
|
-
# TODO: For some reason in Rack (or maybe thin), 304 headers close
|
29
|
-
# the http connection. We might need to make this check if keep
|
30
|
-
# alive was in the request.
|
31
|
-
class KeepAlive
|
32
|
-
def initialize(app)
|
33
|
-
@app = app
|
34
|
-
end
|
35
|
-
|
36
|
-
def call(env)
|
37
|
-
status, headers, body = @app.call(env)
|
38
|
-
|
39
|
-
if status == 304 && env['HTTP_CONNECTION'] && env['HTTP_CONNECTION'].downcase == 'keep-alive'
|
40
|
-
headers['Connection'] = 'keep-alive'
|
41
|
-
end
|
42
|
-
|
43
|
-
[status, headers, body]
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
21
|
|
48
22
|
module Volt
|
49
23
|
class Server
|
@@ -54,7 +28,7 @@ module Volt
|
|
54
28
|
@root_path = root_path || Dir.pwd
|
55
29
|
@volt_app = app
|
56
30
|
|
57
|
-
@app_path
|
31
|
+
@app_path = File.expand_path(File.join(@root_path, 'app'))
|
58
32
|
|
59
33
|
display_welcome
|
60
34
|
end
|
@@ -70,7 +44,10 @@ module Volt
|
|
70
44
|
@volt_app ||= Volt.boot(@root_path)
|
71
45
|
end
|
72
46
|
|
73
|
-
# App returns the main rack app. In development it will
|
47
|
+
# App returns the main rack app. In development it will use ForkingServer,
|
48
|
+
# which forks the app and processes responses in a child process, that is
|
49
|
+
# killed when code changes and reforked. (This provides simple fast code
|
50
|
+
# reloading)
|
74
51
|
def app
|
75
52
|
app = Rack::Builder.new
|
76
53
|
|
@@ -94,7 +71,7 @@ module Volt
|
|
94
71
|
|
95
72
|
# Setup the dispatcher (it stays this class during its run)
|
96
73
|
SocketConnectionHandler.dispatcher = Dispatcher.new(@volt_app)
|
97
|
-
app.run(
|
74
|
+
app.run(@volt_app.middleware)
|
98
75
|
else
|
99
76
|
# In developer
|
100
77
|
app.run ForkingServer.new(self)
|
@@ -102,52 +79,5 @@ module Volt
|
|
102
79
|
|
103
80
|
app
|
104
81
|
end
|
105
|
-
|
106
|
-
# new_server returns the core of the Rack app.
|
107
|
-
# Volt.boot should be called before generating the new server
|
108
|
-
def new_server
|
109
|
-
@rack_app = Rack::Builder.new
|
110
|
-
|
111
|
-
# Should only be used in production
|
112
|
-
if Volt.config.deflate
|
113
|
-
@rack_app.use Rack::Deflater
|
114
|
-
@rack_app.use Rack::Chunked
|
115
|
-
end
|
116
|
-
|
117
|
-
@rack_app.use Rack::ContentLength
|
118
|
-
|
119
|
-
@rack_app.use Rack::KeepAlive
|
120
|
-
@rack_app.use Rack::ConditionalGet
|
121
|
-
@rack_app.use Rack::ETag
|
122
|
-
|
123
|
-
@rack_app.use QuietCommonLogger
|
124
|
-
@rack_app.use Rack::ShowExceptions
|
125
|
-
|
126
|
-
component_paths = @volt_app.component_paths
|
127
|
-
@rack_app.map '/components' do
|
128
|
-
run ComponentHandler.new(component_paths)
|
129
|
-
end
|
130
|
-
|
131
|
-
# Serve the opal files
|
132
|
-
opal_files = OpalFiles.new(@rack_app, @app_path, @volt_app.component_paths)
|
133
|
-
|
134
|
-
# Serve the main html files from public, also figure out
|
135
|
-
# which JS/CSS files to serve.
|
136
|
-
@rack_app.use IndexFiles, @volt_app, @volt_app.component_paths, opal_files
|
137
|
-
|
138
|
-
@rack_app.use HttpResource, @volt_app, @volt_app.router
|
139
|
-
|
140
|
-
@rack_app.use Rack::Static,
|
141
|
-
urls: ['/'],
|
142
|
-
root: 'config/base',
|
143
|
-
index: '',
|
144
|
-
header_rules: [
|
145
|
-
[:all, { 'Cache-Control' => 'public, max-age=86400' }]
|
146
|
-
]
|
147
|
-
|
148
|
-
@rack_app.run lambda { |env| [404, { 'Content-Type' => 'text/html; charset=utf-8' }, ['404 - page not found']] }
|
149
|
-
|
150
|
-
@rack_app
|
151
|
-
end
|
152
82
|
end
|
153
83
|
end
|
@@ -12,6 +12,10 @@ class Promise
|
|
12
12
|
promise
|
13
13
|
end
|
14
14
|
|
15
|
+
def respond_to_missing(method_name, include_private = false)
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
15
19
|
# Allow .each to be called directly on promises
|
16
20
|
def each(&block)
|
17
21
|
raise ArgumentError, 'no block given' unless block
|
@@ -69,7 +73,7 @@ class Promise
|
|
69
73
|
|
70
74
|
if error
|
71
75
|
err_str = "Exception in Promise at .sync: #{error.inspect}"
|
72
|
-
err_str += error.backtrace.join("\n")
|
76
|
+
err_str += error.backtrace.join("\n") if error.respond_to?(:backtrace)
|
73
77
|
Volt.logger.error(err_str)
|
74
78
|
fail error
|
75
79
|
else
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Temp until https://github.com/opal/opal/pull/596
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
class Set
|
5
|
+
def delete(o)
|
6
|
+
if include?(o)
|
7
|
+
@hash.delete(o)
|
8
|
+
true
|
9
|
+
else
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete_if
|
15
|
+
block_given? or return enum_for(__method__)
|
16
|
+
# @hash.delete_if should be faster, but using it breaks the order
|
17
|
+
# of enumeration in subclasses.
|
18
|
+
select { |o| yield o }.each { |o| @hash.delete(o) }
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_a
|
23
|
+
@hash.keys
|
24
|
+
end
|
25
|
+
end
|
data/lib/volt/utils/timers.rb
CHANGED
@@ -14,6 +14,18 @@ module Volt
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
# yields the passed in block after interval ms, or immediately if on the
|
18
|
+
# server.
|
19
|
+
def self.client_set_timeout(interval)
|
20
|
+
if Volt.in_browser?
|
21
|
+
`setTimeout(function() {`
|
22
|
+
yield
|
23
|
+
`}, interval)`
|
24
|
+
else
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
17
29
|
# On the server, we need to manually flush next tick timers.
|
18
30
|
# This is done automatically in the console after each enter.
|
19
31
|
def self.flush_next_tick_timers!
|
data/lib/volt/version.rb
CHANGED
data/lib/volt/volt/app.rb
CHANGED
@@ -37,7 +37,8 @@ module Volt
|
|
37
37
|
end
|
38
38
|
|
39
39
|
attr_reader :component_paths, :router, :page, :live_query_pool,
|
40
|
-
:channel_live_queries, :app_path, :database, :message_bus
|
40
|
+
:channel_live_queries, :app_path, :database, :message_bus,
|
41
|
+
:middleware
|
41
42
|
|
42
43
|
def initialize(app_path=nil)
|
43
44
|
if Volt.server? && !app_path
|
@@ -53,6 +54,14 @@ module Volt
|
|
53
54
|
setup_page
|
54
55
|
|
55
56
|
if RUBY_PLATFORM != 'opal'
|
57
|
+
# We need to run the root config first so we can setup the Rack::Session
|
58
|
+
# middleware.
|
59
|
+
run_config
|
60
|
+
|
61
|
+
# Setup all of the middleware we can before we load the users components
|
62
|
+
# since the users components might want to add middleware during boot.
|
63
|
+
setup_preboot_middleware
|
64
|
+
|
56
65
|
# Setup all app paths
|
57
66
|
setup_paths
|
58
67
|
|
@@ -69,6 +78,9 @@ module Volt
|
|
69
78
|
|
70
79
|
reset_query_pool!
|
71
80
|
|
81
|
+
# Setup the middleware that we can only setup after all components boot.
|
82
|
+
setup_postboot_middleware
|
83
|
+
|
72
84
|
start_message_bus
|
73
85
|
end
|
74
86
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
# The following setup handles setting up the app on the server.
|
2
2
|
unless RUBY_PLATFORM == 'opal'
|
3
3
|
require 'volt/server/message_bus/peer_to_peer'
|
4
|
+
require 'volt/server/middleware/middleware_stack'
|
5
|
+
require 'volt/server/middleware/default_middleware_stack'
|
6
|
+
require 'volt/volt/core'
|
7
|
+
|
4
8
|
end
|
5
9
|
|
6
10
|
module Volt
|
@@ -21,6 +25,16 @@ module Volt
|
|
21
25
|
@router = Routes.new
|
22
26
|
end
|
23
27
|
|
28
|
+
|
29
|
+
def setup_preboot_middleware
|
30
|
+
@middleware = MiddlewareStack.new
|
31
|
+
DefaultMiddlewareStack.preboot_setup(self, @middleware)
|
32
|
+
end
|
33
|
+
|
34
|
+
def setup_postboot_middleware
|
35
|
+
DefaultMiddlewareStack.postboot_setup(self, @middleware)
|
36
|
+
end
|
37
|
+
|
24
38
|
def require_http_controllers
|
25
39
|
@component_paths.app_folders do |app_folder|
|
26
40
|
# Sort so we get consistent load order across platforms
|
@@ -32,11 +46,15 @@ module Volt
|
|
32
46
|
end
|
33
47
|
end
|
34
48
|
|
49
|
+
# This config needs to run earlier than others
|
50
|
+
def run_config
|
51
|
+
require("#{Volt.root}/config/app.rb")
|
52
|
+
end
|
35
53
|
|
36
54
|
# Load in all .rb files in the initializers folders and the config/app.rb
|
37
55
|
# file.
|
38
56
|
def run_app_and_initializers
|
39
|
-
files = [
|
57
|
+
files = []
|
40
58
|
|
41
59
|
# Include the root initializers
|
42
60
|
files += Dir[Volt.root + '/config/initializers/*.rb']
|
data/lib/volt/volt/users.rb
CHANGED
@@ -53,13 +53,19 @@ module Volt
|
|
53
53
|
|
54
54
|
# True if the user is logged in and the user is loaded
|
55
55
|
def current_user?
|
56
|
-
|
56
|
+
current_user.then do |user|
|
57
|
+
!!user
|
58
|
+
end
|
57
59
|
end
|
58
60
|
|
59
61
|
# Return the current user.
|
60
62
|
def current_user
|
61
|
-
|
62
|
-
|
63
|
+
user_id = current_user_id
|
64
|
+
if user_id
|
65
|
+
$page.store._users.where(id: user_id).first
|
66
|
+
else
|
67
|
+
Promise.new.resolve(nil)
|
68
|
+
end
|
63
69
|
end
|
64
70
|
|
65
71
|
# Put in a deprecation placeholder
|
@@ -69,13 +75,8 @@ module Volt
|
|
69
75
|
end
|
70
76
|
|
71
77
|
def fetch_current_user
|
72
|
-
|
73
|
-
|
74
|
-
u_query.fetch_first
|
75
|
-
else
|
76
|
-
# No user, resolve nil
|
77
|
-
Promise.new.resolve(nil)
|
78
|
-
end
|
78
|
+
Volt.logger.warn("Deprication Warning: fetch current user have been depricated, Volt.current_user returns a promise now.")
|
79
|
+
current_user
|
79
80
|
end
|
80
81
|
|
81
82
|
# Login the user, return a promise for success
|
@@ -110,17 +111,5 @@ module Volt
|
|
110
111
|
|
111
112
|
user_id_signature
|
112
113
|
end
|
113
|
-
|
114
|
-
private
|
115
|
-
|
116
|
-
# Returns a query for the current user_id or nil if there is no user_id
|
117
|
-
def user_query
|
118
|
-
user_id = current_user_id
|
119
|
-
if user_id
|
120
|
-
$page.store._users.where(_id: user_id)
|
121
|
-
else
|
122
|
-
nil
|
123
|
-
end
|
124
|
-
end
|
125
114
|
end
|
126
115
|
end
|
data/lib/volt.rb
CHANGED
@@ -5,6 +5,7 @@ require 'volt/reactive/dependency'
|
|
5
5
|
require 'volt/utils/modes'
|
6
6
|
require 'volt/utils/volt_user_error'
|
7
7
|
require 'volt/utils/boolean_patch'
|
8
|
+
require 'volt/utils/set_patch'
|
8
9
|
|
9
10
|
require 'volt/config'
|
10
11
|
require 'volt/data_stores/data_store' unless RUBY_PLATFORM == 'opal'
|
@@ -3,7 +3,7 @@
|
|
3
3
|
client '/bindings/{{ route_test }}', action: 'bindings'
|
4
4
|
client '/bindings', action: 'bindings'
|
5
5
|
client '/form', action: 'form'
|
6
|
-
client '/store', action: '
|
6
|
+
client '/store', action: 'store_demo'
|
7
7
|
client '/cookie_test', action: 'cookie_test'
|
8
8
|
client '/flash', action: 'flash'
|
9
9
|
client '/yield', action: 'yield'
|
@@ -10,6 +10,10 @@ module Main
|
|
10
10
|
a[{}] = 5
|
11
11
|
end
|
12
12
|
|
13
|
+
def store_demo
|
14
|
+
puts "STORE DEMO"
|
15
|
+
end
|
16
|
+
|
13
17
|
def form_ready
|
14
18
|
`$('#title').html('form_ready')`
|
15
19
|
`$('select#location').val('AL').change()` # have to trigger manually as this is not user initiaized action
|
@@ -54,6 +58,24 @@ module Main
|
|
54
58
|
page._show = value
|
55
59
|
end
|
56
60
|
|
61
|
+
def show_with_delay
|
62
|
+
changes = Promise.new
|
63
|
+
page._items = changes
|
64
|
+
`
|
65
|
+
setTimeout(function () {
|
66
|
+
#{changes.resolve(0.upto(100).to_a)}
|
67
|
+
}, 50);
|
68
|
+
`
|
69
|
+
page._items = 901.upto(1000).to_a
|
70
|
+
end
|
71
|
+
|
72
|
+
def show_without_delay
|
73
|
+
changes = Promise.new
|
74
|
+
changes.resolve(1.upto(200).to_a)
|
75
|
+
page._items = 901.upto(1000).to_a
|
76
|
+
page._items = changes
|
77
|
+
end
|
78
|
+
|
57
79
|
private
|
58
80
|
|
59
81
|
# the main template contains a #template binding that shows another
|
@@ -134,6 +134,16 @@
|
|
134
134
|
<a id='showtrue' e-click='set_show(true)'>set _show true</a>
|
135
135
|
<a id='showfalse' e-click='set_show(false)'>set _show false</a>
|
136
136
|
|
137
|
+
<h2>Each Bindings</h2>
|
138
|
+
<ul id='eachbinding'>
|
139
|
+
{{ _items.each do |item| }}
|
140
|
+
<li>{{ item }}</li>
|
141
|
+
{{ end }}
|
142
|
+
</ul>
|
143
|
+
|
144
|
+
<a id='each-show-with-delay' e-click='show_with_delay'>Show with Delay</a>
|
145
|
+
<a id='each-show-without-delay' e-click='show_without_delay'>Show without Delay</a>
|
146
|
+
|
137
147
|
<h2>Content</h2>
|
138
148
|
|
139
149
|
<p id="escapeContent">{{{this is {{escaped}}}}}</p>
|
@@ -7,7 +7,12 @@ if RUBY_PLATFORM != 'opal'
|
|
7
7
|
|
8
8
|
describe Volt::HttpController do
|
9
9
|
class TestHttpController < Volt::HttpController
|
10
|
+
attr_reader :ran_action1
|
10
11
|
attr_reader :action_called
|
12
|
+
attr_reader :stoped_action_called
|
13
|
+
|
14
|
+
before_action :run_action1
|
15
|
+
before_action :run_action2, only: [:stoped_action]
|
11
16
|
|
12
17
|
def just_call_an_action
|
13
18
|
@action_called = true
|
@@ -45,6 +50,18 @@ if RUBY_PLATFORM != 'opal'
|
|
45
50
|
def access_body
|
46
51
|
render json: JSON.parse(request.body.read)
|
47
52
|
end
|
53
|
+
|
54
|
+
def stoped_action
|
55
|
+
@stoped_action_called = true
|
56
|
+
end
|
57
|
+
|
58
|
+
def run_action1
|
59
|
+
@ran_action1 = true
|
60
|
+
end
|
61
|
+
|
62
|
+
def run_action2
|
63
|
+
stop_chain
|
64
|
+
end
|
48
65
|
end
|
49
66
|
|
50
67
|
let(:app) { ->(env) { [404, env, 'app'] } }
|
@@ -128,5 +145,15 @@ if RUBY_PLATFORM != 'opal'
|
|
128
145
|
{ test: 'params' }.to_json)
|
129
146
|
expect(response.body).to eq({ test: 'params' }.to_json)
|
130
147
|
end
|
148
|
+
|
149
|
+
it 'should run the before action' do
|
150
|
+
controller.perform(:render_plain_text)
|
151
|
+
expect(controller.ran_action1).to be(true)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should not call the stoped_action' do
|
155
|
+
controller.perform(:stoped_action)
|
156
|
+
expect(controller.stoped_action_called).to be_nil
|
157
|
+
end
|
131
158
|
end
|
132
159
|
end
|
@@ -186,6 +186,35 @@ describe 'bindings test', type: :feature, sauce: true do
|
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
189
|
+
describe 'each binding' do
|
190
|
+
it 'should display the last assignment even if the previous assignment resolved afterwards' do
|
191
|
+
visit '/'
|
192
|
+
|
193
|
+
click_link 'Bindings'
|
194
|
+
|
195
|
+
click_link 'Show with Delay'
|
196
|
+
|
197
|
+
sleep 0.2
|
198
|
+
|
199
|
+
expect(find('#eachbinding li:first-child')).to have_content('901')
|
200
|
+
expect(page).to have_selector('#eachbinding li', count: 100)
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'should display the last assignment regardless whether the previous promise has already been resolved' do
|
204
|
+
visit '/'
|
205
|
+
|
206
|
+
click_link 'Bindings'
|
207
|
+
|
208
|
+
click_link 'Show without Delay'
|
209
|
+
|
210
|
+
sleep 0.2
|
211
|
+
|
212
|
+
expect(find('#eachbinding li:first-child')).to have_content('1')
|
213
|
+
expect(page).to have_selector('#eachbinding li', count: 200)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
|
189
218
|
describe 'if/unless binding' do
|
190
219
|
it 'should show corret text' do
|
191
220
|
visit '/'
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe 'store', type: :feature, sauce: true do
|
4
|
-
|
5
|
-
|
3
|
+
# describe 'store', type: :feature, sauce: true do
|
4
|
+
# it 'should sync between nested root properties on store' do
|
5
|
+
# visit '/store'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
7
|
+
# fill_in('field1', with: 'should sync')
|
8
|
+
# expect(find('#field2').value).to eq('should sync')
|
9
|
+
# end
|
10
|
+
# end
|
data/spec/models/model_spec.rb
CHANGED
@@ -591,4 +591,14 @@ describe Volt::Model do
|
|
591
591
|
'Model does not have a parent and cannot be deleted.')
|
592
592
|
end
|
593
593
|
end
|
594
|
+
|
595
|
+
describe 'serialization' do
|
596
|
+
it 'supports JSON via to_json' do
|
597
|
+
model = Volt::Model.new({})
|
598
|
+
expect(model.to_json).to eq(model.to_h.to_json)
|
599
|
+
expect(model.to_json).to eq(model.to_h.to_json)
|
600
|
+
array_model = Volt::ArrayModel.new([model])
|
601
|
+
expect(array_model.to_json).to eq(array_model.to_a.to_json)
|
602
|
+
end
|
603
|
+
end
|
594
604
|
end
|
@@ -92,7 +92,7 @@ describe 'model permissions' do
|
|
92
92
|
# Clear the identity map, so we can load up a fresh copy
|
93
93
|
model.save_to.persistor.clear_identity_map
|
94
94
|
|
95
|
-
reloaded = store._test_deny_read_names.
|
95
|
+
reloaded = store._test_deny_read_names.first.sync
|
96
96
|
|
97
97
|
expect(reloaded._name).to eq(nil)
|
98
98
|
expect(reloaded._other).to eq('should be visible')
|
@@ -106,13 +106,16 @@ describe 'model permissions' do
|
|
106
106
|
# Saved
|
107
107
|
count = 0
|
108
108
|
|
109
|
-
store._test_deny_deletes.delete(model).
|
109
|
+
store._test_deny_deletes.delete(model).fail do |err|
|
110
110
|
# deleted
|
111
111
|
count += 1
|
112
|
-
|
112
|
+
|
113
|
+
match = !!(err =~ /permissions did not allow delete for /)
|
114
|
+
expect(match).to eq(true)
|
115
|
+
end.sync
|
113
116
|
|
114
117
|
expect(count).to eq(1)
|
115
|
-
end
|
118
|
+
end.sync
|
116
119
|
end
|
117
120
|
|
118
121
|
it 'should not check the read permissions when updating (so that all fields are present for the permissions check)' do
|