volt 0.8.4 → 0.8.5

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: a84884c1b8515b231b4dabcbe6757cb7d18f6744
4
- data.tar.gz: b9e66a5548bc014e1759280520516094362d7ab4
3
+ metadata.gz: 3c7f9c10d1c4c9b36bbf686d224d63b7efac606d
4
+ data.tar.gz: 3d5734b9bf49bd4bc385442fcafe8fa52a083d6c
5
5
  SHA512:
6
- metadata.gz: c1c7d2b1280226777aa301457c8a6f61dc09c2a43ff9e0a000035308a7712447dd0d4423e5d4e5536778b3b47edea464ee8f7881d4bae32d06b1470d31ff7437
7
- data.tar.gz: 6e76d4a9a137a9eb1d7691f1dc56e0f80002bc6afdd200a606ca5ade4cb5dd4c31e86649006df493e5d8b18aa07201851dabe9848352be366576db53ce9b590f
6
+ metadata.gz: ea67b035043177a2f63d14906b25a9b71e12f6bb2737b471c749947971bc170680d83d61df1a20c7a9b13a009d1bb43c3e5610a71374d79a763c7af7158431a1
7
+ data.tar.gz: 9aed66c68f300dc644f38ff84802152f3e2c4cd37780306c2a142247b6d6d71d70a89c49b307117e07b04e89db05165d1f1c86ed7472f28218d80a0078f76608
@@ -1,4 +1,8 @@
1
- # 0.0.8 - Oct 3, 2014
1
+ # 0.8.4 - Oct 4, 2014
2
+
3
+ - Added configuration for databases.
4
+
5
+ # 0.8.0 - Oct 3, 2014
2
6
 
3
7
  - Major change: After a bunch of research and effort, we have decided to change the way the reactive core works. Previously, all objects that maybe changed would be wrapped in a ReactiveValue object that could be updated using ```.cur=``` and accessed using ```.cur``` This had many advantages, but resulted in very complex framework code. It also had a few problems, mainly that reactive value's (sometimes) needed to be unwrapped when passed to code that wasn't aware of reactivity. Our goal is transparent reactivity. Taking infuence from meteor.js, we have switched to a simpler reactive model. See the Readme for details of the new reactive system. The new system has a few advantages. Mainly, you can for the most part write code that is reactive and it will just work.
4
8
  - Radio button support has been added, see README.md
data/Readme.md CHANGED
@@ -72,19 +72,28 @@ You can access the Volt console with:
72
72
  1. [Getting Help](#getting-help)
73
73
  2. [Rendering](#rendering)
74
74
  1. [States and Computations](#state-and-computations)
75
- 1. [Computations](#computations)
75
+ 1. [Computations](#computations)
76
+ 2. [Dependencies](#dependencies)
76
77
  3. [Views](#views)
77
78
  1. [Bindings](#bindings)
78
79
  1. [Content Binding](#content-binding)
79
80
  2. [If Binding](#if-binding)
80
81
  3. [Each Binding](#each-binding)
81
82
  4. [Attribute Bindings](#attribute-bindings)
82
- 5. [Escaping](#escaping)
83
+ 2. [Escaping](#escaping)
83
84
  4. [Models](#models)
84
- 1. [Provided Collections](#provided-collections)
85
- 2. [ArrayModel Events](#arraymodel-events)
86
- 3. [Automatic Model Conversion](#automatic-model-conversion)
85
+ 1. [Nil Models](#nil-models)
86
+ 2. [Provided Collections](#provided-collections)
87
+ 3. [Store Collection](#store-collection)
88
+ 4. [Sub Collections](#sub-collections)
89
+ 5. [Model Classes](#model-classes)
90
+ 6. [Buffers](#buffers)
91
+ 7. [Validations](#validations)
92
+ 8. [Model State](#model-state)
93
+ 9. [ArrayModel Events](#arraymodel-events)
94
+ 10. [Automatic Model Conversion](#automatic-model-conversion)
87
95
  5. [Controllers](#controllers)
96
+ 1. [Reactive Accessors](#reactive-accessors)
88
97
  6. [Tasks](#tasks)
89
98
  7. [Components](#components)
90
99
  1. [Dependencies](#dependencies)
@@ -97,9 +106,11 @@ You can access the Volt console with:
97
106
  9. [Routes](#routes)
98
107
  1. [Routes file](#routes-file)
99
108
  10. [Testing](#testing)
100
- 11. [Volt Helpers](#volt-helpers)
109
+ 11. [Debugging](#debugging)
110
+ 12. [Volt Helpers](#volt-helpers)
101
111
  1. [Logging](#logging)
102
112
  2. [App Configuration](#app-configuration)
113
+ 13. [Contributing](#contributing)
103
114
 
104
115
  # Getting Help
105
116
 
@@ -270,7 +281,7 @@ You can do {index + 1} to correct the zero offset.
270
281
 
271
282
  When items are removed or added to the array, the #each binding automatically and intelligently adds or removes the items from/to the DOM.
272
283
 
273
- ## Attribute Bindings
284
+ ### Attribute Bindings
274
285
 
275
286
  Bindings can also be placed inside of attributes.
276
287
 
@@ -327,17 +338,19 @@ When you need to use { and } outside of bindings, anything in a triple mustache
327
338
 
328
339
  # Models
329
340
 
330
- Volt's concept of a model is slightly different from many frameworks where a model is the name for the ORM to the database. In Volt a model is a class where you can store data easily. Models can be created with a "Persistor", which is responsible for storing the data in the model. Models created without a persistor, simply store the data in the classes instance. Lets first see how to use a model.
341
+ Volt's concept of a model is slightly different from many frameworks where a model is the name for the ORM to the database. In Volt a model is a class where you can store data easily. Models can be created with a "Persistor", which is responsible for storing the data in the model somewhere. Models created without a persistor, simply store the data in the classes instance. Lets first see how to use a model.
331
342
 
332
- Volt comes with many built-in models; one is called `page`. If you call `#page` on a controller, you will get access to the model. Models provided by Volt are automatically wrapped in a ReactiveValue so update events can be tracked.
343
+ Volt comes with many built-in models; one is called `page`. If you call `#page` on a controller, you will get access to the model.
333
344
 
334
345
  ```ruby
335
346
  page._name = 'Ryan'
336
347
  page._name
337
- # => @'Ryan'
348
+ # => 'Ryan'
338
349
  ```
339
350
 
340
- Models act like a hash that you can access with getters and setters that start with an _ . If an underscore method is called that hasn't yet been assigned, you will get back a "nil model". Prefixing with an underscore makes sure we don't accidentally try to call a method that doesn't exist and get back nil model instead of raising an exception. There is no need to define which fields a model has. Fields behave similarly to a hash, but with a different access and assignment syntax.
351
+ Models act like a hash that you can access with getters and setters that start with an underscore. If an attribute is accessed that hasn't yet been assigned, you will get back a "nil model". Prefixing with an underscore makes sure we don't accidentally try to call a method that doesn't exist and get back nil model instead of raising an exception. Fields behave similarly to a hash, but with a different access and assignment syntax.
352
+
353
+ # TODO: Add docs on fields in classes
341
354
 
342
355
  Models also let you nest data without creating the intermediate models:
343
356
 
@@ -350,23 +363,28 @@ Models also let you nest data without creating the intermediate models:
350
363
  # => @#<Model:_settings {:_color=>"blue"}>
351
364
  ```
352
365
 
353
- Nested data is automatically setup when assigned. In this case, page._settings is a model that is part of the page model.
366
+ Nested data is automatically setup when assigned. In this case, page._settings is a model that is part of the page model. This allows nested models to be bound to a binding without the need to setup the model before use.
354
367
 
355
- You can also append to a model if it's not defined yet. In Volt models, plural properties are assumed to contain arrays (or more specifically, ArrayModels).
368
+ In Volt models, plural properties return an ArrayModel instance. ArrayModels behave the same way as normal arrays. You can add/remove items to the array with normal array methods (#<<, push, append, delete, delete_at, etc...)
356
369
 
357
370
  ```ruby
358
- page._items << 'item 1'
359
371
  page._items
360
- # => @#<ArrayModel ["item 1", "item 2"]>
372
+ # #<ArrayModel:70303686333720 []>
373
+
374
+ page._items << {_name: 'Item 1'}
375
+
376
+ page._items
377
+ # #<ArrayModel:70303686333720 [<Model:70303682055800 {:_name=>"Item 1"}>]>
378
+
379
+ page._items.size
380
+ # => 1
361
381
 
362
382
  page._items[0]
363
- # => @"item 1"
383
+ # => <Model:70303682055800 {:_name=>"Item 1"}>
364
384
  ```
365
385
 
366
- ArrayModels can be appended to and accessed just like regular arrays.
367
-
368
386
 
369
- ### Nil Models
387
+ ## Nil Models
370
388
 
371
389
  As a convience, calling something like ```page._info``` returns what's called a NilModel (assuming it isn't already initialized). NilModels are place holders for future possible Models. NilModels allow us to bind deeply nested values without initializing any intermediate values.
372
390
 
@@ -417,6 +435,160 @@ Above, I mentioned that Volt comes with many default collection models accessibl
417
435
 
418
436
  **more storage locations are planned**
419
437
 
438
+ ## Store Collection
439
+
440
+ The store collection backs data in the data store. Currently the only supported data store is Mongo. (More coming soon, RethinkDb will probably be next) You can use store very similar to the other collections.
441
+
442
+ In Volt you can access ```store``` on the front-end and the back-end. Data will automatically be synced between the front-end and the backend. Any changes to the data in store will be reflected on any clients using the data (unless a [buffer](#buffer) is in use - see below).
443
+
444
+ ```ruby
445
+ store._items << {_name: 'Item 1'}
446
+
447
+ store._items[0]
448
+ # => <Model:70303681865560 {:_name=>"Item 1", :_id=>"e6029396916ed3a4fde84605"}>
449
+ ```
450
+
451
+ Inserting into ```store._items``` will create a ```_items``` table and insert the model into it. An pseudo-unique _id will be automatically generated.
452
+
453
+ Currently one difference between ```store``` and other collections is ```store``` does not store properties directly. Only ArrayModels are allowed directly on ```store```
454
+
455
+ ```ruby
456
+ store._something = 'yes'
457
+ # => won't be saved at the moment
458
+ ```
459
+
460
+ Note: We're planning to add support for direct ```store``` properties.
461
+
462
+ ## Sub Collections
463
+
464
+ Models can be nested on ```store```
465
+
466
+ ```ruby
467
+ store._states << {_name: 'Montana'}
468
+ montana = store._states[0]
469
+
470
+ montana._cities << {_name: 'Bozeman'}
471
+ montana._cities << {_name: 'Helena'}
472
+
473
+ store._states << {_name: 'Idaho'}
474
+ idaho = store._states[1]
475
+
476
+ idaho._cities << {_name: 'Boise'}
477
+ idaho._cities << {_name: 'Twin Falls'}
478
+
479
+ store._states
480
+ # #<ArrayModel:70129010999880 [<Model:70129010999460 {:_name=>"Montana", :_id=>"e3aa44651ff2e705b8f8319e"}>, <Model:70128997554160 {:_name=>"Montana", :_id=>"9aaf6d2519d654878c6e60c9"}>, <Model:70128997073860 {:_name=>"Idaho", :_id=>"5238883482985760e4cb2341"}>, <Model:70128997554160 {:_name=>"Montana", :_id=>"9aaf6d2519d654878c6e60c9"}>, <Model:70128997073860 {:_name=>"Idaho", :_id=>"5238883482985760e4cb2341"}>]>
481
+ ```
482
+
483
+ You can also create a Model first and then insert it.
484
+
485
+ ```ruby
486
+ montana = Model.new({_name: 'Montana'})
487
+
488
+ montana._cities << {_name: 'Bozeman'}
489
+ montana._cities << {_name: 'Helena'}
490
+
491
+ store._states << montana
492
+ ```
493
+
494
+ ## Model Classes
495
+
496
+ By default all collections use the Model class by default.
497
+
498
+ ```ruby
499
+ page._info.class
500
+ # => Model
501
+ ```
502
+
503
+ You can provide classes that will be loaded in place of the standard model class. You can place these in any app/{component}/models folder. For example, you could add ```app/main/info.rb``` Model classes should inherit from ```Model```
504
+
505
+ ```ruby
506
+ class Info < Model
507
+ end
508
+ ```
509
+
510
+ Now when you access any sub-collection called ```_info```, it will load as an instance of ```Info```
511
+
512
+ ```ruby
513
+ page._info.class
514
+ # => Info
515
+ ```
516
+
517
+ This lets you set custom methods and validations within collections.
518
+
519
+ ## Buffers
520
+
521
+ Because the store collection is automatically synced to the backend, any change to a model's property will result in all other clients seeing the change immediately. Often this is not the desired behavior. To facilitate building [CRUD](http://en.wikipedia.org/wiki/Create,_read,_update_and_delete) apps, Volt provides the concept of a "buffer". A buffer can be created from one model and will not save data back to its backing model until .save! is called on it. This lets you create a form thats not saved until a submit button is pressed.
522
+
523
+ ```ruby
524
+ store._items << {_name: 'Item 1'}
525
+
526
+ item1 = store._items[0]
527
+
528
+ item1_buffer = item1.buffer
529
+
530
+ item1_buffer._name = 'Updated Item 1'
531
+ item1_buffer._name
532
+ # => 'Updated Item 1'
533
+
534
+ item1._name
535
+ # => 'Item 1'
536
+
537
+ item1_buffer.save!
538
+
539
+ item1_buffer._name
540
+ # => 'Updated Item 1'
541
+
542
+ item1._name
543
+ # => 'Updated Item 1'
544
+ ```
545
+
546
+ ```#save!``` on buffer also returns a [promise](http://opalrb.org/blog/2014/05/07/promises-in-opal/) that will resolve when the data has been saved back to the server.
547
+
548
+ ```ruby
549
+ item1_buffer.save!.then do
550
+ puts "Item 1 saved"
551
+ end.fail do |err|
552
+ puts "Unable to save because #{err}"
553
+ end
554
+ ```
555
+
556
+ Calling .buffer on an existing model will return a buffer for that model instance. If you call .buffer on an ArrayModel (plural sub-collection), you will get a buffer for a new item in that collection. Calling .save! will then add the item to that sub-collection as if you had done << to push the item into the collection.
557
+
558
+ ## Validations
559
+
560
+ Within a model class, you can setup validations. Validations let you restrict the types of data that can be stored in a model. Validations are mostly useful for the ```store``` collection, though they can be used elsewhere.
561
+
562
+ At the moment we only have two validations implemented (length and presence). Though a lot more will be coming.
563
+
564
+ ```ruby
565
+ class Info < Model
566
+ validate :_name, length: 5
567
+ validate :_state, presence: true
568
+ end
569
+ ```
570
+
571
+ When calling save on a model with validations, the following occurs:
572
+
573
+ 1. Client side validations are run; if they fail, the promise from ```save!``` is rejected with the error object.
574
+ 2. The data is sent to the server and client and server side validations are run on the server; any failures are returned and the promise is rejected on the front-end (with the error object)
575
+ - re-running the validations on the server side makes sure that no data can be saved that doesn't pass the validations
576
+ 3. If all validations pass, the data is saved to the database and the promise resolved on the client.
577
+ 4. The data is synced to all other clients.
578
+
579
+
580
+ ## Model State
581
+
582
+ **Work in progress**
583
+
584
+ | state | events bound | description |
585
+ |-------------|--------------|--------------------------------------------------------------|
586
+ | not_loaded | no | no events and no one has accessed the data in the model |
587
+ | loading | maybe | someone either accessed the data or bound an event |
588
+ | loaded | yes | data is loaded and there is an event bound |
589
+ | dirty | no | data was either accessed without binding an event, or an event was bound, but later unbound. |
590
+
591
+
420
592
  ## ArrayModel Events
421
593
 
422
594
  Models trigger events when their data is updated. Currently, models emit two events: added and removed. For example:
@@ -781,16 +953,7 @@ If ```params._view``` were 'todos' and ```params._index``` were not nil, the rou
781
953
 
782
954
  Routes are matched top to bottom in a routes file.
783
955
 
784
- ## Debugging
785
-
786
- An in browser irb is in the works. We also have source maps support, but they are currently disabled by default. To enable them run:
787
-
788
- MAPS=true volt s
789
-
790
- This feature is disabled by default because (due to the volume of pages rendered) it slows down page rendering. We're working with the opal and sprockets teams to make it so everything is still served in one big source maps file (which would show the files as they originated on disk)
791
-
792
-
793
- ## Channel
956
+ # Channel
794
957
 
795
958
  Controllers provide a `#channel` method, that you can use to get the status of the connection to the backend. Channel is provided in a ReactiveValue, and when the status changes, the changed events are triggered. It provides the following:
796
959
 
@@ -822,6 +985,14 @@ To run Capybara tests, you need to specify a driver. The following drivers are
822
985
 
823
986
  Chrome is not supported due to [this issue](https://code.google.com/p/chromedriver/issues/detail?id=887#makechanges) with ChromeDriver. Feel free to go [here](https://code.google.com/p/chromedriver/issues/detail?id=887#makechanges) and pester the chromedriver team to fix it.
824
987
 
988
+ # Debugging
989
+
990
+ An in browser irb is in the works. We also have source maps support, but they are currently disabled by default. To enable them run:
991
+
992
+ MAPS=true volt s
993
+
994
+ This feature is disabled by default because (due to the volume of pages rendered) it slows down page rendering. We're working with the opal and sprockets teams to make it so everything is still served in one big source maps file (which would show the files as they originated on disk)
995
+
825
996
  # Volt Helpers
826
997
 
827
998
  ## Logging
@@ -859,24 +1030,6 @@ Volt does its best to start with useful defaults. You can configure things like
859
1030
 
860
1031
  TODO
861
1032
 
862
-
863
- # Data Store
864
-
865
- Volt provides a data store collection on the front-end and the back-end. In store, all plural names are assumed to be collections (like an array), and all singular are assumed to be a model (like a hash).
866
-
867
- ```ruby
868
- store._things
869
- ```
870
-
871
- **Work in progress**
872
-
873
- | state | events bound | description |
874
- |-------------|--------------|--------------------------------------------------------------|
875
- | not_loaded | no | no events and no one has accessed the data in the model |
876
- | loading | maybe | someone either accessed the data or bound an event |
877
- | loaded | yes | data is loaded and there is an event bound |
878
- | dirty | no | data was either accessed without binding an event, or an event was bound, but later unbound. |
879
-
880
1033
  # Contributing
881
1034
 
882
1035
  You want to contribute? Great! Thanks for being awesome! At the moment, we have a big internal todo list, hop on https://gitter.im/voltrb/volt so we don't duplicate work. Pull requests are always welcome, but asking about helping on gitter should save some duplication.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.4
1
+ 0.8.5
@@ -2,7 +2,10 @@ require 'mongo'
2
2
 
3
3
  class DataStore
4
4
  def initialize
5
- @@db = Volt::DataStore.fetch
5
+ end
6
+
7
+ def db
8
+ @@db ||= Volt::DataStore.fetch
6
9
  end
7
10
 
8
11
  def query(collection, query)
@@ -13,6 +16,6 @@ class DataStore
13
16
  end
14
17
  end
15
18
 
16
- @@db[collection].find(query).to_a
19
+ db[collection].find(query).to_a
17
20
  end
18
21
  end
@@ -3,14 +3,12 @@ require 'query_tasks'
3
3
 
4
4
  class StoreTasks
5
5
  def initialize(channel=nil, dispatcher=nil)
6
- @@db = Volt::DataStore.fetch
7
-
8
6
  @channel = channel
9
7
  @dispatcher = dispatcher
10
8
  end
11
9
 
12
10
  def db
13
- @@db
11
+ @@db ||= Volt::DataStore.fetch
14
12
  end
15
13
 
16
14
  def model_errors(collection, data)
@@ -43,14 +41,14 @@ class StoreTasks
43
41
  # TODO: Seems mongo is dumb and doesn't let you upsert with custom id's
44
42
  begin
45
43
  # data['_id'] = BSON::ObjectId('_id') if data['_id']
46
- @@db[collection].insert(data)
44
+ db[collection].insert(data)
47
45
  rescue Mongo::OperationFailure => error
48
46
  # Really mongo client?
49
47
  if error.message[/^11000[:]/]
50
48
  # Update because the id already exists
51
49
  update_data = data.dup
52
50
  update_data.delete(:_id)
53
- @@db[collection].update({:_id => id}, update_data)
51
+ db[collection].update({:_id => id}, update_data)
54
52
  else
55
53
  return {:error => error.message}
56
54
  end
@@ -64,7 +62,7 @@ class StoreTasks
64
62
  end
65
63
 
66
64
  def delete(collection, id)
67
- @@db[collection].remove('_id' => id)
65
+ db[collection].remove('_id' => id)
68
66
 
69
67
  QueryTasks.live_query_pool.updated_collection(collection, @channel)
70
68
  end
@@ -1,5 +1,4 @@
1
1
  # A place for things shared between an ArrayModel and a Model
2
-
3
2
  module ModelHelpers
4
3
  def deep_unwrap(value)
5
4
  if value.is_a?(Model)
@@ -23,16 +22,16 @@ module ModelHelpers
23
22
 
24
23
  # Gets the class for a model at the specified path.
25
24
  def class_at_path(path)
26
- if path && path.last == :[]
25
+ if path
27
26
  begin
28
- # TODO: SECURITY on the back-end we need to check that the model class we're loading
29
- # is coming from the models folder.
30
-
31
27
  # remove the _ and then singularize
32
- klass_name = path[-2][1..-1].singularize.camelize
28
+ if path.last == :[]
29
+ klass_name = path[-2][1..-1].singularize.camelize
30
+ else
31
+ klass_name = path[-1][1..-1].singularize.camelize
32
+ end
33
33
 
34
- klass_name = klass_name.camelize
35
- klass = Object.send(:const_get, klass_name.to_sym)
34
+ klass = $page.model_classes[klass_name] || Model
36
35
  rescue NameError => e
37
36
  # Ignore exception, just means the model isn't defined
38
37
  klass = Model
@@ -31,7 +31,7 @@ module Persistors
31
31
  root_model.persistor.save_all
32
32
  end
33
33
 
34
- def loaded
34
+ def loaded(initial_state=nil)
35
35
  # When the main model is first loaded, we pull in the data from the
36
36
  # store if it exists
37
37
  if @model.path == []
@@ -31,7 +31,7 @@ require 'volt/page/tasks'
31
31
 
32
32
 
33
33
  class Page
34
- attr_reader :url, :params, :page, :templates, :routes, :events
34
+ attr_reader :url, :params, :page, :templates, :routes, :events, :model_classes
35
35
 
36
36
  def initialize
37
37
  @model_classes = {}
@@ -138,7 +138,7 @@ class Page
138
138
  end
139
139
 
140
140
  def add_model(model_name)
141
- @model_classes[["*", "_#{model_name}"]] = Object.const_get(model_name.camelize)
141
+ @model_classes[model_name] = Object.const_get(model_name.camelize)
142
142
  end
143
143
 
144
144
  def add_template(name, template, bindings)
@@ -19,7 +19,7 @@ class Dispatcher
19
19
  error = nil
20
20
  rescue => e
21
21
  # TODO: Log these errors better
22
- puts "ERROR: #{e.inspect}"
22
+ puts e.inspect
23
23
  puts e.backtrace
24
24
  result = nil
25
25
  error = e
@@ -1,12 +1,14 @@
1
+ require 'spec_helper'
1
2
  require 'volt/models'
2
- require 'volt/reactive/dependency'
3
- require 'volt/reactive/computation'
4
3
 
5
4
 
6
5
  class TestItem < Model
6
+ end
7
7
 
8
+ class Item < Model
8
9
  end
9
10
 
11
+
10
12
  describe Model do
11
13
 
12
14
  it "should allow _ methods to be used to store values without predefining them" do
@@ -413,4 +415,22 @@ describe Model do
413
415
  @model = Model.new(nil, persistor: persistor)
414
416
  end
415
417
  end
418
+
419
+ if RUBY_PLATFORM != 'opal'
420
+ describe "class loading" do
421
+ it 'should load classes for models' do
422
+ $page = Page.new
423
+ $page.add_model('Item')
424
+
425
+ @model = Model.new
426
+
427
+ # Should return a buffer of the right type
428
+ expect(@model._items.buffer.class).to eq(Item)
429
+
430
+ # Should insert as the right type
431
+ @model._items << {_name: 'Item 1'}
432
+ expect(@model._items[0].class).to eq(Item)
433
+ end
434
+ end
435
+ end
416
436
  end
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.4
4
+ version: 0.8.5
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-04 00:00:00.000000000 Z
11
+ date: 2014-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor