volt 0.8.17 → 0.8.18

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e7e97e958515996c80730d0ab074d74eb43a27fe
4
- data.tar.gz: 2d6e4c932e26f55dc4a225965a59cf8f5a3b0704
3
+ metadata.gz: 643b4bf773281e2714b4002a68362b71e886b84b
4
+ data.tar.gz: c229e47bfe005bbb3e4b5b0cfd54bef225b3eb87
5
5
  SHA512:
6
- metadata.gz: bf7586b654567deb37578959dcbca1acd0b63edbd20685d4467b31ba7c0ef99b8512594cc372ae33fbab3111461b6151c627efe5f3f23e0a03f04aaf63159b3e
7
- data.tar.gz: 91db170065e99364b5172228878af671875f98745841947b010f1cb589382c7506b12152e4b09d35a87cf40196256bac4a964265cf3882f36b0bb7bf341d6595
6
+ metadata.gz: e794f7cce33a794913abb6c06d516e50d9fb4fe55c099d63c2a478cb2d1339b75c96d46943e0960f6a42c16be8efc9d3526e77613362cc927ac9941955d844e8
7
+ data.tar.gz: 6e6b49d6d6504f25911bbf766d99453a25c34a9dee63f27b73f73dcfc5dd31f811ef29492a0189ff1ecbbdaa528d4ea5d87677cfef697f044cb3cae433512906
data/.travis.yml CHANGED
@@ -6,7 +6,7 @@ rvm:
6
6
  - "2.1.3"
7
7
  # - jruby-19mode # JRuby in 1.9 mode
8
8
  # - rbx
9
- script: bundle exec rspec
9
+ script: bundle exec rake
10
10
  notifications:
11
11
  webhooks:
12
12
  urls:
data/CHANGELOG.md CHANGED
@@ -1,8 +1,17 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.8.18 - 2014-10-26
4
+ ### Added
5
+ - Added a default app.css.scss file
6
+
7
+ ### Changed
8
+ - back button fixed
9
+ - improve security on task dispatcher
10
+
3
11
  ## 0.8.17 - 2014-10-20
4
12
  ### Added
5
13
  - Volt now has a runner task (like rails) so you can run .rb files inside of the volt project. Example: ```volt runner lib/import.rb```
14
+ - New video showing pagination: https://www.youtube.com/watch?v=1uanfzMLP9g
6
15
 
7
16
  ## 0.8.16 - 2014-10-20
8
17
  ### Added
data/Gemfile CHANGED
@@ -45,3 +45,7 @@ group :development do
45
45
  # gem 'opal-rspec', '0.3.0.beta2'#, git: 'https://github.com/adambeynon/opal-rspec.git'
46
46
  # gem 'yard', require: false
47
47
  end
