bluesky 0.0.1 → 0.1.0

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: 8026d38b693a30250518feaa44d015bc53d84f6c
4
- data.tar.gz: e176fc2a30755f2580ea12a2871abf415b561aca
3
+ metadata.gz: 7e338bf2cf158cd50ad10a1b536b79a7353ac3f8
4
+ data.tar.gz: 3b58b50347ebcdc8372823f589e477865766e0ff
5
5
  SHA512:
6
- metadata.gz: 2e833e11e26b668e146c76cffeb5df9404ee5a938e38d5bfa04148884b3ec9203a7da46e528b0dcf6bccff416b657581c826b1c2e8a884990f1c722e52a6bcac
7
- data.tar.gz: 8e4b9b75a7d66d8d934dcb5d30f6bcd3fb125b99680297f002bc75534746d8244ddc02df4f906f4da480ac7649f8263aaa88745fa2b9e33a037566e7a5f1f4e5
6
+ metadata.gz: 98722b63ffc517414e6d89f23802861a0d6665ed752e0130ceb1c8ad349cb8a1d6fd2396f7e2863849d2650b4eaff1c56dd578fb292fc95d0555aff518f534d0
7
+ data.tar.gz: dd6b122929fefd65889d58d75ad7106191c21a8338b7f2b1d6249f099a7d72aeab4cfd1293e200dc81e3df202ddf8c83ba4d5098e45e2358d0786c7f8601298c
@@ -1,11 +1,16 @@
1
1
  module Bluesky
2
2
 
3
- # Bluesky::Application
3
+ # The application entry point
4
4
  class Application
5
5
 
6
6
  include DOMHelper
7
+ include TryHelper
7
8
 
8
- attr_accessor :root_view_controller, :debug, :delegate
9
+ # Top level ViewController
10
+ attr_accessor :root_view_controller
11
+
12
+ # Receives all notifications
13
+ attr_accessor :delegate
9
14
 
10
15
  def initialize
11
16
  @dispatch_queue = []
@@ -16,84 +21,83 @@ module Bluesky
16
21
  @debug
17
22
  end
18
23
 
24
+ # Turns on debug logging
19
25
  def debug!
20
26
  @debug = true
21
- @clearwater.debug! if @clearwater
22
- @delegate = DebugDelegate.new(@delegate)
23
27
  self
24
28
  end
25
29
 
30
+ # Dispatches an action on target
31
+ #
32
+ # Attributes:
33
+ # target: (Object) The object that receives the send action
34
+ # action (Symbol) The method symbol on target
35
+ # payload: (Array) The arguments passed to send if any
36
+ # block: (Block) Optional block that will be passed as argument to send
26
37
  def dispatch(target, action, *payload, &block)
27
38
  promise = Promise.new
28
- delegate.try(:dispatch, target, action, *payload)
39
+ notify(self, :dispatch_requested, target, action, *payload)
29
40
  @dispatch_queue << lambda do
30
41
  begin
31
42
  result = target.send(action, *payload, &block)
32
43
  promise.resolve(result).then { refresh }
33
- delegate.try(:dispatch_resolved, target, action, *payload, result)
44
+ notify(self, :dispatch_resolved, target, action, *payload, result)
34
45
  rescue => err
35
46
  promise.reject(err)
36
- delegate.try(:dispatch_rejected, target, action, *payload, err)
47
+ notify(self, :dispatch_rejected, target, action, *payload, err)
37
48
  end
38
49
  end
39
50
  defer { process_dispatch_queue }
40
51
  promise
41
52
  end
42
53
 
43
- def process_dispatch_queue
44
- return if @dispatch_queue.empty?
45
- @dispatch_queue.delete_if do |task|
46
- task.call
47
- true
48
- end
49
- end
50
54
 
55
+ # Notifies the delegate about an event
56
+ #
57
+ # Attributes:
58
+ # source: (Object) The object that send the event
59
+ # event: (Symbol) The event symbol
60
+ # payload: (Array) Additional arguments to pass along
51
61
  def notify(source, event, *payload)
52
- @delegate.try(:notify, source, event, *payload)
62
+ try(@delegate, source, event, *payload)
63
+ puts "#{event} #{payload}" if debug?
53
64
  end
54
65
 
66
+ # Refreshes (runs render) on the root_view_controller and invokes the block
67
+ # (if any) when the render is complete.
55
68
  def refresh(&block)
