sugarcube 1.1.0 → 1.3.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.
@@ -1,16 +1,18 @@
1
1
  module SugarCube
2
2
  module DateParser
3
+ module_function
4
+
3
5
  # Parse a date string: E.g.:
4
6
  #
5
7
  # SugarCube::DateParser.parse_date "There is a date in here tomorrow at 9:00 AM"
6
8
  #
7
9
  # => 2013-02-20 09:00:00 -0800
8
- def self.parse_date(date_string)
10
+ def parse_date(date_string)
9
11
  result = sugarcube_detect(date_string).first
10
12
  if result
11
13
  return result.date
12
14
  else
13
- return sugarcube_iso8601(date_string)
15
+ return iso8601(date_string)
14
16
  end
15
17
  end
16
18
 
@@ -20,7 +22,7 @@ module SugarCube
20
22
  #
21
23
  # Caveat: This is implemented per Apple documentation. I've never really
22
24
  # seen it work.
23
- def self.parse_time_zone(date_string)
25
+ def parse_time_zone(date_string)
24
26
  result = sugarcube_detect(date_string).first
25
27
  result && result.timeZone
26
28
  end
@@ -32,23 +34,17 @@ module SugarCube
32
34
  # => 21600.0
33
35
  #
34
36
  # Divide by 3600.0 to get number of hours duration.
35
- def self.parse_duration(date_string)
37
+ def parse_duration(date_string)
36
38
  result = sugarcube_detect(date_string).first
37
39
  result && result.send(:duration)
38
40
  end
39
41
 
40
42
  # Parse a date into a raw match array for further processing
41
- def self.match(date_string)
43
+ def match(date_string)
42
44
  sugarcube_detect(date_string)
43
45
  end
44
46
 
