volt 0.9.3.pre5 → 0.9.3.pre6
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 +2 -0
- data/app/volt/tasks/store_tasks.rb +0 -1
- data/lib/volt/cli/new_gem.rb +3 -9
- data/lib/volt/data_stores/data_store.rb +1 -1
- data/lib/volt/models/persistors/local_store.rb +3 -3
- data/lib/volt/models/persistors/model_store.rb +0 -5
- data/lib/volt/models/url.rb +10 -6
- data/lib/volt/page/channel.rb +3 -3
- data/lib/volt/page/page.rb +2 -1
- data/lib/volt/page/tasks.rb +3 -1
- data/lib/volt/reactive/reactive_array.rb +2 -1
- data/lib/volt/server.rb +4 -0
- data/lib/volt/server/forking_server.rb +41 -4
- data/lib/volt/server/forking_server/boot_error.html.erb +42 -0
- data/lib/volt/server/rack/opal_files.rb +1 -1
- data/lib/volt/server/socket_connection_handler.rb +19 -10
- data/lib/volt/server/websocket/websocket_handler.rb +1 -4
- data/lib/volt/spec/setup.rb +9 -1
- data/lib/volt/tasks/dispatcher.rb +10 -6
- data/lib/volt/utils/ejson.rb +55 -6
- data/lib/volt/utils/promise_extensions.rb +31 -8
- data/lib/volt/version.rb +1 -1
- data/lib/volt/volt/server_setup/app.rb +2 -1
- data/spec/models/model_spec.rb +10 -8
- data/spec/models/validators/length_validator_spec.rb +2 -2
- data/spec/models/validators/phone_number_validator_spec.rb +2 -2
- data/spec/utils/ejson_spec.rb +101 -0
- data/spec/utils/promise_extensions_spec.rb +16 -0
- data/templates/newgem/newgem.gemspec.tt +1 -0
- data/templates/newgem/spec/spec_helper.rb.tt +14 -2
- data/templates/project/config/base/index.html +4 -5
- metadata +5 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 6b47ed7510baf946cc2e65e7140be76022472b53
         | 
| 4 | 
            +
              data.tar.gz: cf681b804b8609987671fbf2626aaf399d39bec0
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: ffcd6ef512a9b74b519b1b2ee294b8bef5d00075b8052ab6c4cee1375fac9662d2d2991024a469ccb7b8cf3c0e1d7388999dc6e5ff908f1b48a6705e8cef12df
         | 
| 7 | 
            +
              data.tar.gz: 811b21c5c24ee684593c7069aba0cd68fad6480b22486c0646f34e67f365b8ab7e0ef36857c0defba4030fc9be243745f27c9a2e8930a7ba6fe58a29afc3dad0
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -19,6 +19,8 @@ | |
| 19 19 | 
             
            - Volt.current_user now works in HttpController's
         | 
| 20 20 | 
             
            - You can now add your own middleware to the middleware stack.  (see docs)
         | 
| 21 21 | 
             
            - Added a threadpool for Tasks, and options to customize pool size in config/app.rb
         | 
| 22 | 
            +
            - Volt now handles Syntax errors much better, it will display an error message when your app does not compile, and can reload from that page when things change. (in development)
         | 
| 23 | 
            +
            - Time objects can now be saved in models.
         | 
| 22 24 |  | 
| 23 25 | 
             
            ### Changed
         | 
| 24 26 | 
             
            - All methods on ArrayModel's under the store collection now return a Promise.
         | 
    
        data/lib/volt/cli/new_gem.rb
    CHANGED
    
    | @@ -57,15 +57,9 @@ class NewGem | |
| 57 57 |  | 
| 58 58 | 
             
              def copy_options
         | 
| 59 59 | 
             
                copy('newgem/bin/newgem.tt', "bin/#{@name}") if @options[:bin]
         | 
| 60 | 
            -
                 | 
| 61 | 
            -
                 | 
| 62 | 
            -
             | 
| 63 | 
            -
                  copy('newgem/spec/spec_helper.rb.tt', 'spec/spec_helper.rb')
         | 
| 64 | 
            -
                  copy('newgem/spec/newgem_spec.rb.tt', "spec/#{@namespaced_path}_spec.rb")
         | 
| 65 | 
            -
                when 'minitest'
         | 
| 66 | 
            -
                  copy('newgem/test/minitest_helper.rb.tt', 'test/minitest_helper.rb')
         | 
| 67 | 
            -
                  copy('newgem/test/test_newgem.rb.tt', "test/test_#{@namespaced_path}.rb")
         | 
| 68 | 
            -
                end
         | 
| 60 | 
            +
                copy('newgem/rspec.tt', '.rspec')
         | 
| 61 | 
            +
                copy('newgem/spec/spec_helper.rb.tt', 'spec/spec_helper.rb')
         | 
| 62 | 
            +
                copy('newgem/spec/newgem_spec.rb.tt', "spec/#{@namespaced_path}_spec.rb")
         | 
| 69 63 | 
             
                puts "Initializing git repo in #{@target}"
         | 
| 70 64 | 
             
                Dir.chdir(@target) { `git init`; `git add .` }
         | 
| 71 65 |  | 
| @@ -14,7 +14,7 @@ module Volt | |
| 14 14 | 
             
                    adaptor_name = root.const_get(adaptor_name)
         | 
| 15 15 | 
             
                    @adaptor = adaptor_name.new
         | 
| 16 16 | 
             
                  else
         | 
| 17 | 
            -
                    raise "#{database_name} is not a supported database"
         | 
| 17 | 
            +
                    raise "#{database_name} is not a supported database, you might be missing a volt-#{database_name} gem"
         | 
| 18 18 | 
             
                  end
         | 
| 19 19 |  | 
| 20 20 | 
             
                  @adaptor
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            require 'volt/models/persistors/base'
         | 
| 2 2 | 
             
            require 'volt/utils/local_storage'
         | 
| 3 | 
            -
            require ' | 
| 3 | 
            +
            require 'volt/utils/ejson'
         | 
| 4 4 |  | 
| 5 5 | 
             
            module Volt
         | 
| 6 6 | 
             
              module Persistors
         | 
| @@ -17,7 +17,7 @@ module Volt | |
| 17 17 | 
             
                    if @model.path == []
         | 
| 18 18 | 
             
                      json_data = LocalStorage['volt-store']
         | 
| 19 19 | 
             
                      if json_data
         | 
| 20 | 
            -
                        root_attributes =  | 
| 20 | 
            +
                        root_attributes = EJSON.parse(json_data)
         | 
| 21 21 |  | 
| 22 22 | 
             
                        @loading_data = true
         | 
| 23 23 | 
             
                        root_attributes.each_pair do |key, value|
         | 
| @@ -37,7 +37,7 @@ module Volt | |
| 37 37 | 
             
                  def save_all
         | 
| 38 38 | 
             
                    return if @loading_data
         | 
| 39 39 |  | 
| 40 | 
            -
                    json_data =  | 
| 40 | 
            +
                    json_data = EJSON.stringify(@model.to_h)
         | 
| 41 41 |  | 
| 42 42 | 
             
                    LocalStorage['volt-store'] = json_data
         | 
| 43 43 | 
             
                  end
         | 
    
        data/lib/volt/models/url.rb
    CHANGED
    
    | @@ -8,15 +8,18 @@ module Volt | |
| 8 8 | 
             
                include ReactiveAccessors
         | 
| 9 9 |  | 
| 10 10 | 
             
                # TODO: we need to make it so change events only trigger on changes
         | 
| 11 | 
            -
                reactive_accessor :scheme, :host, :port, :path, :query, : | 
| 11 | 
            +
                reactive_accessor :scheme, :host, :port, :path, :query, :fragment
         | 
| 12 12 | 
             
                attr_accessor :router
         | 
| 13 13 |  | 
| 14 14 | 
             
                def initialize(router = nil)
         | 
| 15 15 | 
             
                  @router = router
         | 
| 16 | 
            -
                  @params = Model.new({}, persistor: Persistors::Params)
         | 
| 17 16 | 
             
                  @location = Location.new
         | 
| 18 17 | 
             
                end
         | 
| 19 18 |  | 
| 19 | 
            +
                def params
         | 
| 20 | 
            +
                  @params ||= Model.new({}, persistor: Persistors::Params)
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 20 23 | 
             
                # Parse takes in a url and extracts each sections.
         | 
| 21 24 | 
             
                # It also assigns and changes to the params.
         | 
| 22 25 | 
             
                def parse(url)
         | 
| @@ -95,7 +98,7 @@ module Volt | |
| 95 98 | 
             
                end
         | 
| 96 99 |  | 
| 97 100 | 
             
                def url_with(params)
         | 