48
+
49
+ group :development, :test do
50
+ gem 'bson_ext'
51
+ end
data/Readme.md CHANGED
@@ -16,6 +16,7 @@ Pages HTML is written in a template language where you can put ruby between ```{
16
16
 
17
17
  See some demo videos here:
18
18
  - [Volt Todos Example](https://www.youtube.com/watch?v=Tg-EtRnMz7o)
19
+ - [Pagination Example](https://www.youtube.com/watch?v=1uanfzMLP9g)
19
20
  - [Build a Blog with Volt](https://www.youtube.com/watch?v=c478sMlhx1o)
20
21
  ** Note: The blog video is outdated, expect an updated version soon.
21
22
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.17
1
+ 0.8.18
@@ -1,4 +1,5 @@
1
1
  require 'mongo'
2
+ require 'volt/models'
2
3
 
3
4
  class StoreTasks < Volt::TaskHandler
4
5
  def initialize(channel = nil, dispatcher = nil)
@@ -10,7 +11,7 @@ class StoreTasks < Volt::TaskHandler
10
11
  @@db ||= Volt::DataStore.fetch
11
12
  end
12
13
 
13
- def model_values_and_errors(collection, data)
14
+ def load_model(collection, path, data)
14
15
  model_name = collection.singularize.camelize
15
16
 
16
17
  # TODO: Security check to make sure we have a valid model
@@ -18,44 +19,37 @@ class StoreTasks < Volt::TaskHandler
18
19
  begin
19
20
  model_class = Object.send(:const_get, model_name)
20
21
  rescue NameError => e
21
- model_class = nil
22
+ model_class = Volt::Model
22
23
  end
23
24
 
24
25
  if model_class
25
- model = model_class.new(data)
26
- return model.to_h, model.errors
26
+ # Load the model, use the Store persistor and set the path
27
+ model = model_class.new(data, persistor: Volt::Persistors::StoreFactory.new(nil), path: path)
28
+ return model
27
29
  end
28
30
 
29
- [data, {}]
31
+ return nil
30
32
  end
31
33
 
32
- def save(collection, data)
34
+ def save(collection, path, data)
33
35
  data = data.symbolize_keys
34
- values, errors = model_values_and_errors(collection, data)
36
+ model = load_model(collection, path, data)
35
37
 
36
- if errors.size == 0
37
- # id = BSON::ObjectId(values[:_id])
38
- id = values[:_id]
38
+ errors = model.errors
39
39
 
40
- # Try to create
41
- # TODO: Seems mongo is dumb and doesn't let you upsert with custom id's
42
- begin
43
- # values['_id'] = BSON::ObjectId('_id') if values['_id']
44
- db[collection].insert(values)
45
- rescue Mongo::OperationFailure => error
46
- # Really mongo client?
47
- if error.message[/^11000[:]/]
48
- # Update because the id already exists
49
- update_values = values.dup
50
- update_values.delete(:_id)
51
- db[collection].update({ _id: id }, update_values)
52
- else
53
- return { error: error.message }
54
- end
55
- end
40
+ if model.errors.size == 0
41
+
42
+ # On the backend, the promise is resolved before its returned, so we can
43
+ # return from within it.
44
+ #
45
+ # Pass the channel as a thread-local so that we don't update the client
46
+ # who sent the update.
47
+ Thread.current['in_channel'] = @channel
48
+ model.persistor.changed do |errors|
49
+ Thread.current['in_channel'] = nil
56
50
 
57
- QueryTasks.live_query_pool.updated_collection(collection, @channel)
58
- return {}
51
+ return errors
52
+ end
59
53
  else
60
54
  return errors
61
55
  end
data/lib/volt/cli.rb CHANGED
@@ -23,7 +23,7 @@ module Volt
23
23
  desc 'console', 'run the console on the project in the current directory'
24
24
 
25
25
  def console
26
- require 'volt/console'
26
+ require 'volt/cli/console'
27
27
  Console.start
28
28
  end
29
29
 
File without changes
@@ -7,6 +7,7 @@ module Volt
7
7
  def self.run_file(path)
8
8
  Volt.boot(Dir.pwd)
9
9
 
10
+ # Require in the file at path
10
11
  require './' + path
11
12
  end
12
13
  end
@@ -22,10 +22,8 @@ module Volt
22
22
  else
23
23
  fail "#{val} is not the name of a valid model, choose from: #{collections.join(', ')}"
24
24
  end
25
- elsif val
26
- self.current_model = val
27
25
  else
28
- fail "model can not be #{val.inspect}"
26
+ self.current_model = val
29
27
  end
30
28
  end
31
29
 
@@ -43,7 +41,7 @@ module Volt
43
41
  def self.new(*args, &block)
44
42
  inst = allocate
45
43
 
46
- inst.model = (@default_model || :controller)
44
+ inst.model = @default_model if @default_model
47
45
 
48
46
  inst.initialize(*args, &block)
49
47
 
@@ -73,10 +71,6 @@ module Volt
73
71
  $page.page
74
72
  end
75
73
 
76
- def paged
77
- $page.page
78
- end
79
-
80
74
  def store
81
75
  $page.store
82
76
  end
@@ -109,8 +103,27 @@ module Volt
109
103
  @controller ||= Model.new
110
104
  end
111
105
 
106
+ def loaded?
107
+ respond_to?(:state) && state == :loaded
108
+ end
109
+
110
+ # Check if this controller responds_to method, or the model
111
+ def respond_to?(method_name)
112
+ super || begin
113
+ model = self.model
114
+
115
+ model.respond_to?(method_name) if model
116
+ end
117
+ end
118
+
112
119
  def method_missing(method_name, *args, &block)
113
- model.send(method_name, *args, &block)
120
+ model = self.model
121
+
122
+ if model
123
+ model.send(method_name, *args, &block)
124
+ else
125
+ super
126
+ end
114
127
  end
115
128
  end
116
129
  end
@@ -46,7 +46,7 @@ module Volt
46
46
 
47
47
  # Convert the model to a hash all of the way down.
48
48
  def to_h
49
- if empty?
49
+ if @attributes.nil?
50
50
  nil
51
51
  else
52
52
  hash = {}
@@ -158,7 +158,7 @@ module Volt
158
158
  def add(index, data)
159
159
  $loading_models = true
160
160
 
161
- data_id = data[:_id]
161
+ data_id = data['_id'] || data[:_id]
162
162
 
163
163
  # Don't add if the model is already in the ArrayModel
164
164
  unless @model.array.find { |v| v._id == data_id }
@@ -1,6 +1,11 @@
1
1
  require 'volt/models/persistors/store'
2
2
  require 'volt/models/persistors/store_state'
3
3
 
4
+ if RUBY_PLATFORM == 'opal'
5
+ else
6
+ require 'mongo'
7
+ end
8
+
4
9
  module Volt
5
10
  module Persistors
6
11
  class ModelStore < Store
@@ -52,6 +57,14 @@ module Volt
52
57
  id.join
53
58
  end
54
59
 
60
+ def save_changes?
61
+ if RUBY_PLATFORM == 'opal'
62
+ return !(defined?($loading_models) && $loading_models) && @tasks
63
+ else
64
+ return true
65
+ end
66
+ end
67
+
55
68
  # Called when the model changes
56
69
  def changed(attribute_name = nil)
57
70
  path = @model.path
@@ -61,7 +74,7 @@ module Volt
61
74
  ensure_setup
62
75
 
63
76
  path_size = path.size
64
- if !(defined?($loading_models) && $loading_models) && @tasks && path_size > 0 && !@model.nil?
77
+ if save_changes? && path_size > 0 && !@model.nil?
65
78
  if path_size > 3 && (parent = @model.parent) && (source = parent.parent)
66
79
  @model.attributes[:"#{path[-4].singularize}_id"] = source._id
67
80
  end
@@ -70,7 +83,16 @@ module Volt
70
83
  puts 'Attempting to save model directly on store.'
71
84
  fail 'Attempting to save model directly on store.'
72
85
  else
73
- StoreTasks.save(collection, self_attributes).then do |errors|
86
+ if RUBY_PLATFORM == 'opal'
87
+ StoreTasks.save(collection, path, self_attributes).then do |errors|
88
+ if errors.size == 0
89
+ promise.resolve(nil)
90
+ else
91
+ promise.reject(errors)
92
+ end
93
+ end
94
+ else
95
+ errors = save_to_db!(self_attributes)
74
96
  if errors.size == 0
75
97
  promise.resolve(nil)
76
98
  else
@@ -117,6 +139,38 @@ module Volt
117
139
  def collection
118
140
  @model.path[-2]
119
141
  end
142
+
143
+ if RUBY_PLATFORM != 'opal'
144
+ def db
145
+ @@db ||= Volt::DataStore.fetch
146
+ end
147
+
148
+ # Do the actual writing of data to the database, only runs on the backend.
149
+ def save_to_db!(values)
150
+ id = values[:_id]
151
+
152
+ # Try to create
153
+ # TODO: Seems mongo is dumb and doesn't let you upsert with custom id's
154
+ begin
155
+ # values['_id'] = BSON::ObjectId('_id') if values['_id']
156
+ db[collection].insert(values)
157
+ rescue Mongo::OperationFailure => error
158
+ # Really mongo client?
159
+ if error.message[/^11000[:]/]
160
+ # Update because the id already exists
161
+ update_values = values.dup
162
+ update_values.delete(:_id)
163
+ db[collection].update({ _id: id }, update_values)
164
+ else
165
+ return { error: error.message }
166
+ end
167
+ end
168
+
169
+ # puts "Update Collection: #{collection.inspect} - #{values.inspect}"
170
+ QueryTasks.live_query_pool.updated_collection(collection.to_s, Thread.current['from_channel'])
171
+ return {}
172
+ end
173
+ end
120
174
  end
121
175
  end
122
176
  end
@@ -109,7 +109,7 @@ module Volt
109
109
  def scroll
110
110
  if Volt.client?
111
111
  frag = fragment
112
- if frag
112
+ if frag.present?
113
113
  # Scroll to anchor via http://www.w3.org/html/wg/drafts/html/master/browsers.html#scroll-to-fragid
114
114
  `