45
- private
46
- def self.sugarcube_detect(date_string)
47
- @@sugarcube_detector ||= NSDataDetector.dataDetectorWithTypes(NSTextCheckingTypeDate, error:Pointer.new(:object))
48
- return @@sugarcube_detector.matchesInString(date_string, options:0, range:NSMakeRange(0, date_string.length))
49
- end
50
-
51
- def self.sugarcube_iso8601(date_string)
47
+ def iso8601(date_string)
52
48
  @@sugarcube_iso_detectors ||= [
53
49
  "yyyy-MM-dd'T'HH:mm:ss",
54
50
  "yyyy-MM-dd'T'HH:mm:ssZ",
@@ -63,6 +59,12 @@ module SugarCube
63
59
  return @@sugarcube_iso_detectors.inject(nil) { |date, formatter| date || formatter.dateFromString(date_string) }
64
60
  end
65
61
 
62
+ def sugarcube_detect(date_string)
63
+ @@sugarcube_detector ||= NSDataDetector.dataDetectorWithTypes(NSTextCheckingTypeDate, error:Pointer.new(:object))
64
+ return @@sugarcube_detector.matchesInString(date_string, options:0, range:NSMakeRange(0, date_string.length))
65
+ end
66
+ private :sugarcube_detect
67
+
66
68
  end
67
69
  end
68
70
 
@@ -1,5 +1,10 @@
1
1
  class NSString
2
2
 
3
+ # checks ISO8601 formats *before* falling back on natural language detection
4
+ def nsdate
5
+ SugarCube::DateParser.iso8601(self) || SugarCube::DateParser.parse_date(self)
6
+ end
7
+
3
8
  def nstimezone
4
9
  case self
5
10
  when /([+-]?\d{4})/
@@ -1,7 +1,7 @@
1
- class Fixnum
1
+ class Numeric
2
2
 
3
- def nstimezone
4
- NSTimeZone.timeZoneForSecondsFromGMT(self)
3
+ def nsdate
4
+ NSDate.dateWithTimeIntervalSince1970(self)
5
5
  end
6
6
 
7
7
  def before(date)
@@ -21,3 +21,12 @@ class Fixnum
21
21
  end
22
22
 
23
23
  end
24
+
25
+
26
+ class Fixnum
27
+
28
+ def nstimezone
29
+ NSTimeZone.timeZoneForSecondsFromGMT(self)
30
+ end
31
+
32
+ end
@@ -4,6 +4,13 @@ class Numeric
4
4
  ##| MISC
5
5
  ##|
6
6
 
7
+ # Uses the screen scale to determine how many pixels (converts "pixels" to
8
+ # "points")
9
+ def pixels
10
+ self.to_f / UIScreen.mainScreen.scale
11
+ end
12
+ alias pixel pixels
13
+
7
14
  def percent
8
15
  self / 100.0
9
16
  end
@@ -5,7 +5,7 @@ class UILabel
5
5
  if text && text.length > 20
6
6
  text = text[0..20] + '...'
7
7
  end
8
- super options.merge(inner: 'text: ' + text.inspect)
8
+ super options.merge(inner: {text: text})
9
9
  end
10
10
 
11
11
  end
@@ -1,7 +1,6 @@
1
1
  class UIView
2
2
 
3
3
  def to_s(options={})
4
- options[:superview] = true if options[:superview].nil?
5
4
  if self.respond_to? :stylename and self.stylename
6
5
  suffix = ' stylename: ' + self.stylename.inspect
7
6
  else
@@ -20,7 +19,7 @@ class UIView
20
19
  "#{self.class.name}(##{self.object_id.to_s(16)}, #{SugarCube::Adjust::format_frame(self.frame)}" +
21
20
  (inner ? ', ' + inner : '') +
22
21
  ')' +
23
- (options[:superview] && self.superview ? ", child of #{self.superview.class.name}(##{self.superview.object_id.to_s(16)})" : '') +
22
+ (options.fetch(:superview, true) && self.superview ? ", child of #{self.superview.class.name}(##{self.superview.object_id.to_s(16)})" : '') +
24
23
  suffix
25
24
  end
26
25
 
@@ -10,12 +10,12 @@ class UIView
10
10
  def attr_updates(*attrs)
11
11
  attr_accessor(*attrs)
12
12
  attrs.each do |attr|
13
- define_method("#{attr}=") { |value|
13
+ define_method("#{attr}=") do |value|
14
14
  if instance_variable_get("@#{attr}") != value
15
15
  setNeedsDisplay
16
16
  end
17
17
  instance_variable_set("@#{attr}", value)
18
- }
18
+ end
19
19
  end
20
20
  end
21
21
 
@@ -80,7 +80,7 @@ class UIView
80
80
  if use_content_size
81
81
  UIGraphicsBeginImageContextWithOptions(contentSize, false, scale)
82
82
  context = UIGraphicsGetCurrentContext()
83
- subviews.each do |subview|
83
+ self.subviews.each do |subview|
84
84
  CGContextSaveGState(context)
85
85
  CGContextTranslateCTM(context, subview.frame.origin.x, subview.frame.origin.y)
86
86
  subview.layer.renderInContext(context)
@@ -99,12 +99,82 @@ class UIView
99
99
 
100
100
  # Returns the receiver's bounds in the coordinate system of `destination`
101
101
  def convert_bounds(destination)
102
- self.convertRect(self.bounds, toView:destination)
102
+ message = "The (ambiguously named) `convert_bounds` method has been deprecated, use `convert_frame_to` (or `convert_frame_from`)"
103
+ if defined?(SugarCube::Legacy)
104
+ SugarCube::Legacy.log(message)
105
+ else
106
+ NSLog(message)
107
+ end
108
+ return convert_frame_to(destination)
109
+ end
110
+
111
+ def convert_frame_to(destination)
112
+ return self.convertRect(CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), toView:destination)
113
+ end
114
+
115
+ def convert_frame_from(source)
116
+ return self.convertRect(CGRectMake(0, 0, source.frame.size.width, source.frame.size.height), fromView:source)
103
117
  end
104
118
 
105
119
  # Returns the receiver's bounds in the coordinate system of `destination`
106
120
  def convert_origin(destination)
107
- self.convertPoint([0, 0], toView:destination)
121
+ message = "The (ambiguously named) `convert_origin` method has been deprecated, use `convert_origin_to` (or `convert_origin_from`)"
122
+ if defined?(SugarCube::Legacy)
123
+ SugarCube::Legacy.log(message)
124
+ else
125
+ NSLog(message)
126
+ end
127
+ return self.convert_origin_to(destination)
128
+ end
129
+
130
+ def convert_origin_to(destination)
131
+ return self.convertPoint([0, 0], toView:destination)
132
+ end
133
+
134
+ def convert_origin_from(source)
135
+ return self.convertPoint([0, 0], fromView:source)
136
+ end
137
+
138
+ # Easily get and set a UIView's frame properties
139
+
140
+ def x
141
+ self.frame.origin.x
142
+ end
143
+
144
+ def setX(newX)
145
+ newFrame = self.frame
146
+ newFrame.origin.x = newX
147
+ self.frame = newFrame
148
+ end
149
+
150
+ def y
151
+ self.frame.origin.y
152
+ end
153
+
154
+ def setY(newY)
155
+ newFrame = self.frame
156
+ newFrame.origin.y = newY
157
+ self.frame = newFrame
158
+ end
159
+
160
+ def height
161
+ self.frame.size.height
162
+ end
163
+
164
+ def setHeight(newHeight)
165
+ newFrame = self.frame
166
+ newFrame.size.height = newHeight
167
+ self.frame = newFrame
168
+ end
169
+
170
+ def width
171
+ self.frame.size.width
172
+ end
173
+
174
+ def setWidth(newWidth)
175
+ newFrame = self.frame
176
+ newFrame.size.width = newWidth
177
+ self.frame = newFrame
108
178
  end