| 98 | 
            -
                  url_for( | 
| 101 | 
            +
                  url_for(params.to_h.merge(params))
         | 
| 99 102 | 
             
                end
         | 
| 100 103 |  | 
| 101 104 | 
             
                # Called when the state has changed and the url in the
         | 
| @@ -103,7 +106,7 @@ module Volt | |
| 103 106 | 
             
                # Called when an attribute changes to update the url
         | 
| 104 107 | 
             
                def update!
         | 
| 105 108 | 
             
                  if Volt.in_browser?
         | 
| 106 | 
            -
                    new_url = url_for( | 
| 109 | 
            +
                    new_url = url_for(params.to_h)
         | 
| 107 110 |  | 
| 108 111 | 
             
                    # Push the new url if pushState is supported
         | 
| 109 112 | 
             
                    # TODO: add fragment fallback
         | 
| @@ -158,8 +161,9 @@ module Volt | |
| 158 161 | 
             
                  query_hash.merge!(new_params)
         | 
| 159 162 |  | 
| 160 163 | 
             
                  # Loop through the .params we already have assigned.
         | 
| 161 | 
            -
                   | 
| 162 | 
            -
                   | 
| 164 | 
            +
                  lparams = params
         | 
| 165 | 
            +
                  assign_from_old(lparams, query_hash)
         | 
| 166 | 
            +
                  assign_new(lparams, query_hash)
         | 
| 163 167 | 
             
                end
         | 
| 164 168 |  | 
| 165 169 | 
             
                # Loop through the old params, and overwrite any existing values,
         | 
    
        data/lib/volt/page/channel.rb
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            # The channel is the connection between the front end and the backend.
         | 
| 2 2 |  | 
| 3 | 
            -
            require ' | 
| 3 | 
            +
            require 'volt/utils/ejson'
         | 
| 4 4 | 
             
            require 'volt/reactive/reactive_accessors'
         | 
| 5 5 | 
             
            require 'volt/reactive/eventable'
         | 
| 6 6 |  | 
| @@ -94,7 +94,7 @@ module Volt | |
| 94 94 | 
             
                end
         | 
| 95 95 |  | 
| 96 96 | 
             
                def message_received(message)
         | 
| 97 | 
            -
                  message =  | 
| 97 | 
            +
                  message = EJSON.parse(message)
         | 
| 98 98 |  | 
| 99 99 | 
             
                  trigger!('message', *message)
         | 
| 100 100 | 
             
                end
         | 
| @@ -104,7 +104,7 @@ module Volt | |
| 104 104 | 
             
                    @queue << message
         | 
| 105 105 | 
             
                  else
         | 
| 106 106 | 
             
                    # TODO: Temp: wrap message in an array, so we're sure its valid JSON
         | 
| 107 | 
            -
                    message =  | 
| 107 | 
            +
                    message = EJSON.stringify([message])
         | 
| 108 108 | 
             
                    `
         | 
| 109 109 | 
             
                      this.socket.send(message);
         | 
| 110 110 | 
             
                    `
         | 
    
        data/lib/volt/page/page.rb
    CHANGED
    
    | @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            require 'volt/utils/ejson'
         | 
| 1 2 |  | 
| 2 3 | 
             
            module Volt
         | 
| 3 4 | 
             
              class Page
         | 
| @@ -178,7 +179,7 @@ module Volt | |
| 178 179 | 
             
                      `if (page_obj_str) {`
         | 
| 179 180 | 
             
                      `sessionStorage.removeItem('___page');`
         | 
| 180 181 |  | 
| 181 | 
            -
                       | 
| 182 | 
            +
                      EJSON.parse(page_obj_str).each_pair do |key, value|
         | 
| 182 183 | 
             
                        page.send(:"_#{key}=", value)
         | 
| 183 184 | 
             
                      end
         | 
| 184 185 | 
             
                      `}`
         | 
    
        data/lib/volt/page/tasks.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            require 'volt/utils/ejson'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module Volt
         | 
| 2 4 | 
             
              # The tasks class provides an interface to call tasks on
         | 
| 3 5 | 
             
              # the backend server.  This class is setup as page.task (as a singleton)
         | 
| @@ -63,7 +65,7 @@ module Volt | |
| 63 65 |  | 
| 64 66 | 
             
                def reload
         | 
| 65 67 | 
             
                  # Stash the current page value
         | 
| 66 | 
            -
                  value =  | 
| 68 | 
            +
                  value = EJSON.stringify($page.page.to_h)
         | 
| 67 69 |  | 
| 68 70 | 
             
                  # If this browser supports session storage, store the page, so it will
         | 
| 69 71 | 
             
                  # be in the same state when we reload.
         | 
    
        data/lib/volt/server.rb
    CHANGED
    
    | @@ -17,6 +17,7 @@ require 'volt/page/page' | |
| 17 17 | 
             
            require 'volt/server/websocket/websocket_handler'
         | 
| 18 18 | 
             
            require 'volt/utils/read_write_lock'
         | 
| 19 19 | 
             
            require 'volt/server/forking_server'
         | 
| 20 | 
            +
            require 'volt/server/websocket/rack_server_adaptor'
         | 
| 20 21 |  | 
| 21 22 |  | 
| 22 23 | 
             
            module Volt
         | 
| @@ -49,6 +50,9 @@ module Volt | |
| 49 50 | 
             
                # killed when code changes and reforked.  (This provides simple fast code
         | 
| 50 51 | 
             
                # reloading)
         | 
| 51 52 | 
             
                def app
         | 
| 53 | 
            +
                  # Setup the rack server and adaptor
         | 
| 54 | 
            +
                  RackServerAdaptor.load
         | 
| 55 | 
            +
             | 
| 52 56 | 
             
                  app = Rack::Builder.new
         | 
| 53 57 |  | 
| 54 58 | 
             
                  # Handle websocket connections
         | 
| @@ -4,6 +4,15 @@ require 'drb' | |
| 4 4 | 
             
            require 'stringio'
         | 
| 5 5 | 
             
            require 'listen'
         | 
| 6 6 |  | 
| 7 | 
            +
            class ErrorDispatcher
         | 
| 8 | 
            +
              def dispatch(channel, message)
         | 
| 9 | 
            +
                Volt.logger.error("The app failed to start, so the following message can not be run: #{message}")
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              def close_channel(channel)
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 7 16 | 
             
            module Volt
         | 
| 8 17 | 
             
              class ForkingServer
         | 
| 9 18 | 
             
                def initialize(server)
         | 
| @@ -58,11 +67,17 @@ module Volt | |
| 58 67 | 
             
                      # Running as child
         | 
| 59 68 | 
             
                      @reader.close
         | 
| 60 69 |  | 
| 61 | 
            -
                       | 
| 62 | 
            -
             | 
| 70 | 
            +
                      begin
         | 
| 71 | 
            +
                        volt_app = @server.boot_volt
         | 
| 72 | 
            +
                        @rack_app = volt_app.middleware
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                        # Set the drb object locally
         | 
| 75 | 
            +
                        @dispatcher = Dispatcher.new(volt_app)
         | 
| 76 | 
            +
                      rescue Exception => error
         | 
| 77 | 
            +
                        boot_error(error)
         | 
| 78 | 
            +
                      end
         | 
| 79 | 
            +
             | 
| 63 80 |  | 
| 64 | 
            -
                      # Set the drb object locally
         | 
| 65 | 
            -
                      @dispatcher = Dispatcher.new(volt_app)
         | 
| 66 81 | 
             
                      drb_object = DRb.start_service('drbunix:', [self, @dispatcher])
         | 
| 67 82 |  | 
| 68 83 | 
             
                      @writer.puts(drb_object.uri)
         | 
| @@ -79,6 +94,28 @@ module Volt | |
| 79 94 | 
             
                  end
         | 
| 80 95 | 
             
                end
         | 
| 81 96 |  | 
| 97 | 
            +
                # called from the child when the boot failes.  Sets up an error page rack
         | 
| 98 | 
            +
                # app to show the user the error and handle reloading requests.
         | 
| 99 | 
            +
                def boot_error(error)
         | 
| 100 | 
            +
                  msg = error.inspect
         | 
| 101 | 
            +
                  if error.respond_to?(:backtrace)
         | 
| 102 | 
            +
                    msg << "\n" + error.backtrace.join("\n")
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
                  Volt.logger.error(msg)
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                  # Only require when needed
         | 
| 107 | 
            +
                  require 'cgi'
         | 
| 108 | 
            +
                  @rack_app = Proc.new do
         | 
| 109 | 
            +
                    path = File.join(File.dirname(__FILE__), "forking_server/boot_error.html.erb")
         | 
| 110 | 
            +
                    html = File.read(path)
         | 
| 111 | 
            +
                    error_page = ERB.new(html, nil, '-').result(binding)
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                    [500, {"Content-Type" => "text/html"}, error_page]
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                  @dispatcher = ErrorDispatcher.new
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
             | 
| 82 119 |  | 
| 83 120 | 
             
                def stop_child
         | 
| 84 121 | 
             
                  # clear the drb object and kill the child process.
         | 
| @@ -0,0 +1,42 @@ | |
| 1 | 
            +
            <!DOCTYPE html>
         | 
| 2 | 
            +
            <html>
         | 
| 3 | 
            +
              <head>
         | 
| 4 | 
            +
                <meta charset="UTF-8" />
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                <script>
         | 
| 7 | 
            +
                    // Simple code to handle reload messages
         | 
| 8 | 
            +
                    if (document.location.protocol == 'https:') {
         | 
| 9 | 
            +
                      var wsProto = 'wss';
         | 
| 10 | 
            +
                    } else {
         | 
| 11 | 
            +
                      var wsProto = 'ws';
         | 
| 12 | 
            +
                    }
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    this.socket = new WebSocket(wsProto + '://' + document.location.host + '/socket');
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                    // Log errors
         | 
| 17 | 
            +
                    this.socket.onerror = function (error) {
         | 
| 18 | 
            +
                      document.location.reload();
         | 
| 19 | 
            +
                    };
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    // Log messages from the server
         | 
| 22 | 
            +
                    this.socket.onmessage = function(message) {
         | 
| 23 | 
            +
                      if (message.data == '["reload"]') {
         | 
| 24 | 
            +
                        document.location.reload();
         | 
| 25 | 
            +
                      }
         | 
| 26 | 
            +
                    };
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    this.socket.onclose = function(error) {
         | 
| 29 | 
            +
                      document.location.reload();
         | 
| 30 | 
            +
                    };
         | 
| 31 | 
            +
                </script>
         | 
| 32 | 
            +
              </head>
         | 
| 33 | 
            +
              <body>
         | 
| 34 | 
            +
                <h2><%= CGI::escapeHTML(error.inspect) %></h2>
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                <% if error.respond_to?(:backtrace) %>
         | 
| 37 | 
            +
            <pre>
         | 
| 38 | 
            +
            <%= error.backtrace.map {|l| CGI::escapeHTML(l) }.join("<br />") %>
         | 
| 39 | 
            +
            </pre>
         | 
| 40 | 
            +
                <% end %>
         | 
| 41 | 
            +
              </body>
         | 
| 42 | 
            +
            </html>
         | 
| @@ -22,7 +22,7 @@ module Volt | |
| 22 22 | 
             
                  Opal.append_path(Volt.root + '/app')
         | 
| 23 23 | 
             
                  Opal.append_path(Volt.root + '/lib')
         | 
| 24 24 |  | 
| 25 | 
            -
                  Gem.loaded_specs.values.select {|gem| gem.name =~ /^volt/ }
         | 
| 25 | 
            +
                  Gem.loaded_specs.values.select {|gem| gem.name =~ /^(volt|ejson_ext)/ }
         | 
| 26 26 | 
             
                  .each do |gem|
         | 
| 27 27 | 
             
                    ['app', 'lib'].each do |folder|
         | 
| 28 28 | 
             
                      path = gem.full_gem_path + "/#{folder}"
         | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            require ' | 
| 1 | 
            +
            require 'volt/utils/ejson'
         | 
| 2 2 | 
             
            require File.join(File.dirname(__FILE__), '../../../app/volt/tasks/query_tasks')
         | 
| 3 3 |  | 
| 4 4 | 
             
            module Volt
         | 
| @@ -9,6 +9,14 @@ module Volt | |
| 9 9 | 
             
                # This may be changed as new listeners connect, which is fine.
         | 
| 10 10 | 
             
                attr_accessor :user_id
         | 
| 11 11 |  | 
| 12 | 
            +
             | 
| 13 | 
            +
                def initialize(session, *args)
         | 
| 14 | 
            +
                  @session = session
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  @@channels ||= []
         | 
| 17 | 
            +
                  @@channels << self
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 12 20 | 
             
                def self.dispatcher=(val)
         | 
| 13 21 | 
             
                  @@dispatcher = val
         | 
| 14 22 | 
             
                end
         | 
| @@ -26,17 +34,10 @@ module Volt | |
| 26 34 | 
             
                  end
         | 
| 27 35 | 
             
                end
         | 
| 28 36 |  | 
| 29 | 
            -
                def initialize(session, *args)
         | 
| 30 | 
            -
                  @session = session
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                  @@channels ||= []
         | 
| 33 | 
            -
                  @@channels << self
         | 
| 34 | 
            -
                end
         | 
| 35 | 
            -
             | 
| 36 37 | 
             
                def process_message(message)
         | 
| 37 38 | 
             
                  # self.class.message_all(message)
         | 
| 38 39 | 
             
                  # Messages are json and wrapped in an array
         | 
| 39 | 
            -
                  message =  | 
| 40 | 
            +
                  message = EJSON.parse(message).first
         | 
| 40 41 |  | 
| 41 42 | 
             
                  begin
         | 
| 42 43 | 
             
                    @@dispatcher.dispatch(self, message)
         | 
| @@ -51,9 +52,17 @@ module Volt | |
| 51 52 | 
             
                end
         | 
| 52 53 |  | 
| 53 54 | 
             
                def send_message(*args)
         | 
| 54 | 
            -
                  str =  | 
| 55 | 
            +
                  str = EJSON.stringify([*args])
         | 
| 55 56 |  | 
| 56 57 | 
             
                  @session.send(str)
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  if RUNNING_SERVER == 'thin'
         | 
| 60 | 
            +
                    # This might seem strange, but it prevents a delay with outgoing
         | 
| 61 | 
            +
                    # messages.
         | 
| 62 | 
            +
                    # TODO: Figure out the cause of the issue and submit a fix upstream.
         | 
| 63 | 
            +
                    EM.next_tick {}
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 57 66 | 
             
                end
         | 
| 58 67 |  | 
| 59 68 | 
             
                def closed
         | 
| @@ -1,13 +1,10 @@ | |
| 1 1 | 
             
            require 'faye/websocket'
         | 
| 2 2 | 
             
            require 'volt/server/socket_connection_handler'
         | 
| 3 | 
            -
             | 
| 3 | 
            +
             | 
| 4 4 |  | 
| 5 5 | 
             
            module Volt
         | 
| 6 6 | 
             
              class WebsocketHandler
         | 
| 7 7 | 
             
                def initialize(app)
         | 
| 8 | 
            -
                  # Setup the rack server and adaptor
         | 
| 9 | 
            -
                  RackServerAdaptor.load
         | 
| 10 | 
            -
             | 
| 11 8 | 
             
                  @app = app
         | 
| 12 9 | 
             
                end
         | 
| 13 10 |  | 
    
        data/lib/volt/spec/setup.rb
    CHANGED
    
    | @@ -49,7 +49,7 @@ module Volt | |
| 49 49 |  | 
| 50 50 | 
             
                  # Setup the spec collection accessors
         | 
| 51 51 | 
             
                  # RSpec.shared_context "volt collections", {} do
         | 
| 52 | 
            -
                  RSpec. | 
| 52 | 
            +
                  RSpec.shared_context 'volt collections', {} do
         | 
| 53 53 | 
             
                    # Page conflicts with capybara's page method, so we call it the_page for now.
         | 
| 54 54 | 
             
                    # TODO: we need a better solution for page
         | 
| 55 55 |  | 
| @@ -60,7 +60,15 @@ module Volt | |
| 60 60 | 
             
                      $page.store
         | 
| 61 61 | 
             
                    end
         | 
| 62 62 | 
             
                    let(:volt_app) { volt_app }
         | 
| 63 | 
            +
                    let(:params) { volt_app.page.params }
         | 
| 63 64 |  | 
| 65 | 
            +
                    after do
         | 
| 66 | 
            +
                      # Clear params if used
         | 
| 67 | 
            +
                      url = volt_app.page.url
         | 
| 68 | 
            +
                      if url.instance_variable_get('@params')
         | 
| 69 | 
            +
                        url.instance_variable_set('@params', nil)
         | 
| 70 | 
            +
                      end
         | 
| 71 | 
            +
                    end
         | 
| 64 72 |  | 
| 65 73 | 
             
                    if RUBY_PLATFORM != 'opal'
         | 
| 66 74 | 
             
                      after do |example|
         | 
| @@ -2,6 +2,7 @@ | |
| 2 2 | 
             
            require 'volt/utils/logging/task_logger'
         | 
| 3 3 | 
             
            require 'drb'
         | 
| 4 4 | 
             
            require 'concurrent'
         | 
| 5 | 
            +
            require 'timeout'
         | 
| 5 6 |  | 
| 6 7 | 
             
            module Volt
         | 
| 7 8 | 
             
              # The task dispatcher is responsible for taking incoming messages
         | 
| @@ -95,11 +96,13 @@ module Volt | |
| 95 96 | 
             
                    # Init and send the method
         | 
| 96 97 | 
             
                    promise = promise.then do
         | 
| 97 98 | 
             
                      result = nil
         | 
| 98 | 
            -
                       | 
| 99 | 
            +
                      Timeout.timeout(klass.__timeout || @worker_timeout) do
         | 
| 99 100 | 
             
                        Thread.current['meta'] = meta_data
         | 
| 100 | 
            -
                         | 
| 101 | 
            -
             | 
| 102 | 
            -
                         | 
| 101 | 
            +
                        begin
         | 
| 102 | 
            +
                          result = klass.new(@volt_app, channel, self).send(method_name, *args)
         | 
| 103 | 
            +
                        ensure
         | 
| 104 | 
            +
                          Thread.current['meta'] = nil
         | 
| 105 | 
            +
                        end
         | 
| 103 106 | 
             
                      end
         | 
| 104 107 |  | 
| 105 108 | 
             
                      result
         | 
| @@ -112,8 +115,9 @@ module Volt | |
| 112 115 |  | 
| 113 116 | 
             
                  # Called after task runs or fails
         | 
| 114 117 | 
             
                  finish = proc do |error|
         | 
| 115 | 
            -
                    if error.is_a?( | 
| 116 | 
            -
                       | 
| 118 | 
            +
                    if error.is_a?(Timeout::Error)
         | 
| 119 | 
            +
                      # re-raise with a message
         | 
| 120 | 
            +
                      error = Timeout::Error.new("Task Timed Out after #{@worker_timeout} seconds: #{message}")
         | 
| 117 121 | 
             
                    end
         | 
| 118 122 |  | 
| 119 123 | 
             
                    run_time = ((Time.now.to_f - start_time) * 1000).round(3)
         | 
    
        data/lib/volt/utils/ejson.rb
    CHANGED
    
    | @@ -1,11 +1,60 @@ | |
| 1 | 
            +
            require 'json'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module Volt
         | 
| 2 | 
            -
              class  | 
| 3 | 
            -
                def self. | 
| 4 | 
            -
                  obj
         | 
| 4 | 
            +
              class EJSON
         | 
| 5 | 
            +
                def self.stringify(obj)
         | 
| 6 | 
            +
                  encode(obj).to_json
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def self.parse(str)
         | 
| 10 | 
            +
                  decode(JSON.parse(str))
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                private
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def self.decode(obj)
         | 
| 16 | 
            +
                  if Array === obj
         | 
| 17 | 
            +
                    obj.map {|v| decode(v) }
         | 
| 18 | 
            +
                  elsif Hash === obj
         | 
| 19 | 
            +
                    if obj.size == 1 && (escape = obj['$escape'])
         | 
| 20 | 
            +
                      return escape.map do |key, value|
         | 
| 21 | 
            +
                        [key, decode(value)]
         | 
| 22 | 
            +
                      end.to_h
         | 
| 23 | 
            +
                    elsif obj.size == 1 && (time = obj['$date'])
         | 
| 24 | 
            +
                      if time.is_a?(Fixnum)
         | 
| 25 | 
            +
                        return Time.at(time / 1000.0)
         | 
| 26 | 
            +
                      end
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    obj.map do |key, value|
         | 
| 30 | 
            +
                      [key, decode(value)]
         | 
| 31 | 
            +
                    end.to_h
         | 
| 32 | 
            +
                  else
         | 
| 33 | 
            +
                    obj
         | 
| 34 | 
            +
                  end
         | 
| 5 35 | 
             
                end
         | 
| 6 36 |  | 
| 7 | 
            -
                def self. | 
| 8 | 
            -
                   | 
| 37 | 
            +
                def self.encode(obj)
         | 
| 38 | 
            +
                  if Array === obj
         | 
| 39 | 
            +
                    obj.map {|v| encode(v) }
         | 
| 40 | 
            +
                  elsif Hash === obj
         | 
| 41 | 
            +
                    obj.map do |key, value|
         | 
| 42 | 
            +
                      if key == '$date'
         | 
| 43 | 
            +
                        key = '$escape'
         | 
| 44 | 
            +
                        value = {'$date' => encode(value)}
         | 
| 45 | 
            +
                      else
         | 
| 46 | 
            +
                        value = encode(value)
         | 
| 47 | 
            +
                      end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                      [key, value]
         | 
| 50 | 
            +
                    end.to_h
         | 
| 51 | 
            +
                  else
         | 
| 52 | 
            +
                    if obj.is_a?(Time)
         | 
| 53 | 
            +
                      {'$date' => obj.to_i * 1_000}
         | 
| 54 | 
            +
                    else
         | 
| 55 | 
            +
                      obj
         | 
| 56 | 
            +
                    end
         | 
| 57 | 
            +
                  end
         | 
| 9 58 | 
             
                end
         | 
| 10 59 | 
             
              end
         | 
| 11 | 
            -
            end
         | 
| 60 | 
            +
            end
         | 
| @@ -4,16 +4,25 @@ require 'volt/utils/promise' | |
| 4 4 | 
             
            # A temp patch for promises until https://github.com/opal/opal/pull/725 is released.
         | 
| 5 5 | 
             
            class Promise
         | 
| 6 6 |  | 
| 7 | 
            -
               | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 7 | 
            +
              # We made a choice not to support comparitors and << and >> on method_missing
         | 
| 8 | 
            +
              # on Promises.  This makes it easier to understand what promise proxying does
         | 
| 9 | 
            +
              # and how it works.  It also prevents confusing situations where you try to
         | 
| 10 | 
            +
              # == compare two Promises for example.  The cost though is more code to do
         | 
| 11 | 
            +
              # comparisons, but we feel it is worth it.
         | 
| 12 | 
            +
              def respond_to_missing?(method_name, include_private = false)
         | 
| 13 | 
            +
                !!(method_name =~ /[a-z_]\w*[?!=]?/)
         | 
| 13 14 | 
             
              end
         | 
| 14 15 |  | 
| 15 | 
            -
              def  | 
| 16 | 
            -
                 | 
| 16 | 
            +
              def method_missing(method_name, *args, &block)
         | 
| 17 | 
            +
                if respond_to_missing?(method_name)
         | 
| 18 | 
            +
                  promise = self.then do |value|
         | 
| 19 | 
            +
                    value.send(method_name, *args, &block)
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  promise
         | 
| 23 | 
            +
                else
         | 
| 24 | 
            +
                  super
         | 
| 25 | 
            +
                end
         | 
| 17 26 | 
             
              end
         | 
| 18 27 |  | 
| 19 28 | 
             
              # Allow .each to be called directly on promises
         | 
| @@ -56,6 +65,20 @@ class Promise | |
| 56 65 | 
             
                @value || @error
         | 
| 57 66 | 
             
              end
         | 
| 58 67 |  | 
| 68 | 
            +
              # When testing with rspec, add in a custom exception! method that doesn't
         | 
| 69 | 
            +
              # swallow ExpectationNotMetError's.
         | 
| 70 | 
            +
              if defined?(RSpec::Expectations::ExpectationNotMetError)
         | 
| 71 | 
            +
                def exception!(error)
         | 
| 72 | 
            +
                  if error.is_a?(RSpec::Expectations::ExpectationNotMetError)
         | 
| 73 | 
            +
                    raise error
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
                  @exception = true
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  reject!(error)
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
             | 
| 59 82 |  | 
| 60 83 | 
             
              # Waits for the promise to resolve (assuming it is blocking on
         | 
| 61 84 | 
             
              # the server) and returns the result.
         | 
    
        data/lib/volt/version.rb
    CHANGED
    
    
| @@ -48,7 +48,8 @@ module Volt | |
| 48 48 |  | 
| 49 49 | 
             
                  # This config needs to run earlier than others
         | 
| 50 50 | 
             
                  def run_config
         | 
| 51 | 
            -
                     | 
| 51 | 
            +
                    path = "#{Volt.root}/config/app.rb"
         | 
| 52 | 
            +
                    require(path) if File.exists?(path)
         | 
| 52 53 | 
             
                  end
         | 
| 53 54 |  | 
| 54 55 | 
             
                  # Load in all .rb files in the initializers folders and the config/app.rb
         | 
    
        data/spec/models/model_spec.rb
    CHANGED
    
    | @@ -232,18 +232,20 @@ describe Volt::Model do | |
| 232 232 | 
             
                expect(count).to eq(1)
         | 
| 233 233 | 
             
              end
         | 
| 234 234 |  | 
| 235 | 
            -
               | 
| 236 | 
            -
                 | 
| 235 | 
            +
              unless RUBY_PLATFORM == 'opal'
         | 
| 236 | 
            +
                it 'should track changes through an expansion' do
         | 
| 237 | 
            +
                  a = Volt::Model.new
         | 
| 237 238 |  | 
| 238 | 
            -
             | 
| 239 | 
            -
             | 
| 239 | 
            +
                  last_count = 0
         | 
| 240 | 
            +
                  -> { last_count = a._todos.count(&:_checked).sync }.watch!
         | 
| 240 241 |  | 
| 241 | 
            -
             | 
| 242 | 
            +
                  expect(last_count).to eq(0)
         | 
| 242 243 |  | 
| 243 | 
            -
             | 
| 244 | 
            -
             | 
| 244 | 
            +
                  a._todos! << { checked: true }
         | 
| 245 | 
            +
                  Volt::Computation.flush!
         | 
| 245 246 |  | 
| 246 | 
            -
             | 
| 247 | 
            +
                  expect(last_count).to eq(1)
         | 
| 248 | 
            +
                end
         | 
| 247 249 | 
             
              end
         | 
| 248 250 |  | 
| 249 251 | 
             
              it 'should call changed when a the reference to a submodel is assigned to another value' do
         | 
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 3 | 
             
            describe Volt::LengthValidator do
         | 
| 4 | 
            -
              subject { Volt::LengthValidator.validate(* | 
| 5 | 
            -
              let(: | 
| 4 | 
            +
              subject { Volt::LengthValidator.validate(*use_params) }
         | 
| 5 | 
            +
              let(:use_params) { [model, field_name, options] }
         | 
| 6 6 |  | 
| 7 7 | 
             
              let(:model) { Volt::Model.new name: name }
         | 
| 8 8 | 
             
              let(:field_name) { :name }
         | 
| @@ -15,8 +15,8 @@ describe Volt::PhoneNumberValidator do | |
| 15 15 | 
             
              let(:valid_intl_number) { '+12 123 123 1234' }
         | 
| 16 16 | 
             
              let(:invalid_number) { '1234-123-123456' }
         | 
| 17 17 |  | 
| 18 | 
            -
              let(:validate) { described_class.validate(* | 
| 19 | 
            -
              let(: | 
| 18 | 
            +
              let(:validate) { described_class.validate(*use_params) }
         | 
| 19 | 
            +
              let(:use_params) { [model, field_name, options] }
         | 
| 20 20 | 
             
              let(:message) { 'must be a phone number with area or country code' }
         | 
| 21 21 |  | 
| 22 22 | 
             
              it_behaves_like 'a format validator'
         | 
| @@ -0,0 +1,101 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Volt::EJSON, '.parse' do
         | 
| 4 | 
            +
              subject { Volt::EJSON }
         | 
| 5 | 
            +
              let(:epoch) { 135820576553 }
         | 
| 6 | 
            +
              let(:ruby_epoch) { epoch / 1000.0 }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              context 'safe escaping' do
         | 
| 9 | 
            +
                it 'does not parse date objects with invalid values' do
         | 
| 10 | 
            +
                  parsed = subject.parse '{"a" : {"$escape" : {"$date" : "something"}}}'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  expect(parsed).to eq('a' => { '$date' => 'something' })
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                it 'only escapes one level down' do
         | 
| 16 | 
            +
                  parsed = subject.parse %({"$escape": {"$date": {"$date": #{epoch}}}})
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  expect(parsed).to eq('$date' => Time.at(ruby_epoch))
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              context 'parsing EJSON fields' do
         | 
| 23 | 
            +
                context 'date' do
         | 
| 24 | 
            +
                  it 'is not parsed when given a bad value' do
         | 
| 25 | 
            +
                    expect(subject.parse '{"a": {"$date" : "something"}}').
         | 
| 26 | 
            +
                      to eq('a' => { '$date' => 'something' })
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  it 'parses proper $date EJSON fields' do
         | 
| 30 | 
            +
                    parsed = subject.parse '{"a" : {"$date": 135820576553}}'
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                    expect(parsed['a']).to eq Time.at(ruby_epoch)
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  it 'parses nested EJSON date fields' do
         | 
| 36 | 
            +
                    parsed = subject.parse '{"a" : {"b" : {"$date": 135820576553}}}'
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                    expect(parsed['a']['b']).to eq Time.at(ruby_epoch)
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  it 'parses nested $dates within $escapes' do
         | 
| 42 | 
            +
                    parsed = subject.parse(
         | 
| 43 | 
            +
                      '{"a" : {"$escape": {"$date" : {"date" : {"$date": 135820576553}}}}}'
         | 
| 44 | 
            +
                    )
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    expect(parsed['a']['$date']['date']).to eq Time.at(ruby_epoch)
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  it 'parses multiple EJSON date fields' do
         | 
| 50 | 
            +
                    ejson = begin
         | 
| 51 | 
            +
                      %({"when":{"$date":#{epoch}},"then":{"$date":#{epoch}}})
         | 
| 52 | 
            +
                    end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                    expect(subject.parse ejson).to eq(
         | 
| 55 | 
            +
                      "when" => Time.at(ruby_epoch),
         | 
| 56 | 
            +
                      "then" => Time.at(ruby_epoch)
         | 
| 57 | 
            +
                    )
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
            end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            describe Volt::EJSON, '.stringify' do
         | 
| 64 | 
            +
              subject { Volt::EJSON }
         | 
| 65 | 
            +
              context 'marshaling dates' do
         | 
| 66 | 
            +
                let(:now) { Time.now }
         | 
| 67 | 
            +
                let(:now_js_epoch) { now.to_i * 1_000 }
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                it 'does nothing with regular hashes' do
         | 
| 70 | 
            +
                  stringified = subject.stringify plain: 'jane'
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  expect(stringified).to eq '{"plain":"jane"}'
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                it 'marshals when given a date' do
         | 
| 76 | 
            +
                  stringified = subject.stringify when: now
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  expect(stringified).to eq %({"when":{"$date":#{now_js_epoch}}})
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                it 'marshals nested dates' do
         | 
| 82 | 
            +
                  stringified = subject.stringify how: { when: now }
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  expect(stringified).to eq %({"how":{"when":{"$date":#{now_js_epoch}}}})
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                it 'marshals multiple dates' do
         | 
| 88 | 
            +
                  stringified = subject.stringify when: now, then: now
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  expect(stringified.gsub(' ', '')).to eq(
         | 
| 91 | 
            +
                    %({"when":{"$date":#{now_js_epoch}},"then":{"$date":#{now_js_epoch}}})
         | 
| 92 | 
            +
                  )
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                it 'escapes reserved key when type is incorrect' do
         | 
| 96 | 
            +
                  stringified = subject.stringify '$date' => 'something'
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                  expect(stringified).to eq '{"$escape":{"$date":"something"}}'
         | 
| 99 | 
            +
                end
         | 
| 100 | 
            +
              end
         | 
| 101 | 
            +
            end
         | 
| @@ -39,4 +39,20 @@ describe Promise do | |
| 39 39 |  | 
| 40 40 | 
             
                expect(count_occurences(b.inspect, 'Promise')).to eq(1)
         | 
| 41 41 | 
             
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              it 'should not respond to comparitors' do
         | 
| 44 | 
            +
                [:>, :<].each do |comp|
         | 
| 45 | 
            +
                  a = Promise.new
         | 
| 46 | 
            +
                  expect do
         | 
| 47 | 
            +
                    a.send(comp, 5)
         | 
| 48 | 
            +
                  end.to raise_error(NoMethodError)
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              it 'should proxy methods on promises' do
         | 
| 53 | 
            +
                a = Promise.new
         | 
| 54 | 
            +
                expect do
         | 
| 55 | 
            +
                  a.something
         | 
| 56 | 
            +
                end.not_to raise_error
         | 
| 57 | 
            +
              end
         | 
| 42 58 | 
             
            end
         | 
| @@ -19,6 +19,7 @@ Gem::Specification.new do |spec| | |
| 19 19 | 
             
              spec.require_paths = ["lib"]
         | 
| 20 20 |  | 
| 21 21 | 
             
              spec.add_development_dependency "volt", "~> <%= config[:volt_version_base] %>"
         | 
| 22 | 
            +
              spec.add_development_dependency 'rspec', '~> 3.2.0'
         | 
| 22 23 | 
             
              spec.add_development_dependency "rake"
         | 
| 23 24 | 
             
            <% if config[:test] -%>
         | 
| 24 25 | 
             
              spec.add_development_dependency "<%=config[:test]%>"
         | 
| @@ -1,2 +1,14 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            require ' | 
| 1 | 
            +
            # Volt sets up rspec and capybara for testing.
         | 
| 2 | 
            +
            require 'volt/spec/setup'
         | 
| 3 | 
            +
            Volt.spec_setup
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            RSpec.configure do |config|
         | 
| 6 | 
            +
              config.run_all_when_everything_filtered = true
         | 
| 7 | 
            +
              config.filter_run :focus
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              # Run specs in random order to surface order dependencies. If you find an
         | 
| 10 | 
            +
              # order dependency and want to debug it, you can fix the order by providing
         | 
| 11 | 
            +
              # the seed, which is printed after each run.
         | 
| 12 | 
            +
              #     --seed 1234
         | 
| 13 | 
            +
              config.order = 'random'
         | 
| 14 | 
            +
            end
         | 
| @@ -1,10 +1,9 @@ | |
| 1 | 
            -
            <%# IMPORTANT: Please read before changing!                                   %>
         | 
| 2 | 
            -
            <%# This file is rendered on the server using ERB, so it does NOT use Volt's  %>
         | 
| 3 | 
            -
            <%# normal template system. You can add to it, but keep in mind the template  %>
         | 
| 4 | 
            -
            <%# language difference. This file handles auto-loading all JS/Opal and CSS.  %>
         | 
| 5 | 
            -
             | 
| 6 1 | 
             
            <!DOCTYPE html>
         | 
| 7 2 | 
             
            <html>
         | 
| 3 | 
            +
              <%# IMPORTANT: Please read before changing!                                   %>
         | 
| 4 | 
            +
              <%# This file is rendered on the server using ERB, so it does NOT use Volt's  %>
         | 
| 5 | 
            +
              <%# normal template system. You can add to it, but keep in mind the template  %>
         | 
| 6 | 
            +
              <%# language difference. This file handles auto-loading all JS/Opal and CSS.  %>
         | 
| 8 7 | 
             
              <head>
         | 
| 9 8 | 
             
                <meta charset="UTF-8" />
         | 
| 10 9 | 
             
                <% javascript_files.each do |javascript_file| %>
         | 
    
        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.9.3. | 
| 4 | 
            +
              version: 0.9.3.pre6
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Ryan Stout
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2015-06- | 
| 11 | 
            +
            date: 2015-06-09 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: thor
         | 
| @@ -526,6 +526,7 @@ files: | |
| 526 526 | 
             
            - lib/volt/server/component_handler.rb
         | 
| 527 527 | 
             
            - lib/volt/server/component_templates.rb
         | 
| 528 528 | 
             
            - lib/volt/server/forking_server.rb
         | 
| 529 | 
            +
            - lib/volt/server/forking_server/boot_error.html.erb
         | 
| 529 530 | 
             
            - lib/volt/server/html_parser/attribute_scope.rb
         | 
| 530 531 | 
             
            - lib/volt/server/html_parser/component_view_scope.rb
         | 
| 531 532 | 
             
            - lib/volt/server/html_parser/each_scope.rb
         | 
| @@ -720,6 +721,7 @@ files: | |
| 720 721 | 
             
            - spec/tasks/query_tracker_spec.rb
         | 
| 721 722 | 
             
            - spec/tasks/user_tasks_spec.rb
         | 
| 722 723 | 
             
            - spec/templates/targets/binding_document/component_node_spec.rb
         | 
| 724 | 
            +
            - spec/utils/ejson_spec.rb
         | 
| 723 725 | 
             
            - spec/utils/generic_counting_pool_spec.rb
         | 
| 724 726 | 
             
            - spec/utils/generic_pool_spec.rb
         | 
| 725 727 | 
             
            - spec/utils/parsing_spec.rb
         | 
| @@ -964,6 +966,7 @@ test_files: | |
| 964 966 | 
             
            - spec/tasks/query_tracker_spec.rb
         | 
| 965 967 | 
             
            - spec/tasks/user_tasks_spec.rb
         | 
| 966 968 | 
             
            - spec/templates/targets/binding_document/component_node_spec.rb
         | 
| 969 | 
            +
            - spec/utils/ejson_spec.rb
         | 
| 967 970 | 
             
            - spec/utils/generic_counting_pool_spec.rb
         | 
| 968 971 | 
             
            - spec/utils/generic_pool_spec.rb
         | 
| 969 972 | 
             
            - spec/utils/parsing_spec.rb
         |