56
69
  promise = Promise.new
57
70
  @clearwater.call { promise.resolve }
58
71
  block ? promise.then(&block) : promise
59
72
  end
60
73
 
74
+ # Does the required wiring and runs the initial render
61
75
  def run
62
76
  raise 'root_view_controller must be defined in Application' unless root_view_controller
63
77
  PureComponent.install_hooks(debug?)
64
78
  root_view_controller.parent = self
65
- @clearwater = Clearwater::Application.new(component: root_view_controller)
79
+ router = RUBY_ENGINE != 'opal' ?
80
+ Clearwater::Router.new(location: 'http://localhost:9292/') :
81
+ Clearwater::Router.new
82
+ @clearwater = Clearwater::Application.new(
83
+ component: root_view_controller,
84
+ router: router
85
+ )
66
86
  @clearwater.debug! if debug?
67
87
  root_view_controller.begin_appearance_transition(true)
68
88
  refresh { root_view_controller.end_appearance_transition() }
69
89
  self
70
90
  end
71
91
 
72
- end
73
-
74
- class DebugDelegate
75
-
76
- def initialize(delegate = nil)
77
- @delegate = delegate
78
- end
79
- def dispatch(target, action, *payload)
80
- @delegate.try(:dispatch, target, action, *payload)
81
- puts "[DISPATCH] #{action} on #{target}"
82
- end
83
-
84
- def dispatch_resolved(target, action, *payload, result)
85
- @delegate.try(:dispatch_resolved, result, target, action, *payload)
86
- puts "[RESOLVED] #{action} on #{target} yielding #{result}"
87
- end
88
-
89
- def dispatch_rejected(target, action, *payload, error)
90
- @delegate.try(:dispatch_rejected, target, action, *payload, error)
91
- puts "[REJECTED] #{action} on #{target}"
92
- warn error
93
- end
92
+ private
94
93
 
95
- def notify(source, event, *payload)
96
- puts "[NOTIFY] #{event} from #{source}"
94
+ # Processes queued dispatches
95
+ def process_dispatch_queue
96
+ return if @dispatch_queue.empty?
97
+ @dispatch_queue.delete_if do |task|
98
+ task.call
99
+ true
100
+ end
97
101
  end
98
102
 
99
103
  end
@@ -34,4 +34,31 @@ module Bluesky
34
34
  end
35
35
 
36
36
  end
37
+
38
+ module ConditionHelper
39
+
40
+ extend self
41
+
42
+ protected
43
+
44
+ def pre(&block)
45
+ raise 'Precondition is violated' unless block.call
46
+ end
47
+
48
+ end
49
+
50
+ module TryHelper
51
+
52
+ extend self
53
+
54
+ protected
55
+
56
+ def try(target, *a, &b)
57
+ return nil if target.respond_to?(:nil?) && target.nil?
58
+ return target.public_send(*a, &b) if target.respond_to?(:public_send)
59
+ return nil
60
+ end
61
+
62
+ end
63
+
37
64
  end
@@ -1,14 +1,14 @@
1
+ require_relative './view_controller'
2
+
1
3
  module Bluesky
2
4
 
3
5
  # Bluesky::NavigationController
4
6
  class NavigationController < ViewController
5
7
 
6
- attr_accessor :root_view_contrller
7
-
8
8
  def initialize(root_view_controller)
9
9
  raise 'NavigationController requires a root_view_controller' unless root_view_controller
10
10
  super
11
- add_child_view_controller(root_view_controller)
11
+ @children = [root_view_controller]
12
12
  end
13
13
 
14
14
  def view
@@ -16,18 +16,22 @@ module Bluesky
16
16
  end
17
17
 
18
18
  def view_will_appear
19
+ super
19
20
  top_view_controller.begin_appearance_transition(true)
20
21
  end
21
22
 
22
23
  def view_did_appear
24
+ super
23
25
  top_view_controller.end_appearance_transition
24
26
  end
25
27
 
26
28
  def view_will_disappear
27
- top_view_controller.end_appearance_transition(false)
29
+ super
30
+ top_view_controller.begin_appearance_transition(false)
28
31
  end
29
32
 
30
33
  def view_did_disappear
34
+ super
31
35
  top_view_controller.end_appearance_transition
32
36
  end
33
37
 
@@ -43,32 +47,56 @@ module Bluesky
43
47
  top_view_controller
44
48
  end
45
49
 