115
115
  var anchor = $('#' + frag);
@@ -129,11 +129,15 @@ module Volt
129
129
  # Clear value
130
130
  @value = nil
131
131
 
132
- @added_listener.remove
133
- @added_listener = nil
132
+ if @added_listener
133
+ @added_listener.remove
134
+ @added_listener = nil
135
+ end
134
136
 
135
- @removed_listener.remove
136
- @removed_listener = nil
137
+ if @removed_listener
138
+ @removed_listener.remove
139
+ @removed_listener = nil
140
+ end
137
141
 
138
142
  if @templates
139
143
  template_count = @templates.size
@@ -12,14 +12,8 @@ module Volt
12
12
  # Setup popstate on the dom ready event. Prevents an extra
13
13
  # popstate trigger
14
14
  `
15
- var first = true;
16
15
  window.addEventListener("popstate", function(e) {
17
- if (first === false) {
18
- that.$url_updated();
19
- }
20
-
21
- first = false;
22
-
16
+ that.$url_updated();
23
17
  return true;
24
18
  });
25
19
  `
@@ -4,28 +4,53 @@ module Volt
4
4
  class Dispatcher
5
5
  def dispatch(channel, message)
6
6
  callback_id, class_name, method_name, *args = message
7
+ method_name = method_name.to_sym
7
8
 
