ProMotion 2.0.1 → 2.1.0.beta1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 26a3f842a22164f1646fa4c70c06717331c37b37
4
- data.tar.gz: b71313bd4e58fd83a405e8741c264547b80e0f19
3
+ metadata.gz: 069e30500b3574a7ff83d4a179af392513ffac2b
4
+ data.tar.gz: e7a65eb50f555d29c2b406deaf3f4bb0c9e88aa1
5
5
  SHA512:
6
- metadata.gz: 309c74e1577110e7c0ab397fe120a367f77343b11f5cfb4813bd99e6f942f89d463eadc36fc143324c49b7fd428ba50191c896246a91dddb17f6d05048eac843
7
- data.tar.gz: c0dbd687ecb04bdea39a131e9b8313da6b12ca5b3a83fc7ab8a6ee915b4efc8ead92fb10247c16613907167f83c877c441078b2da22408003ef5f0212f91ce62
6
+ metadata.gz: 24902da29b4aef04a2620dd41a527052c39a3d9e5bcba5f556d3048cf83a7558b58c8b72ed28ae54f04c92dfb8b6bee847ce842b85c5f2ac6f574ddb70bb3dab
7
+ data.tar.gz: 007f7044aa819c3ce5e1a9b4e16048886984bc65aaf8d8fd16757a43a481ef52753919a9e6d9eaa62ef54cbb217ab73865ed71c601167de11a744d2a8ef20e7c
data/README.md CHANGED
@@ -1,4 +1,10 @@
1
- # ProMotion [![Gem Version](https://badge.fury.io/rb/ProMotion.png)](http://badge.fury.io/rb/ProMotion) [![Build Status](https://travis-ci.org/clearsightstudio/ProMotion.png)](https://travis-ci.org/clearsightstudio/ProMotion) [![Code Climate](https://codeclimate.com/github/clearsightstudio/ProMotion.png)](https://codeclimate.com/github/clearsightstudio/ProMotion) [![Dependency Status](https://gemnasium.com/clearsightstudio/ProMotion.png)](https://gemnasium.com/clearsightstudio/ProMotion)
1
+ # ProMotion
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/ProMotion.png)](http://badge.fury.io/rb/ProMotion)
4
+ [![Build Status](https://travis-ci.org/clearsightstudio/ProMotion.png)](https://travis-ci.org/clearsightstudio/ProMotion)
5
+ [![Code Climate](https://codeclimate.com/github/clearsightstudio/ProMotion.png)](https://codeclimate.com/github/clearsightstudio/ProMotion)
6
+ [![Dependency Status](https://gemnasium.com/clearsightstudio/ProMotion.png)](https://gemnasium.com/clearsightstudio/ProMotion)
7
+ [![omniref](https://www.omniref.com/ruby/gems/ProMotion.png)](https://www.omniref.com/ruby/gems/ProMotion)
2
8
 
3
9
  ## iPhone Apps, Ruby-style
4
10
 
data/lib/ProMotion.rb CHANGED
@@ -9,4 +9,24 @@ Motion::Project::App.setup do |app|
9
9
  Dir.glob(File.join(core_lib, '**/*.rb')).reverse.each do |file|
10
10
  app.files.insert(insert_point, file)
11
11
  end
12
+
13
+ # For compatibility with libraries that don't use detect_dependencies. :-(
14
+ app.files_dependencies({
15
+ "#{core_lib}/cocoatouch/table_view_cell.rb" => [ "#{core_lib}/table/cell/table_view_cell_module.rb" ],
16
+ "#{core_lib}/table/cell/table_view_cell_module.rb" => [ "#{core_lib}/styling/styling.rb" ],
17
+ "#{core_lib}/delegate/delegate.rb" => [ "#{core_lib}/delegate/delegate_parent.rb" ],
18
+ "#{core_lib}/delegate/delegate_parent.rb" => [ "#{core_lib}/delegate/delegate_module.rb" ],
19
+ "#{core_lib}/delegate/delegate_module.rb" => [ "#{core_lib}/tabs/tabs.rb", "#{core_lib}/ipad/split_screen.rb" ],
20
+ "#{core_lib}/screen/screen.rb" => [ "#{core_lib}/screen/screen_module.rb" ],
21
+ "#{core_lib}/screen/screen_module.rb" => [ "#{core_lib}/screen/screen_navigation.rb" ],
22
+ "#{core_lib}/table/data/table_data.rb" => [ "#{core_lib}/table/table.rb" ],
23
+ "#{core_lib}/table/table.rb" => [
24
+ "#{core_lib}/table/table_utils.rb",
25
+ "#{core_lib}/table/extensions/searchable.rb",
26
+ "#{core_lib}/table/extensions/refreshable.rb",
27
+ "#{core_lib}/table/extensions/indexable.rb",
28
+ "#{core_lib}/table/extensions/longpressable.rb"
29
+ ],
30
+ "#{core_lib}/web/web_screen.rb" => [ "#{core_lib}/web/web_screen_module.rb" ],
31
+ })
12
32
  end
@@ -2,10 +2,8 @@ module ProMotion
2
2
  class NavigationController < UINavigationController
3
3
 
4
4
  def popViewControllerAnimated(animated)
5
- if self.viewControllers[-2].respond_to? :on_back
6
- self.viewControllers[-2].send(:on_back)
7
- end
8
- super animated
5
+ super
6
+ self.viewControllers.last.send(:on_back) if self.viewControllers.last.respond_to?(:on_back)
9
7
  end
10
8
 
11
9
  def shouldAutorotate
@@ -19,12 +19,17 @@ module ProMotion
19
19
  error: [:error],
20
20
  warn: [:error, :warn],
21
21
  info: [:error, :warn, :info],
22
+ debug: [:error, :warn, :info, :debug],
22
23
  verbose: [:error, :warn, :info, :debug, :verbose],
23
- debug: [:error, :warn, :info, :debug, :verbose]
24
24
  }
25
25
 
26
26
  def level
27
- @level ||= :debug
27
+ @level ||= (RUBYMOTION_ENV == "release" ? :error : :debug)
28
+ end
29
+
30
+ def level=(new_level)
31
+ log('LOG LEVEL', 'Setting PM.logger to :verbose will make everything REALLY SLOW!', :purple) if new_level == :verbose
32
+ @level = new_level
28
33
  end
29
34
 
30
35
  def levels
@@ -33,9 +38,9 @@ module ProMotion
33
38
 
34
39
  # Usage: PM.logger.log("ERROR", "message here", :red)
35
40
  def log(label, message_text, color)
36
- return if defined?(RUBYMOTION_ENV) && RUBYMOTION_ENV == "test"
41
+ # return if defined?(RUBYMOTION_ENV) && RUBYMOTION_ENV == "test"
37
42
  color = COLORS[color] || COLORS[:default]
38
- puts color[0] + NAME + "[#{label}] #{message_text}" + color[1]
43
+ $stderr.puts color[0] + NAME + "[#{label}] #{message_text}" + color[1]
39
44
  nil
40
45
  end
41
46
 
@@ -50,6 +50,7 @@ module ProMotion
50
50
  nav
51
51
  end
52
52
  self.navigationController.toolbarHidden = !args[:toolbar] unless args[:toolbar].nil?
53
+ self.navigationController.setNavigationBarHidden(args[:hide_nav_bar], animated: false) unless args[:hide_nav_bar].nil?
53
54
  end
54
55
 
55
56
  private
@@ -11,9 +11,9 @@ module ProMotion
11
11
  def screen_init(args = {})
12
12
  check_ancestry
13
13
  resolve_title
14
- tab_bar_setup
15
- set_attributes self, args
14
+ apply_properties(args)
16
15
  add_nav_bar(args) if args[:nav_bar]
16
+ tab_bar_setup
17
17
  try :screen_setup
18
18
  try :on_init
19
19
  PM.logger.deprecated "In #{self.class.to_s}, #on_create has been deprecated and removed. Use #screen_init instead." if respond_to?(:on_create)
@@ -146,6 +146,11 @@ module ProMotion
146
146
 
147
147
  private
148
148
 
149
+ def apply_properties(args)
150
+ reserved_args = [ :nav_bar, :hide_nav_bar, :hide_tab_bar, :animated, :close_all, :in_tab, :in_detail, :in_master, :to_screen ]
151
+ set_attributes self, args.dup.delete_if { |k,v| reserved_args.include?(k) }
152
+ end
153
+
149
154
  def tab_bar_setup
150
155
  self.tab_bar_item = self.class.send(:get_tab_bar_item)
151
156
  self.refresh_tab_bar_item if self.tab_bar_item
@@ -18,9 +18,11 @@ module ProMotion
18
18
  element.send("#{k}=", v)
19
19
  elsif v.is_a?(Array) && element.respond_to?("#{k}") && element.method("#{k}").arity == v.length
20
20
  element.send("#{k}", *v)
21
- else
22
- # Doesn't respond. Check if snake case.
23
- set_attribute(element, camelize(k), v) if k.to_s.include?("_")
21
+ elsif k.to_s.include?("_") # Snake case?
22
+ set_attribute(element, camelize(k), v)
23
+ else # Warn
24
+ PM.logger.debug "set_attribute: #{element.inspect} does not respond to #{k}=."
25
+ PM.logger.log("BACKTRACE", caller(0).join("\n"), :default) if PM.logger.level == :verbose
24
26
  end
25
27
  element
26
28
  end
@@ -23,14 +23,15 @@ module ProMotion
23
23
 
24
24
  # TODO: Remove this in ProMotion 2.1. Just for migration purposes.
25
25
  def check_deprecated_styles
26
- whitelist = [ :title, :subtitle, :image, :remote_image, :accessory, :selection_style, :action, :long_press_action, :arguments, :cell_style, :cell_class, :cell_identifier, :editing_style, :search_text, :keep_selection, :height, :accessory_type, :style ]
26
+ whitelist = [ :title, :subtitle, :image, :remote_image, :accessory, :selection_style, :action, :long_press_action, :arguments, :cell_style, :cell_class, :cell_identifier, :editing_style, :search_text, :keep_selection, :height, :accessory_type, :style, :properties ]
27
27
  if (data_cell.keys - whitelist).length > 0
28
- PM.logger.deprecated("In #{self.table_screen.class.to_s}#table_data, you should set :#{(data_cell.keys - whitelist).join(", :")} in a `style:` hash. See TableScreen documentation.")
28
+ PM.logger.deprecated("In #{self.table_screen.class.to_s}#table_data, you should set :#{(data_cell.keys - whitelist).join(", :")} in a `properties:` hash. See TableScreen documentation.")
29
29
  end
30
30
  end
31
31
 
32
32
  def set_styles
33
- set_attributes self, data_cell[:style] if data_cell[:style]
33
+ data_cell[:properties] ||= data_cell[:style] || data_cell[:styles]
34
+ set_attributes self, data_cell[:properties] if data_cell[:properties]
34
35
  end
35
36
 
36
37
  def set_title
@@ -88,6 +89,7 @@ module ProMotion
88
89
  private
89
90
 
90
91
  def jm_image_cache?
92
+ return false if RUBYMOTION_ENV == 'test'
91
93
  return true if self.imageView.respond_to?("setImageWithURL:placeholder:")
92
94
  PM.logger.error "ProMotion Warning: to use remote_image with TableScreen you need to include the CocoaPod 'JMImageCache'."
93
95
  false
@@ -24,7 +24,7 @@ module ProMotion
24
24
 
25
25
  def cell(params={})
26
26
  params = index_path_to_section_index(params)
27
- table_section = self.section(params[:section])
27
+ table_section = params[:unfiltered] ? self.data[params[:section]] : self.section(params[:section])
28
28
  c = table_section[:cells].at(params[:index].to_i)
29
29
  set_data_cell_defaults c
30
30
  end
@@ -67,6 +67,7 @@ module ProMotion
67
67
  end
68
68
  data_cell[:cell_class] ||= PM::TableViewCell
69
69
  data_cell[:cell_identifier] ||= build_cell_identifier(data_cell)
70
+ data_cell[:properties] ||= data_cell[:style] || data_cell[:styles]
70
71
 
71
72
  data_cell[:accessory] = {
72
73
  view: data_cell[:accessory],
@@ -62,9 +62,17 @@ module ProMotion
62
62
  self.promotion_table_data.search_string
63
63
  end
64
64
 
65
- def update_table_view_data(data)
65
+ def update_table_view_data(data, args = {})
66
66
  self.promotion_table_data.data = data
67
- table_view.reloadData
67
+ if args[:index_paths]
68
+ args[:animation] ||= UITableViewRowAnimationNone
69
+
70
+ table_view.beginUpdates
71
+ table_view.reloadRowsAtIndexPaths(Array(args[:index_paths]), withRowAnimation: args[:animation])
72
+ table_view.endUpdates
73
+ else
74
+ table_view.reloadData
75
+ end
68
76
  @table_search_display_controller.searchResultsTableView.reloadData if searching?
69
77
  end
70
78
 
@@ -100,7 +108,7 @@ module ProMotion
100
108
  deletable_index_paths << index_path
101
109
  end
102
110
  end
103
- table_view.deleteRowsAtIndexPaths(deletable_index_paths, withRowAnimation:map_row_animation_symbol(animation)) if deletable_index_paths.length > 0
111
+ table_view.deleteRowsAtIndexPaths(deletable_index_paths, withRowAnimation: map_row_animation_symbol(animation)) if deletable_index_paths.length > 0
104
112
  end
105
113
 
106
114
  def table_view_cell(params={})
@@ -122,8 +130,11 @@ module ProMotion
122
130
  table_cell
123
131
  end
124
132
 
125
- def update_table_data
126
- self.update_table_view_data(self.table_data)
133
+ def update_table_data(args = {})
134
+ # Try and detect if the args param is a NSIndexPath or an array of them
135
+ args = { index_paths: args } if args.is_a?(NSIndexPath) || (args.is_a?(Array) && array_all_members_of?(args, NSIndexPath))
136
+
137
+ self.update_table_view_data(self.table_data, args)
127
138
  self.promotion_table_data.search(search_string) if searching?
128
139
  end
129
140
 
@@ -133,11 +144,11 @@ module ProMotion
133
144
  end
134
145
 
135
146
  # Number of cells
136
- def tableView(table_view, numberOfRowsInSection:section)
147
+ def tableView(table_view, numberOfRowsInSection: section)
137
148
  self.promotion_table_data.section_length(section)
138
149
  end
139
150
 
140
- def tableView(table_view, titleForHeaderInSection:section)
151
+ def tableView(table_view, titleForHeaderInSection: section)
141
152
  section = promotion_table_data.section(section)
142
153
  section && section[:title]
143
154
  end
@@ -149,29 +160,29 @@ module ProMotion
149
160
  nil
150
161
  end
151
162
 
152
- def tableView(table_view, cellForRowAtIndexPath:index_path)
163
+ def tableView(table_view, cellForRowAtIndexPath: index_path)
153
164
  table_view_cell(index_path: index_path)
154
165
  end
155
166
 
156
167
  def tableView(table_view, willDisplayCell: table_cell, forRowAtIndexPath: index_path)
157
168
  data_cell = self.promotion_table_data.cell(index_path: index_path)
158
- set_attributes table_cell, data_cell[:style] if data_cell[:style]
169
+ set_attributes table_cell, data_cell[:properties] if data_cell[:properties]
159
170
  table_cell.send(:will_display) if table_cell.respond_to?(:will_display)
160
171
  table_cell.send(:restyle!) if table_cell.respond_to?(:restyle!) # Teacup compatibility
161
172
  end
162
173
 
163
- def tableView(table_view, heightForRowAtIndexPath:index_path)
174
+ def tableView(table_view, heightForRowAtIndexPath: index_path)
164
175
  (self.promotion_table_data.cell(index_path: index_path)[:height] || table_view.rowHeight).to_f
165
176
  end
166
177
 
167
- def tableView(table_view, didSelectRowAtIndexPath:index_path)
178
+ def tableView(table_view, didSelectRowAtIndexPath: index_path)
168
179
  data_cell = self.promotion_table_data.cell(index_path: index_path)
169
180
  table_view.deselectRowAtIndexPath(index_path, animated: true) unless data_cell[:keep_selection] == true
170
181
  trigger_action(data_cell[:action], data_cell[:arguments], index_path) if data_cell[:action]
171
182
  end
172
183
 
173
184
  def tableView(table_view, editingStyleForRowAtIndexPath: index_path)
174
- data_cell = self.promotion_table_data.cell(index_path: index_path)
185
+ data_cell = self.promotion_table_data.cell(index_path: index_path, unfiltered: true)
175
186
  map_cell_editing_style(data_cell[:editing_style])
176
187
  end
177
188
 
@@ -181,18 +192,18 @@ module ProMotion
181
192
  end
182
193
  end
183
194
 
184
- def tableView(tableView, sectionForSectionIndexTitle:title, atIndex:index)
195
+ def tableView(tableView, sectionForSectionIndexTitle: title, atIndex: index)
185
196
  return index unless ["{search}", UITableViewIndexSearch].include?(self.table_data_index[0])
186
197
 
187
198
  if index == 0
188
- tableView.scrollRectToVisible(CGRectMake(0.0, 0.0, 1.0, 1.0), animated:false)
199
+ tableView.scrollRectToVisible(CGRectMake(0.0, 0.0, 1.0, 1.0), animated: false)
189
200
  NSNotFound
190
201
  else
191
202
  index - 1
192
203
  end
193
204
  end
194
205
 
195
- def deleteRowsAtIndexPaths(index_paths, withRowAnimation:animation)
206
+ def deleteRowsAtIndexPaths(index_paths, withRowAnimation: animation)
196
207
  PM.logger.warn "ProMotion expects you to use 'delete_cell(index_paths, animation)'' instead of 'deleteRowsAtIndexPaths(index_paths, withRowAnimation:animation)'."
197
208
  delete_row(index_paths, animation)
198
209
  end
@@ -2,12 +2,17 @@ module ProMotion
2
2
  module Table
3
3
  module Utils
4
4
  def index_path_to_section_index(params)
5
- if params[:index_path]
5
+ if params.is_a?(Hash) && params[:index_path]
6
6
  params[:section] = params[:index_path].section
7
7
  params[:index] = params[:index_path].row
8
8
  end
9
9
  params
10
10
  end
11
+
12
+ # Determines if all members of an array are a certain class
13
+ def array_all_members_of?(arr, klass)
14
+ arr.select{ |e| e.is_a?(klass) }.length == arr.length
15
+ end
11
16
  end
12
17
  end
13
18
  end
@@ -38,13 +38,13 @@ module ProMotion
38
38
  item_image = nil
39
39
  end
40
40
 
41
- item = UITabBarItem.alloc.initWithTitle(title, image:item_image, tag:tag)
41
+ item = UITabBarItem.alloc.initWithTitle(title, image: item_image, tag: tag)
42
42
 
43
43
  if item_selected || item_unselected
44
44
  item.setFinishedSelectedImage(item_selected, withFinishedUnselectedImage: item_unselected)
45
45
  end
46
46
 
47
- return item
47
+ item
48
48
  end
49
49
 
50
50
  def create_tab_bar_item(tab={})
@@ -55,17 +55,24 @@ module ProMotion
55
55
  tab[:item] ||= tab[:icon]
56
56
  end
57
57
 
58
- title = "Untitled"
59
- title = tab[:title] if tab[:title]
60
- tab[:tag] ||= @current_tag ||= 0
61
- @current_tag = tab[:tag] + 1
58
+ unless tab[:system_item] || tab[:item]
59
+ PM.logger.warn("You must provide either a `system_item:` or custom `item:` in `tab_bar_item`")
60
+ abort
61
+ end
62
+
63
+ title = tab[:title] || "Untitled"
62
64
 
63
- tab_bar_item = UITabBarItem.alloc.initWithTabBarSystemItem(map_tab_symbol(tab[:system_item]), tag: tab[:tag]) if tab[:system_item]
64
- tab_bar_item = create_tab_bar_item_custom(title, tab[:item], tab[:tag]) if tab[:item]
65
+ tab_bar_item = UITabBarItem.alloc.initWithTabBarSystemItem(map_tab_symbol(tab[:system_item]), tag: current_tag) if tab[:system_item]
66
+ tab_bar_item = create_tab_bar_item_custom(title, tab[:item], current_tag) if tab[:item]
65
67
 
66
68
  tab_bar_item.badgeValue = tab[:badge_number].to_s unless tab[:badge_number].nil? || tab[:badge_number] <= 0
67
69
 
68
- return tab_bar_item
70
+ tab_bar_item
71
+ end
72
+
73
+ def current_tag
74
+ return @prev_tag = 0 unless @prev_tag
75
+ @prev_tag += 1
69
76
  end
70
77
 
71
78
  def replace_current_item(tab_bar_controller, view_controller: vc)
@@ -96,6 +103,7 @@ module ProMotion
96
103
  def tab_bar_item(args={})
97
104
  @tab_bar_item = args
98
105
  end
106
+
99
107
  def get_tab_bar_item
100
108
  @tab_bar_item
101
109
  end
@@ -1,3 +1,3 @@
1
1
  module ProMotion
2
- VERSION = "2.0.1" unless defined?(ProMotion::VERSION)
2
+ VERSION = "2.1.0.beta1" unless defined?(ProMotion::VERSION)
3
3
  end
@@ -36,7 +36,9 @@ module ProMotion
36
36
 
37
37
  def set_initial_content
38
38
  return unless self.respond_to?(:content)
39
- content.is_a?(NSURL) ? open_url(content) : set_content(content)
39
+ current_content = content
40
+ return unless current_content
41
+ current_content.is_a?(NSURL) ? open_url(current_content) : set_content(current_content)
40
42
  end
41
43
 
42
44
  def set_content(content)
@@ -1,6 +1,8 @@
1
1
  describe "ProMotion::Screen functionality" do
2
2
  tests PM::Screen
3
3
 
4
+ before { UIView.setAnimationDuration 0.01 }
5
+
4
6
  # Override controller to properly instantiate
5
7
  def controller
6
8
  rotate_device to: :portrait, button: :bottom
@@ -69,23 +71,22 @@ describe "ProMotion::Screen functionality" do
69
71
  end
70
72
 
71
73
  it "should call the on_back method on the root controller when navigating back" do
72
- @nav_screen = NavigationScreen.new nav_bar: true
73
- @presented_screen = PresentScreen.new
74
- @nav_screen.open @presented_screen
75
- @presented_screen.close
76
- @nav_screen.on_back_fired.should == true
74
+ presented_screen = PresentScreen.new
75
+ @controller.open presented_screen, animated: false
76
+ @controller.navigationController.viewControllers.should == [ @controller, presented_screen ]
77
+ presented_screen.close animated: false
78
+ @controller.on_back_fired.should == true
77
79
  end
78
80
 
79
81
  it "should call the correct on_back method when nesting screens" do
80
- @base_screen = NavigationScreen.new nav_bar: true
81
- @child_screen = @base_screen.open NavigationScreen.new
82
- @grandchild_screen = @child_screen.open NavigationScreen.new
82
+ child_screen = @controller.open NavigationScreen.new, animated: false
83
+ grandchild_screen = child_screen.open NavigationScreen.new, animated: false
83
84
 
84
85
  # start closing
85
- @grandchild_screen.close
86
- @child_screen.on_back_fired.should == true
87
- @child_screen.close
88
- @base_screen.on_back_fired.should == true
86
+ grandchild_screen.close animated: false
87
+ child_screen.on_back_fired.should == true
88
+ child_screen.close animated: false
89
+ @controller.on_back_fired.should == true
89
90
  end
90
91
 
91
92
  it "should allow opening and closing a modal screen" do
@@ -10,6 +10,7 @@ describe "Split screen functionality" do
10
10
  end
11
11
 
12
12
  before do
13
+ UIView.setAnimationDuration 0.01
13
14
  rotate_device to: :landscape, button: :right
14
15
  end
15
16
 
@@ -15,9 +15,15 @@ describe "ProMotion::TableScreen functionality" do
15
15
  end
16
16
 
17
17
  def confirmation_class
18
- TestHelper.ios7 ? UITableViewCellDeleteConfirmationButton : UITableViewCellDeleteConfirmationControl
18
+ TestHelper.ios7 ? "UITableViewCellDeleteConfirmationButton" : "UITableViewCellDeleteConfirmationControl"
19
19
  end
20
20
 
21
+ def table_label_class
22
+ TestHelper.ios7 ? "UILabel" : "UITableViewLabel"
23
+ end
24
+
25
+ before { UIView.setAnimationDuration 0.01 }
26
+
21
27
  after { @table_screen = nil }
22
28
 
23
29
  it "should have a navigation bar" do
@@ -31,7 +37,7 @@ describe "ProMotion::TableScreen functionality" do
31
37
 
32
38
  it "should add a new table cell on tap" do
33
39
  tap("Add New Row")
34
- view("Dynamically Added").class.should == UILabel
40
+ view("Dynamically Added").class.to_s.should == table_label_class
35
41
  end
36
42
 
37
43
  it "should do nothing when no action specified" do
@@ -47,7 +53,7 @@ describe "ProMotion::TableScreen functionality" do
47
53
  it "should delete the specified row from the table view on tap" do
48
54
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 7
49
55
  tap("Delete the row below")
50
- wait 0.3 do
56
+ wait 0.11 do
51
57
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 6
52
58
  end
53
59
  end
@@ -55,7 +61,7 @@ describe "ProMotion::TableScreen functionality" do
55
61
  it "should delete the specified row from the table view on tap with an animation" do
56
62
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 7
57
63
  tap("Delete the row below with an animation")
58
- wait 0.3 do
64
+ wait 0.11 do
59
65
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 6
60
66
  end
61
67
  end
@@ -66,12 +72,12 @@ describe "ProMotion::TableScreen functionality" do
66
72
  table_screen.cell_was_deleted.should != true
67
73
  flick("Just another deletable blank row", :to => :left)
68
74
 
69
- wait 0.25 do
75
+ wait 0.11 do
70
76
  # Tap the delete button
71
77
  view('Just another deletable blank row').superview.superview.subviews.each do |subview|
72
- if subview.class == confirmation_class
78
+ if subview.class.to_s == confirmation_class
73
79
  tap subview
74
- wait 0.25 do
80
+ wait 0.11 do
75
81
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 6
76
82
  table_screen.cell_was_deleted.should == true
77
83
  end
@@ -85,12 +91,12 @@ describe "ProMotion::TableScreen functionality" do
85
91
  table_screen.cell_was_deleted.should != true
86
92
  flick("A non-deletable blank row", :to => :left)
87
93
 
88
- wait 0.25 do
94
+ wait 0.11 do
89
95
  # Tap the delete button
90
96
  view('A non-deletable blank row').superview.superview.subviews.each do |subview|
91
97
  if subview.class == confirmation_class
92
98
  tap subview
93
- wait 0.25 do
99
+ wait 0.11 do
94
100
  table_screen.tableView(table_screen.tableView, numberOfRowsInSection:0).should == 7
95
101
  table_screen.cell_was_deleted.should != false
96
102
  end
@@ -0,0 +1,52 @@
1
+ describe "ProMotion::TableScreen updating functionality" do
2
+ tests PM::UpdateTestTableScreen
3
+
4
+ before { UIView.setAnimationDuration 0.01 }
5
+
6
+ it 'should update a single row in the table view' do
7
+ table_screen = UpdateTestTableScreen.new
8
+ table_screen.make_more_cells
9
+ table_screen.update_table_data
10
+ table_screen.change_cells
11
+
12
+ table_screen.first_cell_title.should == "Cell 1"
13
+ table_screen.second_cell_title.should == "Cell 2"
14
+
15
+ table_screen.update_table_data(NSIndexPath.indexPathForRow(0, inSection:0))
16
+
17
+ table_screen.first_cell_title.should == "Cell A"
18
+ table_screen.second_cell_title.should == "Cell 2"
19
+ end
20
+
21
+ it 'should allow multiple formats of index paths to be passed' do
22
+ table_screen = UpdateTestTableScreen.new
23
+ table_screen.make_more_cells
24
+ table_screen.update_table_data
25
+ table_screen.change_cells
26
+
27
+ # Single NSIndexPath
28
+ Proc.new {
29
+ table_screen.update_table_data(NSIndexPath.indexPathForRow(0, inSection:0))
30
+ }.should.not.raise(StandardError)
31
+
32
+ # Array of NSIndexPaths
33
+ Proc.new {
34
+ table_screen.update_table_data([NSIndexPath.indexPathForRow(0, inSection:0), NSIndexPath.indexPathForRow(1, inSection:0)])
35
+ }.should.not.raise(StandardError)
36
+
37
+ # # Hash with single NSIndexPath
38
+ Proc.new {
39
+ table_screen.update_table_data({index_paths: NSIndexPath.indexPathForRow(0, inSection:0)})
40
+ }.should.not.raise(StandardError)
41
+
42
+ # Hash with array of NSIndexPaths
43
+ Proc.new {
44
+ table_screen.update_table_data({index_paths: [NSIndexPath.indexPathForRow(0, inSection:0), NSIndexPath.indexPathForRow(1, inSection:0)]})
45
+ }.should.not.raise(StandardError)
46
+
47
+ # Hash with NSIndexPath and row animation
48
+ Proc.new {
49
+ table_screen.update_table_data({index_paths: NSIndexPath.indexPathForRow(0, inSection:0), animation: UITableViewRowAnimationFade})
50
+ }.should.not.raise(StandardError)
51
+ end
52
+ end
@@ -1,7 +1,10 @@
1
1
  describe "ProMotion::TestWebScreen functionality" do
2
2
  extend WebStub::SpecHelpers
3
3
 
4
- before { disable_network_access! }
4
+ before do
5
+ disable_network_access!
6
+ UIView.setAnimationDuration 0.01
7
+ end
5
8
  after { enable_network_access! }
6
9
 
7
10
  def controller
@@ -1,6 +1,17 @@
1
1
  class TestHelper
2
+ def self.ios6
3
+ UIDevice.currentDevice.systemVersion.to_f >= 6.0 &&
4
+ UIDevice.currentDevice.systemVersion.to_f < 7.0
5
+ end
6
+
2
7
  def self.ios7
3
- UIDevice.currentDevice.systemVersion.to_f >= 7.0
8
+ UIDevice.currentDevice.systemVersion.to_f >= 7.0 &&
9
+ UIDevice.currentDevice.systemVersion.to_f < 8.0
10
+ end
11
+
12
+ def self.ios8
13
+ UIDevice.currentDevice.systemVersion.to_f >= 8.0 &&
14
+ UIDevice.currentDevice.systemVersion.to_f < 9.0
4
15
  end
5
16
  end
6
17
 
@@ -100,13 +100,13 @@ describe "screen helpers" do
100
100
 
101
101
  it "#push_view_controller should use the default navigation controller if not provided" do
102
102
  vcs = @screen.navigationController.viewControllers
103
- @screen.push_view_controller @second_vc
103
+ @screen.push_view_controller @second_vc, @screen.navigationController, false
104
104
  @screen.navigationController.viewControllers.count.should == vcs.count + 1
105
105
  end
106
106
 
107
107
  it "#push_view_controller should use a provided navigation controller" do
108
108
  second_nav_controller = UINavigationController.alloc.initWithRootViewController @screen
109
- @screen.push_view_controller @second_vc, second_nav_controller
109
+ @screen.push_view_controller @second_vc, second_nav_controller, false
110
110
  second_nav_controller.viewControllers.count.should == 2
111
111
  end
112
112
 
@@ -123,13 +123,14 @@ describe "screen helpers" do
123
123
  end
124
124
 
125
125
  it "should apply properties when opening a new screen" do
126
- new_screen = @screen.send(:set_up_screen_for_open, BasicScreen, { title: 'Some Title', modal: true, hide_tab_bar: true, nav_bar: true })
126
+ new_screen = @screen.send(:set_up_screen_for_open, BasicScreen, { title: 'Some Title', modal: true, hide_tab_bar: true, nav_bar: true, hide_nav_bar: true })
127
127
 
128
128
  new_screen.parent_screen.should == @screen
129
129
  new_screen.title.should == 'Some Title'
130
130
  new_screen.modal?.should == true
131
131
  new_screen.hidesBottomBarWhenPushed.should == true
132
132
  new_screen.nav_bar?.should == true
133
+ new_screen.navigationController.isNavigationBarHidden.should == true
133
134
  end
134
135
 
135
136
  it "should present the navigationController when showing a modal screen" do
@@ -199,7 +200,7 @@ describe "screen helpers" do
199
200
 
200
201
  it "should ignore its own navigation controller if current screen has a navigation controller" do
201
202
  basic = BasicScreen.new(nav_bar: true) # creates a dangling nav_bar that will be discarded.
202
- screen = @screen.open basic
203
+ screen = @screen.open basic, animated: false
203
204
  screen.should.be.kind_of BasicScreen
204
205
  basic.navigationController.should == @screen.navigationController
205
206
  end
@@ -301,13 +302,13 @@ describe "screen helpers" do
301
302
 
302
303
  it "#send_on_return should pass args to the first screen with :root" do
303
304
  first_screen = HomeScreen.new(nav_bar: true)
304
- second_screen = first_screen.open(BasicScreen)
305
- second_screen.open @screen
305
+ second_screen = first_screen.open(BasicScreen, animated: false)
306
+ second_screen.open @screen, animated: false
306
307
 
307
308
 
308
309
  second_screen.stub!(:on_return) { |args| should.flunk "shouldn't call on_return on second_screen!" }
309
310
  first_screen.mock!(:on_return) { |args| args[:key].should == :value }
310
- @screen.close({ key: :value, to_screen: :root })
311
+ @screen.close key: :value, to_screen: :root, animated: false
311
312
  end
312
313
  end
313
314
 
@@ -60,7 +60,7 @@ describe "screen properties" do
60
60
  # Issue https://github.com/clearsightstudio/ProMotion/issues/109
61
61
  it "#should_autorotate should fire when shouldAutorotate fires when in a navigation bar" do
62
62
  parent_screen = BasicScreen.new(nav_bar: true)
63
- parent_screen.open @screen
63
+ parent_screen.open @screen, animated: false
64
64
  @screen.mock!(:should_autorotate) { true.should == true }
65
65
  parent_screen.navigationController.shouldAutorotate
66
66
  end
@@ -31,14 +31,14 @@ describe "split screen `open` functionality" do
31
31
  end
32
32
 
33
33
  it "should open a new screen in the master view's navigation controller" do
34
- screen = @master_screen.open @detail_screen_2
34
+ screen = @master_screen.open @detail_screen_2, animated: false
35
35
  @split_screen.detail_screen.should == @detail_screen_1 # no change
36
36
  @master_screen.navigationController.topViewController.should == @detail_screen_2
37
37
  screen.should == @detail_screen_2
38
38
  end
39
39
 
40
40
  it "should open a new modal screen in the detail view" do
41
- screen = @detail_screen_1.open @detail_screen_2, modal: true
41
+ screen = @detail_screen_1.open @detail_screen_2, modal: true, animated: false
42
42
  @split_screen.detail_screen.should == @detail_screen_1
43
43
  @detail_screen_1.presentedViewController.should == (@detail_screen_2.navigationController || @detail_screen_2)
44
44
  screen.should == @detail_screen_2
@@ -47,7 +47,7 @@ describe "split screen `open` functionality" do
47
47
  it "should not interfere with normal non-split screen navigation" do
48
48
  home = HomeScreen.new(nav_bar: true)
49
49
  child = BasicScreen.new
50
- screen = home.open child, in_detail: true, in_master: true
50
+ screen = home.open child, in_detail: true, in_master: true, animated: false
51
51
  home.navigationController.topViewController.should == child
52
52
  screen.should == child
53
53
  end
@@ -23,6 +23,13 @@ describe "PM::Tabs" do
23
23
  tab_bar.viewControllers.length.should == 4
24
24
  end
25
25
 
26
+ it "should have correct tags on each tabBarItem" do
27
+ @screen1.tabBarItem.tag.should == 0
28
+ @screen2.tabBarItem.tag.should == 1
29
+ @screen3.tabBarItem.tag.should == 2
30
+ @screen4.tabBarItem.tag.should == 3
31
+ end
32
+
26
33
  it "should have the right screens in the right places" do
27
34
  tab_bar.viewControllers[0].should == @screen1.navigationController
28
35
  tab_bar.viewControllers[1].should == @screen2.navigationController
@@ -28,7 +28,7 @@ describe "tab bar functionality" do
28
28
  it "should have set the others to their respective titles" do
29
29
  @tab_bar.tabBar.items[1].title.should == "Basic"
30
30
  @tab_bar.tabBar.items[2].title.should == "Home"
31
- @tab_bar.tabBar.items[3].title.should == "TestTableScreen"
31
+ @tab_bar.tabBar.items[3].title.should == "Test tab title"
32
32
  end
33
33
 
34
34
  it "should allow changing the tab bar item with set_tab_bar_item" do
@@ -5,7 +5,8 @@ describe "PM::Table module" do
5
5
  end
6
6
 
7
7
  def custom_cell
8
- @image = UIImage.imageNamed("list")
8
+ @image ||= UIImage.imageNamed("list")
9
+ @pattern_image_color ||= UIColor.colorWithPatternImage(@image)
9
10
  cell_factory({
10
11
  title: "Crazy Full Featured Cell",
11
12
  subtitle: "This is way too huge..see note",
@@ -29,13 +30,29 @@ describe "PM::Table module" do
29
30
  size: 50,
30
31
  radius: 15
31
32
  },
32
- style: {
33
- masks_to_bounds: true,
34
- background_color: UIColor.colorWithPatternImage(@image)
33
+ properties: {
34
+ content_view: {
35
+ background_color: @pattern_image_color,
36
+ },
37
+ layer: {
38
+ masks_to_bounds: true,
39
+ },
35
40
  }
36
41
  })
37
42
  end
38
43
 
44
+ def default_cell_height
45
+ return UITableViewAutomaticDimension if TestHelper.ios8
46
+ return 44.0 if TestHelper.ios7
47
+ end
48
+
49
+ def default_header_height
50
+ # Thanks, Apple.
51
+ return -1.0 if TestHelper.ios8
52
+ return 23.0 if TestHelper.ios7
53
+ return 22.0 if TestHelper.ios6
54
+ end
55
+
39
56
  before do
40
57
  @subject = TestTableScreen.new
41
58
  @subject.mock! :table_data do
@@ -44,7 +61,7 @@ describe "PM::Table module" do
44
61
  },{
45
62
  title: "Table cell group 2", cells: [ cell_factory ]
46
63
  },{
47
- title: "Table cell group 3", cells: [ cell_factory(title: "3-1"), cell_factory({title: "3-2", style: { background_color: UIColor.blueColor } }) ]
64
+ title: "Table cell group 3", cells: [ cell_factory(title: "3-1"), cell_factory({title: "3-2", properties: { background_color: UIColor.blueColor } }) ]
48
65
  },{
49
66
  title: "Table cell group 4", cells: [ custom_cell, cell_factory(title: "4-2"), cell_factory(title: "4-3"), cell_factory(title: "4-4") ]
50
67
  },{
@@ -101,7 +118,7 @@ describe "PM::Table module" do
101
118
  end
102
119
 
103
120
  it "should return the table's cell height if none is given" do
104
- @subject.tableView(@subject.table_view, heightForRowAtIndexPath:@ip).should == 44.0 # Built-in default
121
+ @subject.tableView(@subject.table_view, heightForRowAtIndexPath:@ip).should == default_cell_height
105
122
  end
106
123
 
107
124
  it "should allow setting a custom cell height" do
@@ -140,11 +157,12 @@ describe "PM::Table module" do
140
157
 
141
158
  it "should set a custom cell background image" do
142
159
  @image.should.not.be.nil
143
- ip = NSIndexPath.indexPathForRow(0, inSection: 3) # Cell 2-1
160
+ ip = NSIndexPath.indexPathForRow(0, inSection: 3) # Cell 4-1
144
161
  cell = @subject.tableView(@subject.table_view, cellForRowAtIndexPath: ip)
145
162
  cell.should.be.kind_of(UITableViewCell)
146
- cell.backgroundColor.should.be.kind_of(UIColor)
147
- cell.backgroundColor.should == UIColor.colorWithPatternImage(@image)
163
+ cell.layer.masksToBounds.should == true
164
+ cell.contentView.backgroundColor.should.be.kind_of(UIColor)
165
+ cell.contentView.backgroundColor.should == @pattern_image_color
148
166
  end
149
167
 
150
168
  it "should set a custom cell background color" do
@@ -162,8 +180,7 @@ describe "PM::Table module" do
162
180
  end
163
181
 
164
182
  it "should use the default section height if none is specified" do
165
- header_height = (UIDevice.currentDevice.systemVersion.to_f >= 7.0) ? 23.0 : 22.0
166
- @subject.tableView(@subject.table_view, heightForHeaderInSection:4).should == header_height # Built-in default
183
+ @subject.tableView(@subject.table_view, heightForHeaderInSection:4).should == default_header_height
167
184
  end
168
185
 
169
186
  it "should use the set title_view_height if one is specified" do
@@ -112,20 +112,6 @@ describe "table screens" do
112
112
  end
113
113
 
114
114
  describe "test PM::TableScreen's updating functionality" do
115
- before do
116
- class UpdateTestTableScreen < PM::TableScreen
117
- def table_data; @table_data ||= []; end
118
- def on_load
119
- @table_data = [{cells: []}]
120
- update_table_data
121
- end
122
-
123
- def make_more_cells
124
- @table_data = [{cells: [{title: "Cell 1"},{title: "Cell 2"}]}]
125
- end
126
- end
127
- end
128
-
129
115
  it 'should update the table data when update_table_data is called' do
130
116
  @screen = UpdateTestTableScreen.new
131
117
  @screen.tableView(@screen.tableView, numberOfRowsInSection:0).should == 0
@@ -0,0 +1,34 @@
1
+ describe "PM::Table utils" do
2
+
3
+ before do
4
+ @subject = TestTableScreen.new
5
+ @subject.on_load
6
+ @subject.update_table_data
7
+ end
8
+
9
+ it "should convert an index path to a section index" do
10
+ index_path = NSIndexPath.indexPathForRow(12, inSection:2)
11
+ given = {index_path: index_path}
12
+ expected = {
13
+ index_path: index_path,
14
+ section: 2,
15
+ index: 12
16
+ }
17
+
18
+ @subject.index_path_to_section_index(given).should == expected
19
+ end
20
+
21
+ it "return the original param when converting an index path with incorrect values" do
22
+ @subject.index_path_to_section_index(17).should == 17
23
+ end
24
+
25
+ it "should properly determine if all members of an array are the same class" do
26
+ @subject.array_all_members_of?([1, 2, 3, 4], Fixnum).should == true
27
+ @subject.array_all_members_of?(["string", 'string2'], String).should == true
28
+ @subject.array_all_members_of?([:sym1, :sym2, :sym3], Symbol).should == true
29
+
30
+ @subject.array_all_members_of?([1, 2, 3, 4, 'String'], Fixnum).should == false
31
+ @subject.array_all_members_of?([4.4, 2], Fixnum).should == false
32
+ end
33
+
34
+ end
@@ -19,7 +19,7 @@ describe "PM::TableViewCellModule" do
19
19
  radius: 15
20
20
  },
21
21
  selection_style: :gray,
22
- style: {
22
+ properties: {
23
23
  layer: {
24
24
  masks_to_bounds: true
25
25
  },
@@ -48,7 +48,7 @@ describe "PM::TableViewCellModule" do
48
48
  {
49
49
  title: "",
50
50
  cells: [
51
- { title: "Test 1", style: { accessory_type: UITableViewCellStateShowingEditControlMask } },
51
+ { title: "Test 1", properties: { accessory_type: UITableViewCellStateShowingEditControlMask } },
52
52
  custom_cell,
53
53
  { title: "Test2", accessory: { view: button } },
54
54
  attributed_cell
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ProMotion
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamon Holmgren
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-09-04 00:00:00.000000000 Z
13
+ date: 2014-10-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: methadone
@@ -18,28 +18,28 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '1.4'
21
+ version: '1.7'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: '1.4'
28
+ version: '1.7'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: webstub
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
33
  - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: '1.0'
35
+ version: '1.1'
36
36
  type: :development
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: '1.0'
42
+ version: '1.1'
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: motion-stump
45
45
  requirement: !ruby/object:Gem::Requirement
@@ -134,6 +134,7 @@ files:
134
134
  - spec/functional/func_screen_spec.rb
135
135
  - spec/functional/func_split_screen_spec.rb
136
136
  - spec/functional/func_table_screen_spec.rb
137
+ - spec/functional/func_table_screen_updating_spec.rb
137
138
  - spec/functional/func_web_screen_spec.rb
138
139
  - spec/helpers/test_helper.rb
139
140
  - spec/unit/delegate_spec.rb
@@ -154,6 +155,7 @@ files:
154
155
  - spec/unit/tables/table_indexable_spec.rb
155
156
  - spec/unit/tables/table_module_spec.rb
156
157
  - spec/unit/tables/table_screen_spec.rb
158
+ - spec/unit/tables/table_utils_spec.rb
157
159
  - spec/unit/tables/table_view_cell_spec.rb
158
160
  - spec/unit/view_helper_spec.rb
159
161
  - spec/unit/view_title_screen.rb
@@ -173,12 +175,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
173
175
  version: '0'
174
176
  required_rubygems_version: !ruby/object:Gem::Requirement
175
177
  requirements:
176
- - - ">="
178
+ - - ">"
177
179
  - !ruby/object:Gem::Version
178
- version: '0'
180
+ version: 1.3.1
179
181
  requirements: []
180
182
  rubyforge_project:
181
- rubygems_version: 2.2.2
183
+ rubygems_version: 2.4.2
182
184
  signing_key:
183
185
  specification_version: 4
184
186
  summary: ProMotion is a fast way to get started building RubyMotion apps. Instead
@@ -190,6 +192,7 @@ test_files:
190
192
  - spec/functional/func_screen_spec.rb
191
193
  - spec/functional/func_split_screen_spec.rb
192
194
  - spec/functional/func_table_screen_spec.rb
195
+ - spec/functional/func_table_screen_updating_spec.rb
193
196
  - spec/functional/func_web_screen_spec.rb
194
197
  - spec/helpers/test_helper.rb
195
198
  - spec/unit/delegate_spec.rb
@@ -210,8 +213,8 @@ test_files:
210
213
  - spec/unit/tables/table_indexable_spec.rb
211
214
  - spec/unit/tables/table_module_spec.rb
212
215
  - spec/unit/tables/table_screen_spec.rb
216
+ - spec/unit/tables/table_utils_spec.rb
213
217
  - spec/unit/tables/table_view_cell_spec.rb
214
218
  - spec/unit/view_helper_spec.rb
215
219
  - spec/unit/view_title_screen.rb
216
220
  - spec/unit/web_spec.rb
217
- has_rdoc: