accessibility_core 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,21 @@
1
+ # 0.3.2 - Adjustments for AXElements
2
+
3
+ * Fix `Element#children` raising when AXAPI returns failure error code
4
+ * Conditionally defined `CGPoint`/`CGSize`/`CGRect` on MRI
5
+ * Tweak various bits of documentation related to Cocoa mappings
6
+ * Calculate `NSString` length properly when wrapping in the C extension
7
+ * Add a 10% drop-in replacement for `NSBundle` for AXElements
8
+ * Add `wrap_dictionary` to wrap `NSDictionary` objects
9
+ * Force `CGPoint`/`CGSize` attrs to be `Float` type at initialize time
10
+ * Add `Object#to_ruby` and `Array#to_ruby` when running on MRI
11
+
12
+
1
13
  # 0.3.1 - Fix it up
2
14
 
3
15
  * Fix C extensions being installed to the wrong location
4
16
  * Fix Accessibility module not always being defined at the appropriate time
5
17
 
18
+
6
19
  # 0.3.0 - Merge accessibility\_bridge
7
20
 
8
21
  * Merge in `accessibility_bridge` v0.2.0
@@ -20,17 +20,6 @@ runtimes.
20
20
  window.set 'AXPosition', CGPoint.new(100, 100)
21
21
 
22
22
 
23
- ## Note
24
-
25
- At this point, `rake-compiler` does not run on MacRuby
26
- 'out-of-the-box'. Actually, it does, but it declares a dependency on
27
- rake which causes rake to be installed from rubygems. Rake from
28
- rubygems does not work with MacRuby. So you need to either fix the
29
- probem with MacRuby or just hack the `rake-compiler.gemspec` file
30
- after you install `rake-compiler` so it does not think it depends on
31
- rake anymore.
32
-
33
-
34
23
  ## TODO
35
24
 
36
25
  * bridging for `NSAttributedString`
data/Rakefile CHANGED
@@ -23,7 +23,7 @@ end
23
23
 
24
24
  desc 'Startup an IRb console with everything loaded'
25
25
  task :console_complete => :compile do
26
- sh 'irb -Ilib -raccessibility/core -raccessibility/bridge -raccessibility/extras -raccessibility/highlighter'
26
+ sh 'irb -Ilib -raccessibility/bridge -raccessibility/core -raccessibility/extras -raccessibility/highlighter'
27
27
  end
28
28
 
29
29
  # Gem stuff
@@ -62,6 +62,7 @@ wrap_unknown(CFTypeRef obj)
62
62
  CFTypeRef
63
63
  unwrap_unknown(VALUE obj)