50
+ def view_controllers
51
+ @children
52
+ end
53
+
54
+ def view_controllers=(controllers)
55
+ index = @children.index(controllers.last)
56
+ pop_to_root_view_controller(controllers.last) unless index.nil?
57
+ @children.replace(controllers)
58
+ end
59
+
46
60
  def push_view_controller(view_controller)
47
61
  old_view_controller = top_view_controller
48
62
  old_view_controller.begin_appearance_transition(false)
49
- view_controller.begin_appearance_transition(true)
63
+ view_controller.begin_appearance_transition(@appearance == :appeared)
50
64
  add_child_view_controller(view_controller)
51
65
  force_update do
52
66
  view_controller.end_appearance_transition
53
67
  old_view_controller.end_appearance_transition
54
68
  end
69
+ return
55
70
  end
56
71
 
57
72
  def pop_view_controller
58
- return nil if top_view_controller == root_view_controller
59
- old_view_controller = top_view_controller
60
- old_view_controller.begin_appearance_transition(false)
61
- old_view_controller.remove_from_parent_view_controller
62
- top_view_controller.begin_appearance_transition(true)
73
+ pre { top_view_controller != root_view_controller }
74
+ popped_view_controller = top_view_controller
75
+ popped_view_controller.begin_appearance_transition(false)
76
+ popped_view_controller.remove_from_parent_view_controller()
77
+ top_view_controller.begin_appearance_transition(@appearance == :appeared)
63
78
  force_update do
64
- top_view_controller.end_appearance_transition
65
- old_view_controller.end_appearance_transition
79
+ top_view_controller.end_appearance_transition()
80
+ popped_view_controller.end_appearance_transition()
66
81
  end
82
+ return popped_view_controller
67
83
  end
68
84
 
69
85
  def pop_to_view_controller(view_controller)
70
- result = []
71
- result << pop_view_controller while top_view_controller != view_controller
86
+ index = @children.index(view_controller)
87
+ count = index.nil? ? 0 : index + 1
88
+ removed = @children[count..-1]
89
+ @children = @children[0...count]
90
+ removed.each { |child| child.begin_appearance_transition(false) }
91
+ top_view_controller.begin_appearance_transition(@appearance == :appeared)
92
+ force_update do
93
+ top_view_controller.end_appearance_transition()
94
+ removed.each do |child|
95
+ child.parent = nil
96
+ child.end_appearance_transition()
97
+ end
98
+ end
99
+ return removed
72
100
  end
73
101
 
74
102
  def pop_to_root_view_controller
@@ -1,40 +1,8 @@
1
1
 
2
- module Bluesky
3
-
4
- module DSL
5
-
6
- module_function
7
-
8
- Clearwater::Component::HTML_TAGS.each do |tag_name|
9
- define_method(tag_name) do |attributes, content|
10
- %x{
11
- if(!(attributes === nil || attributes.$$is_hash)) {
12
- content = attributes;
13
- attributes = nil;
14
- }
15
- }
16
-
17
- tag(tag_name, attributes, content)
18
- end
19
- end
2
+ require 'clearwater'
3
+ require_relative './dsl'
20
4
 
21
- def tag(tag_name, attributes=nil, content=nil, &block)
22
-
23
- if block
24
- attributes ||= {}
25
- content ||= []
26
- block.call(NodeBuilder.new(tag_name, attributes, content))
27
- end
28
-
29
- Clearwater::VirtualDOM.node(
30
- tag_name,
31
- Clearwater::Component.sanitize_attributes(attributes),
32
- Clearwater::Component.sanitize_content(content)
33
- )
34
- end
35
-
36
-
37
- end
5
+ module Bluesky
38
6
 
39
7
  # A presentation `Component`
40
8
  class PureComponent
@@ -1,3 +1,3 @@
1
1
  module Bluesky
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,3 +1,7 @@
1
+ require 'clearwater'
2
+ require_relative './helpers'
3
+ require_relative './dsl'
4
+
1
5
  module Bluesky
2
6
 
3
7
  class ViewController
@@ -5,6 +9,7 @@ module Bluesky
5
9
  include Clearwater::Component
6
10
  include DOMHelper
7
11
  include DSL
12
+ include ConditionHelper
8
13
 
9
14
  def self.attribute(name, *args, &block)
10
15
  case args.length
@@ -29,7 +34,7 @@ module Bluesky
29
34
  end
30
35
  end