109
179
 
110
180
  end
@@ -1,3 +1,3 @@
1
1
  module SugarCube
2
- Version = '1.1.0'
2
+ Version = '1.3.0'
3
3
  end
@@ -99,6 +99,10 @@ describe 'NSAttributeString' do
99
99
  @subject.isEqualToAttributedString('test'.attrd.vertical_glyph_form(1)).should != true
100
100
  end
101
101
 
102
+ it 'should have `letterpress`' do
103
+ @subject.isEqualToAttributedString('test'.attrd.letterpress).should != true
104
+ end
105
+
102
106
  end
103
107
 
104
108
  end
@@ -31,21 +31,21 @@ describe 'NSString' do
31
31
  'little_square.png'.resource_exists?.should == true
32
32
  'foo'.resource_exists?.should == false
33
33
  end
34
-
34
+
35
35
  describe "exists?" do
36
-
36
+
37
37
  it "should not exists" do
38
38
  "abc".exists?.should == false
39
39
  end
40
-
40
+
41
41
  it "should not exists" do
42
42
  "abc".cache.exists?.should == false
43
43
  end
44
-
44
+
45
45
  it "should not exists" do
46
46
  "abc".resource.exists?.should == false
47
47
  end
48
-
48
+
49
49
  describe "in document" do
50
50
  before do
51
51
  "abc".writeToFile "abc".document, atomically:true
@@ -53,12 +53,12 @@ describe 'NSString' do
53
53
  after do
54
54
  NSFileManager.defaultManager.removeItemAtPath "abc".document, error:nil
55
55
  end
56
-
56
+
57
57
  it "should be exists" do
58
58
  "abc".exists?.should == true
59
59
  end
60
60
  end
61
-
61
+
62
62
  describe "in cache" do
63
63
  before do
64
64
  "abc".writeToFile "abc".cache, atomically:true
@@ -66,7 +66,7 @@ describe 'NSString' do
66
66
  after do
67
67
  NSFileManager.defaultManager.removeItemAtPath "abc".cache, error:nil
68
68
  end
69
-
69
+
70
70
  it "should be exists" do
71
71
  "abc".cache.exists?.should == true
72
72
  end
@@ -79,9 +79,9 @@ describe 'NSString' do
79
79
  end
80
80
 
81
81
  end
82
-
82
+
83
83
  describe "remove!" do
84
-
84
+
85
85
  describe "in document" do
86
86
  before do
87
87
  "abc".writeToFile "abc".document, atomically:true
@@ -89,13 +89,13 @@ describe 'NSString' do
89
89
  after do
90
90
  NSFileManager.defaultManager.removeItemAtPath "abc".document, error:nil
91
91
  end
92
-
92
+
93
93
  it "should remove" do
94
94
  "abc".remove!.should == nil
95
95
  "abc".exists?.should == false
96
96
  end
97
97
  end
98
-
98
+
99
99
  describe "in cache" do
100
100
  before do
101
101
  "abc".writeToFile "abc".cache, atomically:true
@@ -103,14 +103,14 @@ describe 'NSString' do
103
103
  after do
104
104
  NSFileManager.defaultManager.removeItemAtPath "abc".cache, error:nil
105
105
  end
106
-
106
+
107
107
  it "should remove" do
108
108
  path = "abc".cache
109
109
  path.remove!.should == nil
110
110
  path.exists?.should == false
111
111
  end
112
112
  end
113
-
113
+
114
114
  end
115
115
 
116
116
  describe 'resource()' do
@@ -153,7 +153,10 @@ describe 'NSString' do
153
153
  describe '"PkgInfo".resource_url' do
154
154
  before { @it = "PkgInfo".resource_url.absoluteString }
155
155
  it 'should start with "file://localhost/Users"' do
156
- @it.hasPrefix("file://localhost/Users").should == true
156
+ (
157
+ @it.hasPrefix("file://localhost/Users") ||
158
+ @it.hasPrefix("file:///Users")
159
+ ).should == true
157
160
  end
158
161
  it 'should end with "SugarCube_spec.app/PkgInfo"' do
159
162
  @it.hasSuffix("SugarCube_spec.app/PkgInfo").should == true
@@ -249,13 +249,13 @@ describe 'UIActionSheet' do
249
249
  proper_wait 0.6