64
64
  {
65
+ // TODO: rb_check_convert_type instead?
65
66
  obj = rb_funcall(obj, sel_to_s, 0);
66
67
  rb_raise(
67
68
  rb_eRuntimeError,
@@ -235,11 +236,7 @@ unwrap_value(VALUE value)
235
236
  VALUE wrap_array_values(CFArrayRef array) { WRAP_ARRAY(wrap_value) }
236
237
 
237
238
 
238
- VALUE
239
- wrap_ref(AXUIElementRef ref)
240
- {
241
- return Data_Wrap_Struct(rb_cElement, NULL, cf_finalizer, (void*)ref);
242
- }
239
+ VALUE wrap_ref(AXUIElementRef obj) { WRAP_OBJC(rb_cElement, cf_finalizer); }
243
240
 
244
241
  AXUIElementRef
245
242
  unwrap_ref(VALUE obj)
@@ -287,7 +284,7 @@ wrap_nsstring(NSString* string)
287
284
  {
288
285
  return rb_enc_str_new(
289
286
  [string UTF8String],
290
- [string length],
287
+ [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding],
291
288
  rb_utf8_encoding()
292
289
  );
293
290
  }
@@ -418,6 +415,7 @@ wrap_nsurl(NSURL* url)
418
415
  CFURLRef
419
416
  unwrap_url(VALUE url)
420
417
  {
418
+ // TODO: should also force encoding to UTF-8 first?
421
419
  url = rb_funcall(url, sel_to_s, 0);
422
420
  CFStringRef string = CFStringCreateWithCString(
423
421
  NULL,
@@ -429,8 +427,15 @@ unwrap_url(VALUE url)
429
427
  return url_ref;
430
428
  }
431
429
 
430
+ NSURL*
431
+ unwrap_nsurl(VALUE url)
432
+ {
433
+ return (NSURL*)unwrap_url(url);
434
+ }
435
+
432
436
  VALUE wrap_array_urls(CFArrayRef array) { WRAP_ARRAY(wrap_url) }
433
437
 
438
+
434
439
  VALUE
435
440
  wrap_date(CFDateRef date)
436
441
  {
@@ -485,19 +490,35 @@ wrap_array(CFArrayRef array)
485
490
  else return wrap_unknown(obj);
486
491
  }
487
492
 
493
+
494
+ VALUE
495
+ wrap_dictionary(NSDictionary* dict)
496
+ {
497
+ __block VALUE hash = rb_hash_new();
498
+
499
+ [dict enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL* stop) {
500
+ rb_hash_aset(hash, to_ruby(key), to_ruby(obj));
501
+ }];
502
+
503
+ return hash;
504
+ }
505
+
506
+
507
+
488
508
  VALUE
489
509
  to_ruby(CFTypeRef obj)
490
510
  {
491
511
  CFTypeID di = CFGetTypeID(obj);
492
- if (di == CFArrayGetTypeID()) return wrap_array(obj);
493
- else if (di == AXUIElementGetTypeID()) return wrap_ref(obj);
494
- else if (di == AXValueGetTypeID()) return wrap_value(obj);
495
- else if (di == CFStringGetTypeID()) return wrap_string(obj);
496
- else if (di == CFNumberGetTypeID()) return wrap_number(obj);
497
- else if (di == CFBooleanGetTypeID()) return wrap_boolean(obj);
498
- else if (di == CFURLGetTypeID()) return wrap_url(obj);
499
- else if (di == CFDateGetTypeID()) return wrap_date(obj);
500
- else return wrap_unknown(obj);
512
+ if (di == CFArrayGetTypeID()) return wrap_array(obj);
513
+ else if (di == AXUIElementGetTypeID()) return wrap_ref(obj);
514
+ else if (di == AXValueGetTypeID()) return wrap_value(obj);
515
+ else if (di == CFStringGetTypeID()) return wrap_string(obj);
516
+ else if (di == CFNumberGetTypeID()) return wrap_number(obj);
517
+ else if (di == CFBooleanGetTypeID()) return wrap_boolean(obj);
518
+ else if (di == CFURLGetTypeID()) return wrap_url(obj);
519
+ else if (di == CFDateGetTypeID()) return wrap_date(obj);
520
+ else if (di == CFDictionaryGetTypeID()) return wrap_dictionary(obj);
521
+ else return wrap_unknown(obj);
501
522
  }
502
523
 
503
524
  CFTypeRef
@@ -33,6 +33,16 @@ extern ID sel_to_s;
33
33
  extern ID sel_parse;
34
34
 
35
35
 
36
+ #define WRAP_OBJC(klass, finalizer) do { \
37
+ return Data_Wrap_Struct(klass, NULL, finalizer, (void*)obj); \
38
+ } while (false);
39
+
40
+ #define UNWRAP_OBJC(klass) do { \
41
+ klass* unwrapped; \
42
+ Data_Get_Struct(obj, klass, unwrapped); \
43
+ return unwrapped; \
44
+ } while (false);
45
+
36
46
  #define WRAP_ARRAY(wrapper) do { \
37
47
  CFIndex length = CFArrayGetCount(array); \
38
48
  VALUE ary = rb_ary_new2(length); \
@@ -107,6 +117,7 @@ CFNumberRef unwrap_number(VALUE number);
107
117
  VALUE wrap_url(CFURLRef url);
108
118
  VALUE wrap_nsurl(NSURL* url);
109
119
  CFURLRef unwrap_url(VALUE url);
120
+ NSURL* unwrap_nsurl(VALUE url);
110
121
  VALUE wrap_array_urls(CFArrayRef array);
111
122
 
112
123
  VALUE wrap_date(CFDateRef date);
@@ -122,6 +133,8 @@ CFBooleanRef unwrap_boolean(VALUE bool_val);
122
133
  // which is usually the case coming from the CF world
123
134
  VALUE wrap_array(CFArrayRef array);