31
36
 
32
- attr_accessor :children, :parent, :data
37
+ attr_accessor :children, :parent, :data, :appearance
33
38
 
34
39
  def initialize(*_, children: [], parent: nil, data: {})
35
40
  @children = children
@@ -53,20 +58,22 @@ module Bluesky
53
58
  end
54
59
 
55
60
  def dispatch(target, action, *payload, &block)
56
- parent.try(:dispatch, target, action, *payload, &block)
61
+ try(parent, :dispatch, target, action, *payload, &block)
57
62
  end
58
63
 
59
64
  def notify(source, event, *payload)
60
- parent.try(:notify, source, event, *payload)
65
+ try(parent, :notify, source, event, *payload)
61
66
  end
62
67
 
63
68
  def begin_appearance_transition(appearing)
64
69
  if appearing
65
- raise "Invalid appearance #{@appearance} when appearing" if @appearance != :disappeared
70
+ return unless @appearance == :disappeared
71
+ # raise "Invalid appearance #{@appearance} when appearing" if @appearance != :disappeared
66
72
  @appearance = :appearing
67
73
  view_will_appear()
68
74
  else
69
- raise "Invalid appearance #{@appearance} when disappearing" if @appearance != :appeared
75
+ return unless @appearance == :appeared
76
+ # raise "Invalid appearance #{@appearance} when disappearing" if @appearance != :appeared
70
77
  @appearance = :disappearing
71
78
  view_will_disappear()
72
79
  end
@@ -81,7 +88,7 @@ module Bluesky
81
88
  @appearance = :disappeared
82
89
  view_did_disappear()
83
90
  else
84
- raise "Invalid appearance #{@appearance} when transitioning"
91
+ # raise "Invalid appearance #{@appearance} when transitioning"
85
92
  end
86
93
  end
87
94
 
@@ -112,7 +119,7 @@ module Bluesky
112
119
 
113
120
  def navigation_controller
114
121
  parent.is_a?(NavigationController) ? parent :
115
- parent.try(:navigation_controller)
122
+ try(parent, :navigation_controller)
116
123
  end
117
124
 
118
125
  # Callbacks
data/lib/bluesky.rb CHANGED
@@ -35,8 +35,7 @@ module Clearwater
35
35
  end
36
36
  end
37
37
 
38
- require_relative 'bluesky/try.rb'
39
- require_relative 'bluesky/dom_helper.rb'
38
+ require_relative 'bluesky/helpers.rb'
40
39
  require_relative 'bluesky/node_builder.rb'
41
40
  require_relative 'bluesky/pure_component.rb'
42
41
  require_relative 'bluesky/view_controller.rb'
