opal-vienna 0.7.0
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 +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +8 -0
- data/Gemfile +7 -0
- data/README.md +294 -0
- data/Rakefile +7 -0
- data/config.ru +8 -0
- data/lib/opal-vienna.rb +1 -0
- data/lib/opal/vienna.rb +7 -0
- data/lib/opal/vienna/version.rb +5 -0
- data/opal-vienna.gemspec +26 -0
- data/opal/vienna.rb +5 -0
- data/opal/vienna/adapters/base.rb +45 -0
- data/opal/vienna/adapters/local.rb +50 -0
- data/opal/vienna/adapters/rest.rb +97 -0
- data/opal/vienna/eventable.rb +35 -0
- data/opal/vienna/history_router.rb +44 -0
- data/opal/vienna/model.rb +222 -0
- data/opal/vienna/observable.rb +90 -0
- data/opal/vienna/observable_array.rb +73 -0
- data/opal/vienna/output_buffer.rb +13 -0
- data/opal/vienna/record_array.rb +31 -0
- data/opal/vienna/router.rb +85 -0
- data/opal/vienna/template_view.rb +41 -0
- data/opal/vienna/view.rb +93 -0
- data/spec/eventable_spec.rb +94 -0
- data/spec/history_router_spec.rb +47 -0
- data/spec/model/accessing_attributes_spec.rb +29 -0
- data/spec/model/as_json_spec.rb +28 -0
- data/spec/model/attribute_spec.rb +22 -0
- data/spec/model/initialize_spec.rb +42 -0
- data/spec/model/load_spec.rb +17 -0
- data/spec/model/persistence_spec.rb +84 -0
- data/spec/model_spec.rb +84 -0
- data/spec/observable_array_spec.rb +130 -0
- data/spec/observable_spec.rb +116 -0
- data/spec/output_buffer_spec.rb +37 -0
- data/spec/record_array_spec.rb +50 -0
- data/spec/route_spec.rb +89 -0
- data/spec/router_spec.rb +103 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/template_view_spec.rb +47 -0
- data/spec/vendor/jquery.js +2 -0
- data/spec/view_spec.rb +78 -0
- metadata +181 -0
| @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            require 'vienna/observable'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Vienna
         | 
| 4 | 
            +
              module ObservableArray
         | 
| 5 | 
            +
                include Vienna::Observable
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                attr_reader :content
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def initialize(content = [])
         | 
| 10 | 
            +
                  @content = content
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def inspect
         | 
| 14 | 
            +
                  "#<ObservableArray: #{content.inspect}>"
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                alias to_s inspect
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def array_content_did_change(idx, removed, added)
         | 
| 20 | 
            +
                  if observers = @array_observers
         | 
| 21 | 
            +
                    observers.each { |obj|
         | 
| 22 | 
            +
                      obj.array_did_change(self, idx, removed, added)
         | 
| 23 | 
            +
                    }
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  attribute_did_change :size
         | 
| 27 | 
            +
                  attribute_did_change :content
         | 
| 28 | 
            +
                  attribute_did_change :empty?
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def add_array_observer(obj)
         | 
| 32 | 
            +
                  (@array_observers ||= []) << obj
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def <<(obj)
         | 
| 36 | 
            +
                  length = @content.length
         | 
| 37 | 
            +
                  @content << obj
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  array_content_did_change length, 0, 1
         | 
| 40 | 
            +
                  self
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def delete(obj)
         | 
| 44 | 
            +
                  if idx = @content.index(obj)
         | 
| 45 | 
            +
                    @content.delete_at idx
         | 
| 46 | 
            +
                    array_content_did_change idx, 1, 0
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  obj
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def insert(idx, obj)
         | 
| 53 | 
            +
                  if idx > @content.length
         | 
| 54 | 
            +
                    raise ArgumentError, 'out of range'
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  @content.insert idx, obj
         | 
| 58 | 
            +
                  array_content_did_change idx, 0, 1
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  self
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                def clear
         | 
| 64 | 
            +
                  length = @content.length
         | 
| 65 | 
            +
                  @content.clear
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  array_content_did_change 0, length, 0
         | 
| 68 | 
            +
                  self
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                alias push <<
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
            end
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            require 'vienna/observable_array'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Vienna
         | 
| 4 | 
            +
              class RecordArray
         | 
| 5 | 
            +
                include ObservableArray
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                attr_writer :content
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def ==(arr)
         | 
| 10 | 
            +
                  if arr.respond_to? :content
         | 
| 11 | 
            +
                    @content == arr.content
         | 
| 12 | 
            +
                  else
         | 
| 13 | 
            +
                    @content == arr
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def method_missing(sym, *args, &block)
         | 
| 18 | 
            +
                  @content.__send__(sym, *args, &block)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def each(&block)
         | 
| 22 | 
            +
                  @content.each(&block)
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def size
         | 
| 26 | 
            +
                  @content.size
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                alias length size
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| @@ -0,0 +1,85 @@ | |
| 1 | 
            +
            require 'native'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Vienna
         | 
| 4 | 
            +
              class Router
         | 
| 5 | 
            +
                attr_reader :path, :routes
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(&block)
         | 
| 8 | 
            +
                  @routes = []
         | 
| 9 | 
            +
                  @location = $global.location
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  $global.addEventListener 'hashchange', -> { update }, false
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  instance_eval(&block) if block
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def route(path, &handler)
         | 
| 17 | 
            +
                  route = Route.new(path, &handler)
         | 
| 18 | 
            +
                  @routes << route
         | 
| 19 | 
            +
                  route
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def update
         | 
| 23 | 
            +
                  @path = if @location.hash.empty?
         | 
| 24 | 
            +
                    "/"
         | 
| 25 | 
            +
                  else
         | 
| 26 | 
            +
                    @location.hash.sub(/^#*/, '')
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  match @path
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def match(path)
         | 
| 33 | 
            +
                  @routes.find { |r| r.match path }
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                # Navigate to the given hash location. This adds the '#' 
         | 
| 37 | 
            +
                # fragment to the start of the path
         | 
| 38 | 
            +
                def navigate(path)
         | 
| 39 | 
            +
                  @location.hash = "##{path}"
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                class Route
         | 
| 43 | 
            +
                  # Regexp for matching named params in path
         | 
| 44 | 
            +
                  NAMED = /:(\w+)/
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  # Regexp for matching named splats in path
         | 
| 47 | 
            +
                  SPLAT = /\\\*(\w+)/
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  OPTIONAL = /\\\((.*?)\\\)/
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  attr_reader :regexp, :named
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  def initialize(pattern, &handler)
         | 
| 54 | 
            +
                    @named, @handler = [], handler
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    pattern = Regexp.escape pattern
         | 
| 57 | 
            +
                    pattern = pattern.gsub OPTIONAL, "(?:$1)?"
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    pattern.gsub(NAMED) { |m| @named << m[1..-1] }
         | 
| 60 | 
            +
                    pattern.gsub(SPLAT) { |m| @named << m[2..-1] }
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    pattern = pattern.gsub NAMED, "([^\\/]*)"
         | 
| 63 | 
            +
                    pattern = pattern.gsub SPLAT, "(.*?)"
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    @regexp = Regexp.new "^#{pattern}$"
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  # Return a hash of all named parts to values if route matches path, or
         | 
| 69 | 
            +
                  # nil otherwise
         | 
| 70 | 
            +
                  def match(path)
         | 
| 71 | 
            +
                    if match = @regexp.match(path)
         | 
| 72 | 
            +
                      params = {}
         | 
| 73 | 
            +
                      @named.each_with_index { |name, i| params[name] = match[i + 1] }
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                      @handler.call params if @handler
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                      return true
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    false
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
            end
         | 
| 85 | 
            +
             | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            require 'template'
         | 
| 2 | 
            +
            require 'vienna/view'
         | 
| 3 | 
            +
            require 'vienna/output_buffer'
         | 
| 4 | 
            +
            require 'active_support/core_ext/string'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Vienna
         | 
| 7 | 
            +
              class TemplateView < View
         | 
| 8 | 
            +
                def self.template(name = nil)
         | 
| 9 | 
            +
                  if name
         | 
| 10 | 
            +
                    @template = name
         | 
| 11 | 
            +
                  elsif @template
         | 
| 12 | 
            +
                    @template
         | 
| 13 | 
            +
                  elsif name = self.name
         | 
| 14 | 
            +
                    @template = name.sub(/View$/, '').demodulize.underscore
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def render
         | 
| 19 | 
            +
                  before_render
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  if template = Template[self.class.template]
         | 
| 22 | 
            +
                    element.html = _render_template(template)
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  after_render
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def partial(name)
         | 
| 29 | 
            +
                  Template[name].render(self)
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def _render_template(template)
         | 
| 33 | 
            +
                  @output_buffer = OutputBuffer.new
         | 
| 34 | 
            +
                  instance_exec @output_buffer, &template.body
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def before_render; end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                def after_render; end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
            end
         | 
    
        data/opal/vienna/view.rb
    ADDED
    
    | @@ -0,0 +1,93 @@ | |
| 1 | 
            +
            module Vienna
         | 
| 2 | 
            +
              class View
         | 
| 3 | 
            +
                def self.element(selector = nil)
         | 
| 4 | 
            +
                  selector ? @element = selector : @element
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def self.tag_name(tag = nil)
         | 
| 8 | 
            +
                  define_method(:tag_name) { tag } if tag
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def self.class_name(css_class = nil)
         | 
| 12 | 
            +
                  define_method(:class_name) { css_class } if css_class
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def self.events
         | 
| 16 | 
            +
                  @events ||= []
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def self.on(name, selector = nil, method = nil, &handler)
         | 
| 20 | 
            +
                  handler = proc { |evt| __send__(method, evt) } if method
         | 
| 21 | 
            +
                  events << [name, selector, handler]
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                attr_accessor :parent
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def element
         | 
| 27 | 
            +
                  return @element if @element
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  @element = create_element
         | 
| 30 | 
            +
                  @element.add_class class_name
         | 
| 31 | 
            +
                  setup_events
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  @element
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def create_element
         | 
| 37 | 
            +
                  scope = (self.parent ? parent.element : Element)
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  if el = self.class.element
         | 
| 40 | 
            +
                    scope.find el
         | 
| 41 | 
            +
                  else
         | 
| 42 | 
            +
                    e = scope.new tag_name
         | 
| 43 | 
            +
                    e.add_class class_name
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def render
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def class_name
         | 
| 51 | 
            +
                  ""
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def tag_name
         | 
| 55 | 
            +
                  "div"
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                def find(selector)
         | 
| 59 | 
            +
                  element.find(selector)
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def setup_events
         | 
| 63 | 
            +
                  return @dom_events if @dom_events
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  el = element
         | 
| 66 | 
            +
                  @dom_events = self.class.events.map do |event|
         | 
| 67 | 
            +
                    name, selector, handler = event
         | 
| 68 | 
            +
                    wrapper = proc { |e| instance_exec(e, &handler) }
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                    el.on(name, selector, &wrapper)
         | 
| 71 | 
            +
                    [name, selector, wrapper]
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                def teardown_events
         | 
| 76 | 
            +
                  el = element
         | 
| 77 | 
            +
                  @dom_events.each do |event|
         | 
| 78 | 
            +
                    name, selector, wrapper = event
         | 
| 79 | 
            +
                    el.off(name, selector, &wrapper)
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                def remove
         | 
| 84 | 
            +
                  element.remove
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                def destroy
         | 
| 88 | 
            +
                  teardown_events
         | 
| 89 | 
            +
                  remove
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
            end
         | 
| 93 | 
            +
             | 
| @@ -0,0 +1,94 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class EventableSpec
         | 
| 4 | 
            +
              include Vienna::Eventable
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              def events
         | 
| 7 | 
            +
                @eventable
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            describe Vienna::Eventable do
         | 
| 12 | 
            +
              subject { EventableSpec.new }
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              describe "#on" do
         | 
| 15 | 
            +
                it "should register event handlers for given name" do
         | 
| 16 | 
            +
                  handler = Proc.new {}
         | 
| 17 | 
            +
                  subject.on(:foo, &handler)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  expect(subject.events[:foo]).to eq([handler])
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                it "returns the given handler" do
         | 
| 23 | 
            +
                  handler = Proc.new {}
         | 
| 24 | 
            +
                  expect(subject.on(:foo, &handler)).to eq(handler)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              describe "#off" do
         | 
| 29 | 
            +
                it "has no affect if no handlers defined at all" do
         | 
| 30 | 
            +
                  subject.off(:bar, proc {})
         | 
| 31 | 
            +
                  subject.on(:foo) { raise "err" }
         | 
| 32 | 
            +
                  subject.off(:bar, proc {})
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                it "removes the handler for the event" do
         | 
| 36 | 
            +
                  called = false
         | 
| 37 | 
            +
                  handler = subject.on(:foo) { called = true }
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  subject.off(:foo, handler)
         | 
| 40 | 
            +
                  subject.trigger(:foo)
         | 
| 41 | 
            +
                  expect(called).to be_falsy
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              describe "#trigger" do
         | 
| 46 | 
            +
                it "should call handler" do
         | 
| 47 | 
            +
                  called = false
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  subject.on(:foo) { called = true }
         | 
| 50 | 
            +
                  called.should == false
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  subject.trigger(:foo)
         | 
| 53 | 
            +
                  called.should == true
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                it "should pass all arguments to handler" do
         | 
| 57 | 
            +
                  args = nil
         | 
| 58 | 
            +
                  subject.on(:foo) { |*a| args = a }
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  subject.trigger(:foo)
         | 
| 61 | 
            +
                  args.should == []
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  subject.trigger(:foo, 1)
         | 
| 64 | 
            +
                  args.should == [1]
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  subject.trigger(:foo, 1, 2, 3)
         | 
| 67 | 
            +
                  args.should == [1, 2, 3]
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                it "should allow multiple different events to be registered" do
         | 
| 71 | 
            +
                  result = []
         | 
| 72 | 
            +
                  subject.on(:foo) { result << :foo }
         | 
| 73 | 
            +
                  subject.on(:bar) { result << :bar }
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  subject.trigger(:foo)
         | 
| 76 | 
            +
                  result.should == [:foo]
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  subject.trigger(:bar)
         | 
| 79 | 
            +
                  result.should == [:foo, :bar]
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                it "should allow multiple handlers for an event" do
         | 
| 83 | 
            +
                  count = 0
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  subject.on(:foo) { count += 1 }
         | 
| 86 | 
            +
                  subject.on(:foo) { count += 1 }
         | 
| 87 | 
            +
                  subject.on(:foo) { count += 1 }
         | 
| 88 | 
            +
                  subject.on(:foo) { count += 1 }
         | 
| 89 | 
            +
                  subject.trigger(:foo)
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  count.should == 4
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
              end
         | 
| 94 | 
            +
            end
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'vienna/history_router'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe Vienna::HistoryRouter do
         | 
| 5 | 
            +
              describe '#update' do
         | 
| 6 | 
            +
                it 'updates path' do
         | 
| 7 | 
            +
                  subject.navigate('/foo')
         | 
| 8 | 
            +
                  expect(subject.path).to eq('/foo')
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                it 'calls #match with the new path' do
         | 
| 12 | 
            +
                  expect(subject).to receive('match').with('/new_url')
         | 
| 13 | 
            +
                  subject.navigate('/new_url')
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              describe '#route' do
         | 
| 18 | 
            +
                it 'should add a new route' do
         | 
| 19 | 
            +
                  subject.route('/users') {}
         | 
| 20 | 
            +
                  expect(subject.routes.size).to eq(1)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  subject.route('/hosts') {}
         | 
| 23 | 
            +
                  expect(subject.routes.size).to eq(2)
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              describe '#match' do
         | 
| 28 | 
            +
                it 'returns nil when no routes on router' do
         | 
| 29 | 
            +
                  expect(subject.match('/foo')).to be_nil
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                it 'returns the matching route for the path' do
         | 
| 33 | 
            +
                  a = subject.route('/foo') {}
         | 
| 34 | 
            +
                  b = subject.route('/bar') {}
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  expect(subject.match('/foo')).to eq(a)
         | 
| 37 | 
            +
                  expect(subject.match('/bar')).to eq(b)
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                it 'returns nil when no matching route' do
         | 
| 41 | 
            +
                  subject.route('/foo') {}
         | 
| 42 | 
            +
                  subject.route('/bar') {}
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  expect(subject.match('/baz')).to be_nil
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
            end
         |