8
9
  # Get the class
9
10
  klass = Object.send(:const_get, class_name)
10
11
 
11
- if klass.ancestors.include?(TaskHandler)
12
+ result = nil
13
+ error = nil
14
+
15
+ if safe_method?(klass, method_name)
12
16
  # Init and send the method
13
17
  begin
14
18
  result = klass.new(channel, self).send(method_name, *args)
15
- error = nil
16
19
  rescue => e
17
20
  # TODO: Log these errors better
18
21
  puts e.inspect
19
22
  puts e.backtrace
20
- result = nil
21
23
  error = e
22
24
  end
25
+ else
26
+ # Unsafe method
27
+ error = RuntimeError.new("unsafe method: #{method_name}")
28
+ end
23
29
 
24
- if callback_id
25
- # Callback with result
26
- channel.send_message('response', callback_id, result, error)
30
+ if callback_id
31
+ # Callback with result
32
+ channel.send_message('response', callback_id, result, error)
33
+ end
34
+ end
35
+
36
+ # Check if it is safe to use this method
37
+ def safe_method?(klass, method_name)
38
+ # Make sure the class being called is a TaskHandler.
39
+ return false unless klass.ancestors.include?(TaskHandler)
40
+
41
+ # Make sure the method is defined on the klass we're using and not up the hiearchy.
42
+ # ^ This check prevents methods like #send, #eval, #instance_eval, #class_eval, etc...
43
+ klass.ancestors.each do |ancestor_klass|
44
+ if ancestor_klass.instance_methods(false).include?(method_name)
45
+ return true
46
+ elsif ancestor_klass == TaskHandler
47
+ # We made it to TaskHandler and didn't find the method, that means it
48
+ # was defined above TaskHandler, so we reject the call.
49
+ return false
27
50
  end
28
51
  end
52
+
53
+ return false
29
54
  end
30
55
  end
31
56
  end
@@ -38,6 +38,11 @@ module Volt
38
38
 
39
39
  promise
40
40
  end
41
+
42
+ # Provide access to the store collection
43
+ def store
44
+ $page.store
45
+ end
41
46
  end
42
47
  end
43
48
  end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'volt/extra_core/array'
3
+
4
+ describe Array do
5
+ it 'should sum an array of integers' do
6
+ expect([1,2,3].sum).to eq(6)
7
+ end
8
+ end
@@ -6,4 +6,8 @@ describe Volt::Inflector do
6
6
  expect('car'.pluralize).to eq('cars')
7
7
  # expect('database'.pluralize).to eq('database')
8
8
  end
9
+
10
+ it 'should singularize correctly' do
11
+ expect('cars'.singularize).to eq('car')
12
+ end
9
13
  end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'volt/extra_core/blank'
3
+
4
+ describe Object do
5
+ it 'should add blank? to all objects' do
6
+ expect(Object.new.blank?).to be_false
7
+ expect(nil.blank?).to be_true
8
+ end
9
+
10
+ it 'should add present? to all objects' do
11
+ expect(Object.new.present?).to be_true
12
+ expect(nil.present?).to be_false
13
+ end
14
+ end
@@ -12,27 +12,6 @@
12
12
  'area51_controller' => 'area51Controller'
13
13
  }
14
14
 