@@ -0,0 +1,161 @@
1
+ require 'test_helper'
2
+
3
+ # See test_helper for #appeared?, #disappeared? and #reset!
4
+ # test_helper also defines a mock application as parent for all new instances
5
+ module TestNavigationController
6
+
7
+ class Constructed < Minitest::Test
8
+
9
+ include Bluesky
10
+
11
+ def setup
12
+ @subject = NavigationController.new(ViewController.new)
13
+ end
14
+
15
+ def test_appearing_it_appears
16
+ refute @subject.appeared?
17
+ @subject.begin_appearance_transition(true)
18
+ @subject.end_appearance_transition()
19
+ assert @subject.appeared?
20
+ end
21
+
22
+ def test_adding_child_updates_top_view_controller
23
+ child = ViewController.new
24
+ @subject.push_view_controller(child)
25
+ assert_equal child, @subject.top_view_controller
26
+ end
27
+
28
+ def test_pop_view_controller_throws
29
+ assert_raises { @subject.pop_view_controller() }
30
+ end
31
+
32
+ end
33
+
34
+ class Appeared < Minitest::Test
35
+
36
+ include Bluesky
37
+
38
+ def setup
39
+ @subject = NavigationController.new(ViewController.new)
40
+ @subject.begin_appearance_transition(true)
41
+ @subject.end_appearance_transition()
42
+ end
43
+
44
+ def test_when_disappearing_it_disappears
45
+ refute @subject.disappeared?
46
+ @subject.begin_appearance_transition(false)
47
+ @subject.end_appearance_transition()
48
+ assert @subject.disappeared?
49
+ end
50
+
51
+ def test_when_appearing_nothing_happens
52
+ @subject.reset!
53
+ @subject.begin_appearance_transition(true)
54
+ @subject.end_appearance_transition()
55
+ refute @subject.appeared?
56
+ refute @subject.disappeared?
57
+ end
58
+
59
+ def test_adding_child_then_child_appears
60
+ child = ViewController.new
61
+ @subject.push_view_controller(child)
62
+ assert child.appeared?
63
+ end
64
+
65
+ end
66
+
67
+ class WithChild < Minitest::Test
68
+
69
+ include Bluesky
70
+
71
+ def setup
72
+ @subject = NavigationController.new(ViewController.new)
73
+ @child = ViewController.new
74
+ @subject.push_view_controller(@child)
75
+ end
76
+
77
+ def test_pop_view_controller_returns_child
78
+ assert_equal @child, @subject.pop_view_controller()
79
+ end
80
+
81
+ def test_appearing_shows_both_subject_and_child_but_not_root_view_controller
82
+ @subject.begin_appearance_transition(true)
83
+ @subject.end_appearance_transition()
84
+
85
+ assert @subject.appeared?
86
+ assert @child.appeared?
87
+ refute @subject.root_view_controller.appeared?
88
+ end
89
+
90
+ def test_moveing_reparents_child
91
+ target = NavigationController.new(ViewController.new)
92
+ target.push_view_controller(@child)
93
+ assert_equal target, @child.parent
94
+ end
95
+
96
+
97
+ end
98
+
99
+ class WithChildren < Minitest::Test
100
+
101
+ include Bluesky
102
+
103
+ def setup
104
+ @subject = NavigationController.new(ViewController.new)
105
+ @children = [ViewController.new, ViewController.new, ViewController.new]
106
+ @children.each { |child| @subject.push_view_controller(child) }
107
+ end
108
+
109
+ def test_pop_view_controller_returns_last_child
110
+ last = @children.last
111
+ assert_equal last, @subject.pop_view_controller()
112
+ end
113
+
114
+ def test_appearing_only_shows_last_child
115
+ @subject.begin_appearance_transition(true)
116
+ @subject.end_appearance_transition()
117
+ last = @children.pop
118
+ assert last.appeared?
119
+ refute @subject.root_view_controller.appeared?
120
+ refute @children.any? &:appeared?
121
+ end
122
+
123
+ def test_pop_to_root_removes_children
124
+ assert_equal @children, @subject.pop_to_root_view_controller()
125
+ end
126
+
127
+ end
128
+
129
+ class WithChildrenAndAppeared < Minitest::Test
130
+
131
+ include Bluesky
132
+
133
+ def setup
134
+ @subject = NavigationController.new(ViewController.new)
135
+ @children = [ViewController.new, ViewController.new, ViewController.new]
136
+ @children.each { |child| @subject.push_view_controller(child) }
137
+ @subject.begin_appearance_transition(true)
138
+ @subject.end_appearance_transition()
139
+ end
140
+
141
+ def test_pop_to_root_hides_last_child
142
+ @subject.pop_to_root_view_controller()
143
+ assert @children.last.disappeared?
144
+ end
145
+
146
+ def test_pop_to_root_shows_root_view_controller
147
+ @subject.pop_to_root_view_controller()
148
+ assert @subject.root_view_controller.appeared?
149
+ end
150
+
151
+ def test_move_top_view_controller_to_hidden_parent_hides_it
152
+ child = @subject.top_view_controller
153
+ target = NavigationController.new(ViewController.new)
154
+ target.push_view_controller(child)
155
+ assert child.disappeared?
156
+ end
157
+
158
+ end
159
+
160
+ end
161
+
@@ -0,0 +1,74 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+ require 'bluesky/view_controller'
4
+ require 'bluesky/navigation_controller'
5
+
6
+ class MockApplication < Bluesky::ViewController
7
+
8
+ def refresh
9
+ yield if block_given?
10
+ end
11
+
12
+ def force_update
13
+ yield if block_given?
14
+ end
15
+
16
+ end
17
+
18
+ class Bluesky::ViewController
19
+
20
+ def index
21
+ @index ||= 0
22
+ @index += 1
23
+ end
24
+
25
+ def view_will_appear
26
+ @will_appear = index
27
+ end
28
+
29
+ def view_did_appear
30
+ @did_appear = index
31
+ end
32
+
33
+ def view_will_disappear
34
+ @will_disappear = index
35
+ end
36
+
37
+ def view_did_disappear
38
+ @did_disappear = index
39
+ end
40
+
41
+ def appeared?
42
+ !!(@will_appear && @did_appear && @will_appear < @did_appear &&
43
+ (@will_disappear ? @will_appear > @will_disappear : true) &&
44
+ (@did_disappear ? @did_appear > @did_disappear : true))
45
+ end
46
+
47
+ def disappeared?
48
+ !!(@will_disappear && @did_disappear && @will_disappear < @did_disappear &&
49
+ (@will_appear ? @will_disappear > @will_appear : true) &&
50
+ (@did_appear ? @did_disappear > @did_appear : true))
51
+ end
52
+
53
+ def reset!
54
+ @will_appear = @did_appear = @will_disappear = @did_disappear = false
55
+ @index = 0
56
+ end
57
+
58
+ def dump
59
+ puts "will_appear == #{@will_appear}"
60
+ puts "did_appear == #{@did_appear}"
61
+ puts "will_disappear == #{@will_disappear}"
62
+ puts "did_disappear == #{@did_disappear}"
63
+ end
64
+
65
+ end
66
+
67
+ class Bluesky::NavigationController
68
+ def self.new *args
69
+ instance = super
70
+ instance.parent = MockApplication.new
71
+ instance
72
+ end
73
+ end
74
+
@@ -0,0 +1,29 @@
1
+ require 'test_helper'
2
+
3
+ # See test_helper for #appeared?, #disappeared? and #reset!
4
+ module TestViewController
5
+
6
+ class Constructed < Minitest::Test
7
+
8
+ include Bluesky
9
+
10
+ def setup
11
+ @subject = ViewController.new
12
+ end
13
+
14
+ def test_appearing_it_appears
15
+ @subject.begin_appearance_transition(true)
16
+ @subject.end_appearance_transition()
17
+ assert @subject.appeared?
18
+ end
19
+
20
+ def test_add_child_view_controller_reparents_child
21
+ child = ViewController.new
22
+ assert_nil child.parent
23
+ @subject.add_child_view_controller(child)
24
+ assert_equal @subject, child.parent
25
+ end
26
+
27
+ end
28
+
29
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bluesky
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Susi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-24 00:00:00.000000000 Z
11
+ date: 2017-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
@@ -39,48 +39,20 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.0.0.rc4
41
41
  - !ruby/object:Gem::Dependency