250
250
  end
251
251
 
252
- it 'should call block with "cancel" when cancel button is pressed' do
252
+ it 'should call block with :cancel when cancel button is pressed' do
253
253
  @alert.cancelButtonIndex.should == 3
254
254
  @alert.dismissWithClickedButtonIndex(@alert.cancelButtonIndex, animated: false)
255
255
  @touched.should == :cancel
256
256
  end
257
257
 
258
- it 'should call block with "destructive" when destructive button is pressed' do
258
+ it 'should call block with :destructive when destructive button is pressed' do
259
259
  @alert.destructiveButtonIndex.should == 0
260
260
  @alert.dismissWithClickedButtonIndex(@alert.destructiveButtonIndex, animated: false)
261
261
  @touched.should == :destructive
@@ -276,4 +276,42 @@ describe 'UIActionSheet' do
276
276
 
277
277
  end
278
278
 
279
+ describe 'with success handler defined' do
280
+
281
+ before do
282
+ @touched = nil
283
+ @alert = UIActionSheet.alert('test',
284
+ buttons: ['cancel', 'destructive', 'test1', 'test2'],
285
+ success: ->(button, index){ @touched, @touched_index = button, index },
286
+ )
287
+ proper_wait 0.6
288
+ end
289
+
290
+ it 'should not call block when cancel button is pressed' do
291
+ @alert.cancelButtonIndex.should == 3
292
+ @alert.dismissWithClickedButtonIndex(@alert.cancelButtonIndex, animated: false)
293
+ @touched.should == nil
294
+ end
295
+
296
+ it 'should not call block when destructive button is pressed' do
297
+ @alert.destructiveButtonIndex.should == 0
298
+ @alert.dismissWithClickedButtonIndex(@alert.destructiveButtonIndex, animated: false)
299
+ @touched.should == nil
300
+ end
301
+
302
+ it 'should call block with "test1" when first button is pressed' do
303
+ @alert.firstOtherButtonIndex.should == 1
304
+ @alert.dismissWithClickedButtonIndex(@alert.firstOtherButtonIndex, animated: false)
305
+ @touched.should == 'test1'
306
+ @touched_index.should == @alert.firstOtherButtonIndex
307
+ end
308
+
309
+ it 'should call block with "test2" when second button is pressed' do
310
+ @alert.dismissWithClickedButtonIndex(@alert.firstOtherButtonIndex + 1, animated: false)
311
+ @touched.should == 'test2'
312
+ @touched_index.should == @alert.firstOtherButtonIndex + 1
313
+ end
314
+
315
+ end
316
+
279
317
  end
@@ -9,14 +9,14 @@ describe 'UIAlertView' do
9
9
 
10
10
  it 'should have :show option (show: true)' do
11
11
  alert = UIAlertView.alert('test', show: true)
12
- proper_wait 0.6
12
+ proper_wait 1
13
13
  alert.visible?.should == true
14
14
  alert.dismissWithClickedButtonIndex(alert.firstOtherButtonIndex, animated: false)
15
15
  end
16
16
 
17
17
  it 'should show by default' do
18
18
  alert = UIAlertView.alert('test')
19
- proper_wait 0.6
19
+ proper_wait 1
20
20
  alert.visible?.should == true
21
21
  alert.dismissWithClickedButtonIndex(alert.firstOtherButtonIndex, animated: false)
22
22
  end
@@ -144,6 +144,10 @@ describe 'UIAlertView' do
144
144
  )
145
145
  end
146
146
 
147
+ after do
148
+ @alert.dismissWithClickedButtonIndex(@alert.cancelButtonIndex, animated: false)
149
+ end
150
+
147
151
  it 'should work for :cancel' do
148
152
  proper_wait 0.6
149
153
  @alert.dismissWithClickedButtonIndex(@alert.cancelButtonIndex, animated: false)
@@ -167,13 +171,16 @@ describe 'UIAlertView' do
167
171
  end
168
172
 
169
173
  it 'should work with :secure_text_input' do
174
+ @called = false
170
175
  alert = UIAlertView.alert('test', buttons: ['cancel', 'ok'], style: :secure_text_input) { |button, text|
176
+ @called = true
171
177
  @text = text
172
178
  }
173
179
  proper_wait 0.6
174
180
  alert.textFieldAtIndex(0).text = 'test text'
175
- alert.dismissWithClickedButtonIndex(alert.cancelButtonIndex, animated: false)
181
+ alert.dismissWithClickedButtonIndex(alert.firstOtherButtonIndex, animated: false)
176
182
 
183
+ @called.should == true
177
184
  @text.should == 'test text'
178
185
  end
179
186