15
- SymbolToLowerCamel = {
16
- product: 'product',
17
- special_guest: 'specialGuest',
18
- application_controller: 'applicationController',
19
- area51_controller: 'area51Controller'
20
- }
21
-
22
- CamelToUnderscoreWithoutReverse = {
23
- 'HTMLTidy' => 'html_tidy',
24
- 'HTMLTidyGenerator' => 'html_tidy_generator',
25
- 'FreeBSD' => 'free_bsd',
26
- 'HTML' => 'html',
27
- 'ForceXMLController' => 'force_xml_controller'
28
- }
29
-
30
- CamelWithModuleToUnderscoreWithSlash = {
31
- 'Admin::Product' => 'admin/product',
32
- 'Users::Commission::Department' => 'users/commission/department',
33
- 'UsersSection::CommissionDepartment' => 'users_section/commission_department'
34
- }
35
-
36
15
  UnderscoresToDashes = {
37
16
  'street' => 'street',
38
17
  'street_address' => 'street-address',
@@ -0,0 +1,15 @@
1
+ if RUBY_PLATFORM == 'opal'
2
+ else
3
+ require 'spec_helper'
4
+ require 'volt/extra_core/symbol'
5
+
6
+ describe Symbol do
7
+ it 'should pluralize correctly' do
8
+ expect(:car.pluralize).to eq(:cars)
9
+ end
10
+
11
+ it 'should singularize correctly' do
12
+ expect(:cars.singularize).to eq(:car)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,31 @@
1
+ if ENV['BROWSER'] && ENV['BROWSER'] != 'phantom'
2
+ require 'spec_helper'
3
+
4
+ describe 'url features', type: :feature do
5
+ it 'should update the page when using the back button' do
6
+ visit '/'
7
+ expect(current_url).to match(/\/$/)
8
+
9
+ click_link 'Bindings'
10
+ expect(current_url).to match(/\/bindings$/)
11
+ expect(page).to have_content('Checkbox')
12
+
13
+ click_link 'Todos'
14
+ expect(current_url).to match(/\/todos$/)
15
+ expect(page).to have_content('Todos Example')
16
+
17
+ # "Click" back button
18
+ page.evaluate_script('window.history.back()')
19
+
20
+ click_link 'Bindings'
21
+ expect(current_url).to match(/\/bindings$/)
22
+ expect(page).to have_content('Checkbox')
23
+
24
+ # "Click" back button
25
+ page.evaluate_script('window.history.back()')
26
+
27
+ expect(current_url).to match(/\/$/)
28
+ end
29
+
30
+ end
31
+ end
@@ -17,7 +17,7 @@ describe Volt::Routes do
17
17
  expect(direct_routes).to eq('/' => { _view: 'index' }, '/page1' => { _view: 'first_page' })
18
18
  end
19
19
 
20
- it 'should setup indiect routes' do
20
+ it 'should setup indirect routes' do
21
21
  routes do
22
22
  get '/blog/{{ _id }}/edit', _view: 'blog/edit'
23
23
  get '/blog/{{ _id }}', _view: 'blog/show'
@@ -0,0 +1,43 @@
1
+ if RUBY_PLATFORM != 'opal'
2
+ class TestTask < Volt::TaskHandler
3
+ def allowed_method(arg1)
4
+ return 'yes' + arg1
5
+ end
6
+ end
7
+
8
+
9
+ describe Volt::Dispatcher do
10
+
11
+ it 'should only allow method calls on TaskHandler or above in the inheritance chain' do
12
+ channel = double('channel')
13
+
14
+ expect(channel).to receive(:send_message).with('response', 0, 'yes works', nil)
15
+
16
+ Volt::Dispatcher.new.dispatch(channel, [0, 'TestTask', :allowed_method, ' works'])
17
+ end
18
+
19
+ it 'should not allow eval' do
20
+ channel = double('channel')
21
+
22
+ expect(channel).to receive(:send_message).with('response', 0, nil, RuntimeError.new('unsafe method: eval'))
23
+
24
+ Volt::Dispatcher.new.dispatch(channel, [0, 'TestTask', :eval, '5 + 10'])
25
+ end
26
+
27
+ it 'should not allow instance_eval' do
28
+ channel = double('channel')
29
+
30
+ expect(channel).to receive(:send_message).with('response', 0, nil, RuntimeError.new('unsafe method: instance_eval'))
31
+
32
+ Volt::Dispatcher.new.dispatch(channel, [0, 'TestTask', :instance_eval, '5 + 10'])
33
+ end
34
+
35
+ it 'should not allow #methods' do
36
+ channel = double('channel')
37
+
38
+ expect(channel).to receive(:send_message).with('response', 0, nil, RuntimeError.new('unsafe method: methods'))
39
+
40
+ Volt::Dispatcher.new.dispatch(channel, [0, 'TestTask', :methods])
41
+ end
42
+ end
43
+ end
@@ -0,0 +1 @@
1
+ // Place your apps css here
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: volt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.17
4
+ version: 0.8.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Stout
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-21 00:00:00.000000000 Z
11
+ date: 2014-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -379,11 +379,11 @@ files:
379
379
  - lib/volt/boot.rb
380
380
  - lib/volt/cli.rb
381
381
  - lib/volt/cli/asset_compile.rb
382
+ - lib/volt/cli/console.rb
382
383
  - lib/volt/cli/generate.rb
383
384
  - lib/volt/cli/new_gem.rb
384
385
  - lib/volt/cli/runner.rb
385
386
  - lib/volt/config.rb
386
- - lib/volt/console.rb
387
387
  - lib/volt/controllers/model_controller.rb
388
388
  - lib/volt/data_stores/data_store.rb
389
389
  - lib/volt/data_stores/mongo_driver.rb
@@ -513,12 +513,16 @@ files:
513
513
  - spec/apps/kitchen_sink/config.ru
514
514
  - spec/apps/kitchen_sink/public/index.html
515
515
  - spec/controllers/reactive_accessors_spec.rb
516
+ - spec/extra_core/array_spec.rb
516
517
  - spec/extra_core/inflector_spec.rb
518
+ - spec/extra_core/object_spec.rb
517
519
  - spec/extra_core/string_transformation_test_cases.rb
518
520
  - spec/extra_core/string_transformations_spec.rb
521
+ - spec/extra_core/symbol_spec.rb
519
522
  - spec/integration/bindings_spec.rb
520
523
  - spec/integration/list_spec.rb
521
524
  - spec/integration/templates_spec.rb
525
+ - spec/integration/url_spec.rb
522
526
  - spec/models/model_spec.rb
523
527
  - spec/models/persistors/params_spec.rb
524
528
  - spec/models/persistors/store_spec.rb
@@ -539,6 +543,7 @@ files:
539
543
  - spec/server/rack/rack_requests_spec.rb
540
544
  - spec/spec_helper.rb
541
545
  - spec/store/mongo_spec.rb
546
+ - spec/tasks/dispatcher_spec.rb
542
547
  - spec/tasks/live_query_spec.rb
543
548
  - spec/tasks/query_tasks.rb
544
549
  - spec/tasks/query_tracker_spec.rb
@@ -580,6 +585,7 @@ files:
580
585
  - templates/project/README.md.tt
581
586
  - templates/project/app/.empty_directory
582
587
  - templates/project/app/main/assets/css/.empty_directory
588
+ - templates/project/app/main/assets/css/app.css.scss
583
589
  - templates/project/app/main/assets/js/.empty_directory
584
590
  - templates/project/app/main/config/dependencies.rb
585
591
  - templates/project/app/main/config/routes.rb
@@ -642,12 +648,16 @@ test_files:
642
648
  - spec/apps/kitchen_sink/config.ru
643
649
  - spec/apps/kitchen_sink/public/index.html
644
650
  - spec/controllers/reactive_accessors_spec.rb
651
+ - spec/extra_core/array_spec.rb
645
652
  - spec/extra_core/inflector_spec.rb
653
+ - spec/extra_core/object_spec.rb
646
654
  - spec/extra_core/string_transformation_test_cases.rb
647
655
  - spec/extra_core/string_transformations_spec.rb
656
+ - spec/extra_core/symbol_spec.rb
648
657
  - spec/integration/bindings_spec.rb
649
658
  - spec/integration/list_spec.rb
650
659
  - spec/integration/templates_spec.rb
660
+ - spec/integration/url_spec.rb
651
661
  - spec/models/model_spec.rb
652
662
  - spec/models/persistors/params_spec.rb
653
663
  - spec/models/persistors/store_spec.rb
@@ -668,6 +678,7 @@ test_files:
668
678
  - spec/server/rack/rack_requests_spec.rb
669
679
  - spec/spec_helper.rb
670
680
  - spec/store/mongo_spec.rb
681
+ - spec/tasks/dispatcher_spec.rb
671
682
  - spec/tasks/live_query_spec.rb
672
683
  - spec/tasks/query_tasks.rb
673
684
  - spec/tasks/query_tracker_spec.rb