124
135
 
136
+ VALUE wrap_dictionary(NSDictionary* dict);
137
+
125
138
  VALUE to_ruby(CFTypeRef obj);
126
139
  CFTypeRef to_ax(VALUE obj);
127
140
 
@@ -1,11 +1,10 @@
1
1
  #include "ruby.h"
2
-
3
- #ifdef NOT_MACRUBY /* This entire extension is pointless when running on MacRuby */
4
-
5
- #import <Cocoa/Cocoa.h>
6
2
  #include "../bridge/bridge.h"
3
+ #import <Cocoa/Cocoa.h>
7
4
 
8
5
 
6
+ #ifdef NOT_MACRUBY /* This entire extension is pointless when running on MacRuby */
7
+
9
8
  static ID ivar_attrs;
10
9
  static ID ivar_param_attrs;
11
10
  static ID ivar_actions;
@@ -345,6 +344,7 @@ rb_acore_children(VALUE self)
345
344
  {
346
345
  case kAXErrorSuccess:
347
346
  return wrap_array_refs(value);
347
+ case kAXErrorFailure:
348
348
  case kAXErrorNoValue:
349
349
  case kAXErrorInvalidUIElement:
350
350
  return rb_ary_new();
@@ -636,6 +636,7 @@ Init_core()
636
636
  Init_bridge();
637
637
 
638
638
  #ifdef NOT_MACRUBY
639
+
639
640
  if (!AXAPIEnabled())
640
641
  rb_raise(
641
642
  rb_eRuntimeError,
@@ -24,5 +24,5 @@ create_makefile 'accessibility/core/core'
24
24
  # modify the bugger so we can depend on bridge.h properly
25
25
  makefile = File.read 'Makefile'
26
26
  makefile.gsub! '$(DLLIB): $(OBJS) Makefile', '$(DLLIB): $(OBJS) Makefile ../bridge/bridge.o'
27
- makefile.gsub! '$(Q) $(LDSHARED) -o $@', '$(Q) $(LDSHARED) -o $@ ../bridge/bridge.o'
27
+ makefile.gsub! '$(LDSHARED) -o $@', ' $(LDSHARED) -o $@ ../bridge/bridge.o'
28
28
  File.open('Makefile', 'w') { |f| f.write makefile }
@@ -24,5 +24,5 @@ create_makefile 'accessibility/extras/extras'
24
24
  # modify the bugger so we can depend on bridge.h properly
25
25
  makefile = File.read 'Makefile'
26
26
  makefile.gsub! '$(DLLIB): $(OBJS) Makefile', '$(DLLIB): $(OBJS) Makefile ../bridge/bridge.o'
27
- makefile.gsub! '$(Q) $(LDSHARED) -o $@', '$(Q) $(LDSHARED) -o $@ ../bridge/bridge.o'
27
+ makefile.gsub! '$(LDSHARED) -o $@', ' $(LDSHARED) -o $@ ../bridge/bridge.o'
28
28
  File.open('Makefile', 'w') { |f| f.write makefile }
@@ -29,6 +29,7 @@ static VALUE rb_cRunningApp;
29
29
  static VALUE rb_cWorkspace;
30
30
  static VALUE rb_cProcInfo;
31
31
  static VALUE rb_cHost;
32
+ static VALUE rb_cBundle;
32
33
 
33
34
  static VALUE key_opts;
34
35
  //static VALUE key_event_params;
@@ -403,22 +404,50 @@ rb_host_localized_name(VALUE self)
403
404
  }
404
405
 
405
406
 
407
+ VALUE wrap_bundle(NSBundle* obj) { WRAP_OBJC(rb_cBundle, objc_finalizer); }
408
+ NSBundle* unwrap_bundle(VALUE obj) { UNWRAP_OBJC(NSBundle); }
409
+
410
+ static
406
411
  VALUE
407
- wrap_screen(NSScreen* screen)
412
+ rb_bundle_with_url(VALUE self, VALUE url)
408
413
  {
409
- return Data_Wrap_Struct(rb_cScreen, NULL, NULL, (void*)screen);
414
+ NSURL* nsurl = unwrap_nsurl(url);
415
+ NSBundle* bundle = [NSBundle bundleWithURL:nsurl];
416
+ VALUE rb_bundle = Qnil;
417
+
418
+ if (bundle)
419
+ rb_bundle = wrap_bundle(bundle);
420
+
421
+ return rb_bundle;
410
422
  }
411
423
 
412
- VALUE wrap_array_screens(CFArrayRef array) { WRAP_ARRAY(wrap_screen); }
424
+ static
425
+ VALUE
426
+ rb_bundle_info_dict(VALUE self)
427
+ {
428
+ NSDictionary* dict = [unwrap_bundle(self) infoDictionary];
429
+ VALUE hash = Qnil;
430
+ if (dict)
431
+ hash = wrap_dictionary(dict);
432
+ return hash;
433
+ }
413
434
 
414
- NSScreen*
415
- unwrap_screen(VALUE screen)
435
+ static
436
+ VALUE
437
+ rb_bundle_object_for_info_dict_key(VALUE self, VALUE key)
416
438
  {
417
- NSScreen* ns_screen;
418
- Data_Get_Struct(screen, NSScreen, ns_screen);
419
- return ns_screen;
439
+ NSString* nskey = unwrap_nsstring(key);
440
+ id obj = [unwrap_bundle(self) objectForInfoDictionaryKey:nskey];
441
+ if (obj)
442
+ return to_ruby(obj);
443
+ return Qnil;
420
444
  }
421
445
 
446
+
447
+ VALUE wrap_screen(NSScreen* obj) { WRAP_OBJC(rb_cScreen, NULL); }
448
+ VALUE wrap_array_screens(CFArrayRef array) { WRAP_ARRAY(wrap_screen); }
449
+ NSScreen* unwrap_screen(VALUE obj) { UNWRAP_OBJC(NSScreen); }
450
+
422
451
  static
423
452
  VALUE
424
453
  rb_screen_main(VALUE self)
@@ -793,6 +822,21 @@ Init_extras()
793
822
  rb_define_singleton_method(rb_cHost, "names", rb_host_names, 0);
794
823
  rb_define_singleton_method(rb_cHost, "addresses", rb_host_addresses, 0);
795
824
  rb_define_singleton_method(rb_cHost, "localizedName", rb_host_localized_name, 0);
825
+
826
+
827
+ /*
828
+ * Document-class: NSBundle
829
+ *
830
+ * A tiny subset of Cocoa's `NSBundle` class. Methods that might be
831
+ * useful to have have been bridged.
832
+ *
833
+ * See [Apple's Developer Reference](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSBundle_Class/Reference/Reference.html)
834
+ * for documentation on the methods available in this class.
835
+ */
836
+ rb_cBundle = rb_define_class("NSBundle", rb_cObject);
837
+ rb_define_singleton_method(rb_cBundle, "bundleWithURL", rb_bundle_with_url, 1);
838
+ rb_define_method(rb_cBundle, "infoDictionary", rb_bundle_info_dict, 0);
839
+ rb_define_method(rb_cBundle, "objectForInfoDictionaryKey", rb_bundle_object_for_info_dict_key, 1);
796
840
  #endif
797
841
 
798
842
 
@@ -25,5 +25,5 @@ create_makefile 'accessibility/highlighter/highlighter'
25
25
  # modify the bugger so we can depend on bridge.h properly
26
26
  makefile = File.read 'Makefile'
27
27
  makefile.gsub! '$(DLLIB): $(OBJS) Makefile', '$(DLLIB): $(OBJS) Makefile ../bridge/bridge.o ../extras/extras.o'
28
- makefile.gsub! '$(Q) $(LDSHARED) -o $@', '$(Q) $(LDSHARED) -o $@ ../bridge/bridge.o ../extras/extras.o'
28
+ makefile.gsub! '$(LDSHARED) -o $@', '$(LDSHARED) -o $@ ../bridge/bridge.o ../extras/extras.o'
29
29
  File.open('Makefile', 'w') { |f| f.write makefile }
@@ -43,6 +43,10 @@ class NSObject
43
43
 
44
44
  ##
45
45
  # Return a usable object from an AXAPI pointer
46
+ #
47
+ # Given an arbitrary return value from an AXAPI function
48
+ # this method is called to delegate the work of actually
49
+ # wrapping the returned value in the correct way.
46
50
  def to_ruby
47
51
  self
48
52
  end
@@ -1,12 +1,12 @@
1
1
  ##
2
2
  # A structure that contains a point in a two-dimensional coordinate system
3
- CGPoint = Struct.new(:x, :y)
3
+ CGPoint = Struct.new(:x, :y) unless defined? CGPoint
4
4
  class CGPoint
5
5
 
6
6
  # @param x [Number]
7
7
  # @param y [Number]
8
8
  def initialize x = 0.0, y = 0.0
9
- super
9
+ super x.to_f, y.to_f
10
10
  end
11
11
 
12
12
  # @!attribute [rw] x
@@ -32,13 +32,13 @@ end
32
32
 
33
33
  ##
34
34
  # A structure that contains the size of a rectangle in a 2D co-ordinate system
35
- CGSize = Struct.new(:width, :height)
35
+ CGSize = Struct.new(:width, :height) unless defined? CGSize
36
36
  class CGSize
37
37
 
38
38
  # @param width [Number]
39
39
  # @param height [Number]
40
40
  def initialize width = 0.0, height = 0.0
41
- super
41
+ super width.to_f, height.to_f
42
42
  end
43
43
 
44
44
  # @!attribute [rw] width
@@ -64,7 +64,7 @@ end
64
64
 
65
65
  ##
66
66
  # Complete definition of a rectangle in a 2D coordinate system
67
- CGRect = Struct.new(:origin, :size)
67
+ CGRect = Struct.new(:origin, :size) unless defined? CGRect
68
68
  class CGRect
69
69
 
70
70
  # @param origin [CGPoint,#to_point]
@@ -120,5 +120,22 @@ class String
120
120
  end
121
121
  end
122
122
 
123
+ ##
124
+ # `accessibility-core` extensions to the `Object` class
125
+ class Object
126
+ # (see NSObject#to_ruby)
127
+ def to_ruby
128
+ self
129
+ end
130
+ end
131
+
132
+ ##
133
+ # `accessibility-core` extensions to the `Array` class
134
+ class Array
135
+ # (see NSArray#to_ruby)
136
+ def to_ruby
137
+ map do |obj| obj.to_ruby end
138
+ end
139
+ end
123
140
 
124
141
  require 'accessibility/bridge/common'
@@ -6,6 +6,6 @@ module Accessibility
6
6
  # Namespace for `accessibility_core` specific classes
7
7
  module Core
8
8
  # return [String]
9
- VERSION = '0.3.1'
9
+ VERSION = '0.3.2'
10
10
  end
11
11
  end
@@ -0,0 +1,100 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ def assert_error args, should_raise: klass, with_fragments: msgs
4
+ e = assert_raises(klass) { (@derp || app).handle_error *args }
5
+ assert_match /test_core.rb:272/, e.backtrace.first unless RUNNING_COMPILED
6
+ msgs.each { |msg| assert_match msg, e.message }
7
+ end
8
+
9
+ def test_handle_errors
10
+ app_inspect = Regexp.new(Regexp.escape(app.inspect))
11
+
12
+ assert_error [KAXErrorFailure],
13
+ should_raise: RuntimeError,
14
+ with_fragments: [/system failure/, app_inspect]
15
+
16
+ assert_error [KAXErrorIllegalArgument],
17
+ should_raise: ArgumentError,
18
+ with_fragments: [/is not an AXUIElementRef/, app_inspect]
19
+
20
+ assert_error [KAXErrorIllegalArgument, :cake],
21
+ should_raise: ArgumentError,
22
+ with_fragments: [/is not a legal argument/, /the element/, app_inspect, /cake/]
23
+
24
+ assert_error [KAXErrorIllegalArgument, 'cake', 'chocolate'],
25
+ should_raise: ArgumentError,
26
+ with_fragments: [/can't get\/set "cake" with\/to "chocolate"/, app_inspect]
27
+
28
+ p = CGPoint.new(1,3)
29
+ assert_error [KAXErrorIllegalArgument, p, nil, nil],
30
+ should_raise: ArgumentError,
31
+ with_fragments: [/The point #{p.inspect}/, app_inspect]
32
+
33
+ assert_error [KAXErrorInvalidUIElement],
34
+ should_raise: ArgumentError,
35
+ with_fragments: [/no longer a valid reference/, app_inspect]
36
+
37
+ assert_error [KAXErrorInvalidUIElementObserver, :pie, :cake],
38
+ should_raise: ArgumentError,
39
+ with_fragments: [/no longer support/]
40
+
41
+ assert_error [KAXErrorCannotComplete],
42
+ should_raise: RuntimeError,
43
+ with_fragments: [/An unspecified error/, app_inspect, /:\(/]
44
+
45
+ @derp = Accessibility::Element.application_for pid_for 'com.apple.finder'
46
+ def @derp.pid; false end
47
+ assert_error [KAXErrorCannotComplete],
48
+ should_raise: RuntimeError,
49
+ with_fragments: [/Application for pid/, /Maybe it crashed\?/]
50
+ @derp = nil
51
+
52
+ assert_error [KAXErrorAttributeUnsupported, :cake],
53
+ should_raise: ArgumentError,
54
+ with_fragments: [/does not have/, /:cake attribute/, app_inspect]
55
+
56
+ assert_error [KAXErrorActionUnsupported, :pie],
57
+ should_raise: ArgumentError,
58
+ with_fragments: [/does not have/, /:pie action/, app_inspect]
59
+
60
+ assert_error [KAXErrorNotificationUnsupported, :cheese],
61
+ should_raise: ArgumentError,
62
+ with_fragments: [/no longer support/]
63
+
64
+ assert_error [KAXErrorNotImplemented],
65
+ should_raise: NotImplementedError,
66
+ with_fragments: [/does not work with AXAPI/, app_inspect]
67
+
68
+ assert_error [KAXErrorNotificationAlreadyRegistered, :lamp],
69
+ should_raise: ArgumentError,
70
+ with_fragments: [/no longer support/]
71
+
72
+ assert_error [KAXErrorNotificationNotRegistered, :peas],
73
+ should_raise: RuntimeError,
74
+ with_fragments: [/no longer support/]
75
+
76
+ assert_error [KAXErrorAPIDisabled],
77
+ should_raise: RuntimeError,
78
+ with_fragments: [/AXAPI has been disabled/]
79
+
80
+ assert_error [KAXErrorNoValue],
81
+ should_raise: RuntimeError,
82
+ with_fragments: [/internal error/]
83
+
84
+ assert_error [KAXErrorParameterizedAttributeUnsupported, :oscar],
85
+ should_raise: ArgumentError,
86
+ with_fragments: [/does not have/, /:oscar parameterized attribute/, app_inspect]
87
+
88
+ assert_error [KAXErrorNotEnoughPrecision],
89
+ should_raise: RuntimeError,
90
+ with_fragments: [/not enough precision/, '¯\(°_o)/¯']
91
+
92
+ exception = assert_raises(RuntimeError) { app.send(:handle_error, 0) }
93
+ assert_match /assertion failed/, exception.message
94
+
95
+ assert_error [99],
96
+ should_raise: RuntimeError,
97
+ with_fragments: [/unknown error code/, /99/, app_inspect]
98
+ end
99
+
100
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: accessibility_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-25 00:00:00.000000000 Z
12
+ date: 2012-12-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yard
@@ -90,6 +90,7 @@ files:
90
90
  - README.markdown
91
91
  - History.markdown
92
92
  - .yardopts
93
+ - test/test_core.rb
93
94
  - test/helper.rb
94
95
  homepage: http://github.com/AXElements/accessibility_core
95
96
  licenses:
@@ -106,7 +107,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
107
  version: '0'
107
108
  segments:
108
109
  - 0
109
- hash: -1612632312201987392
110
+ hash: 4511147993527335350
110
111
  required_rubygems_version: !ruby/object:Gem::Requirement
111
112
  none: false
112
113
  requirements:
@@ -115,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
116
  version: '0'
116
117
  segments:
117
118
  - 0
118
- hash: -1612632312201987392
119
+ hash: 4511147993527335350
119
120
  requirements: []
120
121
  rubyforge_project:
121
122
  rubygems_version: 1.8.24
@@ -123,4 +124,5 @@ signing_key:
123
124
  specification_version: 3
124
125
  summary: A library for building automation tools on OS X
125
126
  test_files:
127
+ - test/test_core.rb
126
128
  - test/helper.rb