sugarcube 1.1.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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