42
- name: opal-rspec
42
+ name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rspec
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rake
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
45
+ - - "~>"
74
46
  - !ruby/object:Gem::Version
75
- version: '0'
47
+ version: '5.10'
76
48
  type: :development
77
49
  prerelease: false
78
50
  version_requirements: !ruby/object:Gem::Requirement
79
51
  requirements:
80
- - - ">="
52
+ - - "~>"
81
53
  - !ruby/object:Gem::Version
82
- version: '0'
83
- description: An app framework for Clearwater
54
+ version: '5.10'
55
+ description: An app framework built on top of opal and clearwater
84
56
  email: john@susi.se
85
57
  executables:
86
58
  - bluesky
@@ -90,14 +62,14 @@ files:
90
62
  - bin/bluesky
91
63
  - lib/bluesky.rb
92
64
  - lib/bluesky/application.rb
93
- - lib/bluesky/dom_helper.rb
65
+ - lib/bluesky/helpers.rb
94
66
  - lib/bluesky/navigation_controller.rb
95
67
  - lib/bluesky/pure_component.rb
96
- - lib/bluesky/try.rb
97
68
  - lib/bluesky/version.rb
98
69
  - lib/bluesky/view_controller.rb
99
- - spec/bluesky_spec.rb
100
- - spec/spec_helper.rb
70
+ - test/navigation_controller_test.rb
71
+ - test/test_helper.rb
72
+ - test/view_controller_test.rb
101
73
  homepage: http://rubygems.org/gems/bluesky
102
74
  licenses:
103
75
  - MIT
@@ -123,5 +95,6 @@ signing_key:
123
95
  specification_version: 4
124
96
  summary: An app framework for Clearwater
125
97
  test_files:
126
- - spec/spec_helper.rb
127
- - spec/bluesky_spec.rb
98
+ - test/test_helper.rb
99
+ - test/view_controller_test.rb
100
+ - test/navigation_controller_test.rb
data/lib/bluesky/try.rb DELETED
@@ -1,100 +0,0 @@
1
- class Object
2
- # Invokes the public method whose name goes as first argument just like
3
- # +public_send+ does, except that if the receiver does not respond to it the
4
- # call returns +nil+ rather than raising an exception.
5
- #
6
- # This method is defined to be able to write
7
- #
8
- # @person.try(:name)
9
- #
10
- # instead of
11
- #
12
- # @person.name if @person
13
- #
14
- # +try+ calls can be chained:
15
- #
16
- # @person.try(:spouse).try(:name)
17
- #
18
- # instead of
19
- #
20
- # @person.spouse.name if @person && @person.spouse
21
- #
22
- # +try+ will also return +nil+ if the receiver does not respond to the method:
23
- #
24
- # @person.try(:non_existing_method) #=> nil
25
- #
26
- # instead of
27
- #
28
- # @person.non_existing_method if @person.respond_to?(:non_existing_method) #=> nil
29
- #
30
- # +try+ returns +nil+ when called on +nil+ regardless of whether it responds
31
- # to the method:
32
- #
33
- # nil.try(:to_i) # => nil, rather than 0
34
- #
35
- # Arguments and blocks are forwarded to the method if invoked:
36
- #
37
- # @posts.try(:each_slice, 2) do |a, b|
38
- # ...
39
- # end
40
- #
41
- # The number of arguments in the signature must match. If the object responds
42
- # to the method the call is attempted and +ArgumentError+ is still raised
43
- # in case of argument mismatch.
44
- #
45
- # If +try+ is called without arguments it yields the receiver to a given
46
- # block unless it is +nil+:
47
- #
48
- # @person.try do |p|
49
- # ...
50
- # end
51
- #
52
- # You can also call try with a block without accepting an argument, and the block
53
- # will be instance_eval'ed instead:
54
- #
55
- # @person.try { upcase.truncate(50) }
56
- #
57
- # Please also note that +try+ is defined on +Object+. Therefore, it won't work
58
- # with instances of classes that do not have +Object+ among their ancestors,
59
- # like direct subclasses of +BasicObject+. For example, using +try+ with
60
- # +SimpleDelegator+ will delegate +try+ to the target instead of calling it on
61
- # the delegator itself.
62
- def try(*a, &b)
63
- try!(*a, &b) if a.empty? || respond_to?(a.first)
64
- end
65
-
66
- # Same as #try, but will raise a NoMethodError exception if the receiver is not +nil+ and
67
- # does not implement the tried method.
68
-
69
- def try!(*a, &b)
70
- if a.empty? && block_given?
71
- if b.arity.zero?
72
- instance_eval(&b)
73
- else
74
- yield self
75
- end
76
- else
77
- public_send(*a, &b)
78
- end
79
- end
80
- end
81
-
82
- class NilClass
83
- # Calling +try+ on +nil+ always returns +nil+.
84
- # It becomes especially helpful when navigating through associations that may return +nil+.
85
- #
86
- # nil.try(:name) # => nil
87
- #
88
- # Without +try+
89
- # @person && @person.children.any? && @person.children.first.name
90
- #
91
- # With +try+
92
- # @person.try(:children).try(:first).try(:name)
93
- def try(*args)
94
- nil
95
- end
96
-
97
- def try!(*args)
98
- nil
99
- end
100
- end
data/spec/bluesky_spec.rb DELETED
@@ -1,34 +0,0 @@
1
- require 'bluesky'
2
-
3
- class RootView < Bluesky::PureComponent
4
-
5
- def render
6
- nil
7
- end
8
- end
9
-
10
- class RootViewController < Bluesky::ViewController
11
-
12
- def view
13
- RootView.new
14
- end
15
-
16
- end
17
-
18
- class Application < Bluesky::Application
19
-
20
- root_view_controller RootViewController
21
-
22
- end
23
-
24
- describe Application do
25
- context 'when run' do
26
- it 'calls render on the root_view_controller' do
27
- logger = double()
28
- application = Application.new
29
- application.logger = logger
30
- expect(logger).to receive(:render).with(application)
31
- application.run
32
- end
33
- end
34
- end
data/spec/spec_helper.rb DELETED
@@ -1,109 +0,0 @@
1
- # This file was generated by the `rspec --init` command. Conventionally, all
2
- # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
- # The generated `.rspec` file contains `--require spec_helper` which will cause
4
- # this file to always be loaded, without a need to explicitly require it in any
5
- # files.
6
- #
7
- # Given that it is always loaded, you are encouraged to keep this file as
8
- # light-weight as possible. Requiring heavyweight dependencies from this file
9
- # will add to the boot time of your test suite on EVERY test run, even for an
10
- # individual file that may not need all of that loaded. Instead, consider making
11
- # a separate helper file that requires the additional dependencies and performs
12
- # the additional setup, and require it from the spec files that actually need
13
- # it.
14
- #
15
- # The `.rspec` file also contains a few flags that are not defaults but that
16
- # users commonly want.
17
- #
18
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19
- require 'bundler/setup'
20
- Bundler.setup
21
-
22
- require 'clearwater'
23
- require 'bluesky'
24
-
25
- RSpec.configure do |config|
26
- # rspec-expectations config goes here. You can use an alternate
27
- # assertion/expectation library such as wrong or the stdlib/minitest
28
- # assertions if you prefer.
29
- config.expect_with :rspec do |expectations|
30
- # This option will default to `true` in RSpec 4. It makes the `description`
31
- # and `failure_message` of custom matchers include text for helper methods
32
- # defined using `chain`, e.g.:
33
- # be_bigger_than(2).and_smaller_than(4).description
34
- # # => "be bigger than 2 and smaller than 4"
35
- # ...rather than:
36
- # # => "be bigger than 2"
37
- expectations.include_chain_clauses_in_custom_matcher_descriptions = true
38
- end
39
-
40
- # rspec-mocks config goes here. You can use an alternate test double
41
- # library (such as bogus or mocha) by changing the `mock_with` option here.
42
- config.mock_with :rspec do |mocks|
43
- # Prevents you from mocking or stubbing a method that does not exist on
44
- # a real object. This is generally recommended, and will default to
45
- # `true` in RSpec 4.
46
- mocks.verify_partial_doubles = true
47
- end
48
-
49
- # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
50
- # have no way to turn it off -- the option exists only for backwards
51
- # compatibility in RSpec 3). It causes shared context metadata to be
52
- # inherited by the metadata hash of host groups and examples, rather than
53
- # triggering implicit auto-inclusion in groups with matching metadata.
54
- config.shared_context_metadata_behavior = :apply_to_host_groups
55
-
56
- # The settings below are suggested to provide a good initial experience
57
- # with RSpec, but feel free to customize to your heart's content.
58
- =begin
59
- # This allows you to limit a spec run to individual examples or groups
60
- # you care about by tagging them with `:focus` metadata. When nothing
61
- # is tagged with `:focus`, all examples get run. RSpec also provides
62
- # aliases for `it`, `describe`, and `context` that include `:focus`
63
- # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
64
- config.filter_run_when_matching :focus
65
-
66
- # Allows RSpec to persist some state between runs in order to support
67
- # the `--only-failures` and `--next-failure` CLI options. We recommend
68
- # you configure your source control system to ignore this file.
69
- config.example_status_persistence_file_path = "spec/examples.txt"
70
-
71
- # Limits the available syntax to the non-monkey patched syntax that is
72
- # recommended. For more details, see:
73
- # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
74
- # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
75
- # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
76
- config.disable_monkey_patching!
77
-
78
- # This setting enables warnings. It's recommended, but in some cases may
79
- # be too noisy due to issues in dependencies.
80
- config.warnings = true
81
-
82
- # Many RSpec users commonly either run the entire suite or an individual
83
- # file, and it's useful to allow more verbose output when running an
84
- # individual spec file.
85
- if config.files_to_run.one?
86
- # Use the documentation formatter for detailed output,
87
- # unless a formatter has already been configured
88
- # (e.g. via a command-line flag).
89
- config.default_formatter = 'doc'
90
- end
91
-
92
- # Print the 10 slowest examples and example groups at the
93
- # end of the spec run, to help surface which specs are running
94
- # particularly slow.
95
- config.profile_examples = 10
96
-
97
- # Run specs in random order to surface order dependencies. If you find an
98
- # order dependency and want to debug it, you can fix the order by providing
99
- # the seed, which is printed after each run.
100
- # --seed 1234
101
- config.order = :random
102
-
103
- # Seed global randomization in this process using the `--seed` CLI option.
104
- # Setting this allows you to use `--seed` to deterministically reproduce
105
- # test failures related to randomization by passing the same `--seed` value
106
- # as the one that triggered the failure.
107
- Kernel.srand config.seed
108
- =end
109
- end