spicycode-micronaut 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/LICENSE +20 -0
  2. data/README +17 -0
  3. data/Rakefile +55 -0
  4. data/examples/example_helper.rb +19 -0
  5. data/examples/lib/micronaut/example_group_example.rb +116 -0
  6. data/examples/lib/micronaut/example_runner_example.rb +5 -0
  7. data/examples/lib/micronaut/expectations/differs/default_example.rb +126 -0
  8. data/examples/lib/micronaut/expectations/extensions/object_example.rb +78 -0
  9. data/examples/lib/micronaut/expectations/fail_with_example.rb +71 -0
  10. data/examples/lib/micronaut/expectations/wrap_expectation_example.rb +30 -0
  11. data/examples/lib/micronaut_example.rb +8 -0
  12. data/lib/autotest/discover.rb +3 -0
  13. data/lib/autotest/micronaut.rb +43 -0
  14. data/lib/micronaut/example_group.rb +100 -0
  15. data/lib/micronaut/example_runner.rb +108 -0
  16. data/lib/micronaut/example_world.rb +13 -0
  17. data/lib/micronaut/exceptions.rb +7 -0
  18. data/lib/micronaut/expectations/differs/default.rb +67 -0
  19. data/lib/micronaut/expectations/handler.rb +52 -0
  20. data/lib/micronaut/expectations/object_extensions.rb +62 -0
  21. data/lib/micronaut/expectations/string_and_symbol_extensions.rb +17 -0
  22. data/lib/micronaut/expectations/wrap_expectation.rb +51 -0
  23. data/lib/micronaut/expectations.rb +57 -0
  24. data/lib/micronaut/extensions/kernel.rb +15 -0
  25. data/lib/micronaut/matchers/be.rb +203 -0
  26. data/lib/micronaut/matchers/be_close.rb +37 -0
  27. data/lib/micronaut/matchers/change.rb +148 -0
  28. data/lib/micronaut/matchers/eql.rb +43 -0
  29. data/lib/micronaut/matchers/equal.rb +43 -0
  30. data/lib/micronaut/matchers/errors.rb +5 -0
  31. data/lib/micronaut/matchers/exist.rb +22 -0
  32. data/lib/micronaut/matchers/generated_descriptions.rb +36 -0
  33. data/lib/micronaut/matchers/has.rb +34 -0
  34. data/lib/micronaut/matchers/have.rb +150 -0
  35. data/lib/micronaut/matchers/include.rb +77 -0
  36. data/lib/micronaut/matchers/match.rb +41 -0
  37. data/lib/micronaut/matchers/method_missing.rb +9 -0
  38. data/lib/micronaut/matchers/operator_matcher.rb +72 -0
  39. data/lib/micronaut/matchers/raise_error.rb +132 -0
  40. data/lib/micronaut/matchers/respond_to.rb +46 -0
  41. data/lib/micronaut/matchers/satisfy.rb +47 -0
  42. data/lib/micronaut/matchers/simple_matcher.rb +132 -0
  43. data/lib/micronaut/matchers/throw_symbol.rb +100 -0
  44. data/lib/micronaut/matchers.rb +141 -0
  45. data/lib/micronaut/mocking/with_mocha.rb +23 -0
  46. data/lib/micronaut.rb +42 -0
  47. metadata +120 -0
@@ -0,0 +1,132 @@
1
+ module Micronaut
2
+ module Matchers
3
+ class SimpleMatcher
4
+ attr_writer :failure_message, :negative_failure_message, :description
5
+
6
+ def initialize(description, &match_block)
7
+ @description = description
8
+ @match_block = match_block
9
+ end
10
+
11
+ def matches?(given)
12
+ @given = given
13
+ case @match_block.arity
14
+ when 2
15
+ @match_block.call(@given, self)
16
+ else
17
+ @match_block.call(@given)
18
+ end
19
+ end
20
+
21
+ def description
22
+ @description || explanation
23
+ end
24
+
25
+ def failure_message
26
+ @failure_message || (@description.nil? ? explanation : %[expected #{@description.inspect} but got #{@given.inspect}])
27
+ end
28
+
29
+ def negative_failure_message
30
+ @negative_failure_message || (@description.nil? ? explanation : %[expected not to get #{@description.inspect}, but got #{@given.inspect}])
31
+ end
32
+
33
+ def explanation
34
+ "No description provided. See RDoc for simple_matcher()"
35
+ end
36
+ end
37
+
38
+ # simple_matcher makes it easy for you to create your own custom matchers
39
+ # in just a few lines of code when you don't need all the power of a
40
+ # completely custom matcher object.
41
+ #
42
+ # The <tt>description</tt> argument will appear as part of any failure
43
+ # message, and is also the source for auto-generated descriptions.
44
+ #
45
+ # The <tt>match_block</tt> can have an arity of 1 or 2. The first block
46
+ # argument will be the given value. The second, if the block accepts it
47
+ # will be the matcher itself, giving you access to set custom failure
48
+ # messages in favor of the defaults.
49
+ #
50
+ # The <tt>match_block</tt> should return a boolean: <tt>true</tt>
51
+ # indicates a match, which will pass if you use <tt>should</tt> and fail
52
+ # if you use <tt>should_not</tt>. false (or nil) indicates no match,
53
+ # which will do the reverse: fail if you use <tt>should</tt> and pass if
54
+ # you use <tt>should_not</tt>.
55
+ #
56
+ # An error in the <tt>match_block</tt> will bubble up, resulting in a
57
+ # failure.
58
+ #
59
+ # == Example with default messages
60
+ #
61
+ # def be_even
62
+ # simple_matcher("an even number") { |given| given % 2 == 0 }
63
+ # end
64
+ #
65
+ # describe 2 do
66
+ # it "should be even" do
67
+ # 2.should be_even
68
+ # end
69
+ # end
70
+ #
71
+ # Given an odd number, this example would produce an error message stating:
72
+ # expected "an even number", got 3.
73
+ #
74
+ # Unfortunately, if you're a fan of auto-generated descriptions, this will
75
+ # produce "should an even number." Not the most desirable result. You can
76
+ # control that using custom messages:
77
+ #
78
+ # == Example with custom messages
79
+ #
80
+ # def rhyme_with(expected)
81
+ # simple_matcher("rhyme with #{expected.inspect}") do |given, matcher|
82
+ # matcher.failure_message = "expected #{given.inspect} to rhyme with #{expected.inspect}"
83
+ # matcher.negative_failure_message = "expected #{given.inspect} not to rhyme with #{expected.inspect}"
84
+ # given.rhymes_with? expected
85
+ # end
86
+ # end
87
+ #
88
+ # # OR
89
+ #
90
+ # def rhyme_with(expected)
91
+ # simple_matcher do |given, matcher|
92
+ # matcher.description = "rhyme with #{expected.inspect}"
93
+ # matcher.failure_message = "expected #{given.inspect} to rhyme with #{expected.inspect}"
94
+ # matcher.negative_failure_message = "expected #{given.inspect} not to rhyme with #{expected.inspect}"
95
+ # given.rhymes_with? expected
96
+ # end
97
+ # end
98
+ #
99
+ # describe "pecan" do
100
+ # it "should rhyme with 'be gone'" do
101
+ # nut = "pecan"
102
+ # nut.extend Rhymer
103
+ # nut.should rhyme_with("be gone")
104
+ # end
105
+ # end
106
+ #
107
+ # The resulting messages would be:
108
+ # description: rhyme with "be gone"
109
+ # failure_message: expected "pecan" to rhyme with "be gone"
110
+ # negative failure_message: expected "pecan" not to rhyme with "be gone"
111
+ #
112
+ # == Wrapped Expectations
113
+ #
114
+ # Because errors will bubble up, it is possible to wrap other expectations
115
+ # in a SimpleMatcher.
116
+ #
117
+ # def be_even
118
+ # simple_matcher("an even number") { |given| (given % 2).should == 0 }
119
+ # end
120
+ #
121
+ # BE VERY CAREFUL when you do this. Only use wrapped expectations for
122
+ # matchers that will always be used in only the positive
123
+ # (<tt>should</tt>) or negative (<tt>should_not</tt>), but not both.
124
+ # The reason is that is you wrap a <tt>should</tt> and call the wrapper
125
+ # with <tt>should_not</tt>, the correct result (the <tt>should</tt>
126
+ # failing), will fail when you want it to pass.
127
+ #
128
+ def simple_matcher(description=nil, &match_block)
129
+ SimpleMatcher.new(description, &match_block)
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,100 @@
1
+ module Micronaut
2
+ module Matchers
3
+
4
+ class ThrowSymbol #:nodoc:
5
+ def initialize(expected_symbol = nil, expected_arg=nil)
6
+ @expected_symbol = expected_symbol
7
+ @expected_arg = expected_arg
8
+ @caught_symbol = nil
9
+ end
10
+
11
+ def matches?(given_proc)
12
+ begin
13
+ if @expected_symbol.nil?
14
+ given_proc.call
15
+ else
16
+ @caught_arg = catch :proc_did_not_throw_anything do
17
+ catch @expected_symbol do
18
+ given_proc.call
19
+ throw :proc_did_not_throw_anything, :nothing_thrown
20
+ end
21
+ end
22
+ @caught_symbol = @expected_symbol unless @caught_arg == :nothing_thrown
23
+ end
24
+ rescue NameError => e
25
+ raise e unless e.message =~ /uncaught throw/
26
+ @caught_symbol = e.name.to_sym
27
+ ensure
28
+ if @expected_symbol.nil?
29
+ return !@caught_symbol.nil?
30
+ else
31
+ if @expected_arg.nil?
32
+ return @caught_symbol == @expected_symbol
33
+ else
34
+ return @caught_symbol == @expected_symbol && @caught_arg == @expected_arg
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def failure_message
41
+ if @caught_symbol
42
+ "expected #{expected}, got #{@caught_symbol.inspect}"
43
+ else
44
+ "expected #{expected} but nothing was thrown"
45
+ end
46
+ end
47
+
48
+ def negative_failure_message
49
+ if @expected_symbol
50
+ "expected #{expected} not to be thrown"
51
+ else
52
+ "expected no Symbol, got :#{@caught_symbol}"
53
+ end
54
+ end
55
+
56
+ def description
57
+ "throw #{expected}"
58
+ end
59
+
60
+ private
61
+
62
+ def expected
63
+ @expected_symbol.nil? ? "a Symbol" : "#{@expected_symbol.inspect}#{args}"
64
+ end
65
+
66
+ def args
67
+ @expected_arg.nil? ? "" : " with #{@expected_arg.inspect}"
68
+ end
69
+
70
+ end
71
+
72
+ # :call-seq:
73
+ # should throw_symbol()
74
+ # should throw_symbol(:sym)
75
+ # should throw_symbol(:sym, arg)
76
+ # should_not throw_symbol()
77
+ # should_not throw_symbol(:sym)
78
+ # should_not throw_symbol(:sym, arg)
79
+ #
80
+ # Given no argument, matches if a proc throws any Symbol.
81
+ #
82
+ # Given a Symbol, matches if the given proc throws the specified Symbol.
83
+ #
84
+ # Given a Symbol and an arg, matches if the given proc throws the
85
+ # specified Symbol with the specified arg.
86
+ #
87
+ # == Examples
88
+ #
89
+ # lambda { do_something_risky }.should throw_symbol
90
+ # lambda { do_something_risky }.should throw_symbol(:that_was_risky)
91
+ # lambda { do_something_risky }.should throw_symbol(:that_was_risky, culprit)
92
+ #
93
+ # lambda { do_something_risky }.should_not throw_symbol
94
+ # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky)
95
+ # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky, culprit)
96
+ def throw_symbol(sym=nil)
97
+ Matchers::ThrowSymbol.new(sym)
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,141 @@
1
+ require 'micronaut/matchers/generated_descriptions'
2
+ require 'micronaut/matchers/errors'
3
+ require 'micronaut/matchers/method_missing'
4
+ require 'micronaut/matchers/simple_matcher'
5
+ require 'micronaut/matchers/be'
6
+ require 'micronaut/matchers/be_close'
7
+ require 'micronaut/matchers/change'
8
+ require 'micronaut/matchers/eql'
9
+ require 'micronaut/matchers/equal'
10
+ require 'micronaut/matchers/exist'
11
+ require 'micronaut/matchers/has'
12
+ require 'micronaut/matchers/have'
13
+ require 'micronaut/matchers/include'
14
+ require 'micronaut/matchers/match'
15
+ require 'micronaut/matchers/raise_error'
16
+ require 'micronaut/matchers/respond_to'
17
+ require 'micronaut/matchers/satisfy'
18
+ require 'micronaut/matchers/throw_symbol'
19
+ require 'micronaut/matchers/operator_matcher'
20
+
21
+ module Micronaut
22
+
23
+ # We ship with a number of useful Expression Matchers. An Expression Matcher
24
+ # is any object that responds to the following methods:
25
+ #
26
+ # matches?(actual)
27
+ # failure_message
28
+ # negative_failure_message #optional
29
+ # description #optional
30
+ #
31
+ # See Micronaut::Expectations to learn how to use these as Expectation Matchers.
32
+ # See Micronaut::Mocks to learn how to use them as Mock Argument Constraints.
33
+ #
34
+ # == Predicates
35
+ #
36
+ # In addition to those Expression Matchers that are defined explicitly, we will
37
+ # create custom Matchers on the fly for any arbitrary predicate, giving your specs
38
+ # a much more natural language feel.
39
+ #
40
+ # A Ruby predicate is a method that ends with a "?" and returns true or false.
41
+ # Common examples are +empty?+, +nil?+, and +instance_of?+.
42
+ #
43
+ # All you need to do is write +should be_+ followed by the predicate without
44
+ # the question mark, and we will figure it out from there. For example:
45
+ #
46
+ # [].should be_empty => [].empty? #passes
47
+ # [].should_not be_empty => [].empty? #fails
48
+ #
49
+ # In addtion to prefixing the predicate matchers with "be_", you can also use "be_a_"
50
+ # and "be_an_", making your specs read much more naturally:
51
+ #
52
+ # "a string".should be_an_instance_of(String) =>"a string".instance_of?(String) #passes
53
+ #
54
+ # 3.should be_a_kind_of(Fixnum) => 3.kind_of?(Numeric) #passes
55
+ # 3.should be_a_kind_of(Numeric) => 3.kind_of?(Numeric) #passes
56
+ # 3.should be_an_instance_of(Fixnum) => 3.instance_of?(Fixnum) #passes
57
+ # 3.should_not be_instance_of(Numeric) => 3.instance_of?(Numeric) #fails
58
+ #
59
+ # We will also create custom matchers for predicates like +has_key?+. To
60
+ # use this feature, just state that the object should have_key(:key) and we will
61
+ # call has_key?(:key) on the target. For example:
62
+ #
63
+ # {:a => "A"}.should have_key(:a) => {:a => "A"}.has_key?(:a) #passes
64
+ # {:a => "A"}.should have_key(:b) => {:a => "A"}.has_key?(:b) #fails
65
+ #
66
+ # You can use this feature to invoke any predicate that begins with "has_", whether it is
67
+ # part of the Ruby libraries (like +Hash#has_key?+) or a method you wrote on your own class.
68
+ #
69
+ # == Custom Expectation Matchers
70
+ #
71
+ # When you find that none of the stock Expectation Matchers provide a natural
72
+ # feeling expectation, you can very easily write your own.
73
+ #
74
+ # For example, imagine that you are writing a game in which players can
75
+ # be in various zones on a virtual board. To specify that bob should
76
+ # be in zone 4, you could say:
77
+ #
78
+ # bob.current_zone.should eql(Zone.new("4"))
79
+ #
80
+ # But you might find it more expressive to say:
81
+ #
82
+ # bob.should be_in_zone("4")
83
+ #
84
+ # and/or
85
+ #
86
+ # bob.should_not be_in_zone("3")
87
+ #
88
+ # To do this, you would need to write a class like this:
89
+ #
90
+ # class BeInZone
91
+ # def initialize(expected)
92
+ # @expected = expected
93
+ # end
94
+ # def matches?(target)
95
+ # @target = target
96
+ # @target.current_zone.eql?(Zone.new(@expected))
97
+ # end
98
+ # def failure_message
99
+ # "expected #{@target.inspect} to be in Zone #{@expected}"
100
+ # end
101
+ # def negative_failure_message
102
+ # "expected #{@target.inspect} not to be in Zone #{@expected}"
103
+ # end
104
+ # end
105
+ #
106
+ # ... and a method like this:
107
+ #
108
+ # def be_in_zone(expected)
109
+ # BeInZone.new(expected)
110
+ # end
111
+ #
112
+ # And then expose the method to your specs. This is normally done
113
+ # by including the method and the class in a module, which is then
114
+ # included in your spec:
115
+ #
116
+ # module CustomGameMatchers
117
+ # class BeInZone
118
+ # ...
119
+ # end
120
+ #
121
+ # def be_in_zone(expected)
122
+ # ...
123
+ # end
124
+ # end
125
+ #
126
+ # describe "Player behaviour" do
127
+ # include CustomGameMatchers
128
+ # ...
129
+ # end
130
+ #
131
+ # or you can include in globally in a spec_helper.rb file <tt>require</tt>d
132
+ # from your spec file(s):
133
+ #
134
+ # Micronaut::Runner.configure do |config|
135
+ # config.include(CustomGameMatchers)
136
+ # end
137
+ #
138
+ module Matchers
139
+
140
+ end
141
+ end
@@ -0,0 +1,23 @@
1
+ require 'mocha/standalone'
2
+ require 'mocha/object'
3
+
4
+ module Micronaut
5
+ module Mocking
6
+ module WithMocha
7
+ include Mocha::Standalone
8
+
9
+ def setup_mocks
10
+ mocha_setup
11
+ end
12
+
13
+ def verify_mocks
14
+ mocha_verify
15
+ end
16
+
17
+ def teardown_mocks
18
+ mocha_teardown
19
+ end
20
+
21
+ end
22
+ end
23
+ end
data/lib/micronaut.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'micronaut/mocking/with_mocha'
2
+ require 'micronaut/exceptions'
3
+ require 'micronaut/matchers'
4
+ require 'micronaut/expectations'
5
+ require 'micronaut/example_world'
6
+ require 'micronaut/example_runner'
7
+ require 'micronaut/example_group'
8
+ require 'micronaut/extensions/kernel'
9
+
10
+ module Micronaut
11
+ VERSION = "0.0.2"
12
+
13
+ file = if RUBY_VERSION =~ /^1\.9/ then # bt's expanded, but __FILE__ isn't :(
14
+ File.expand_path __FILE__
15
+ elsif __FILE__ =~ /^[^\.]/ then # assume both relative
16
+ require 'pathname'
17
+ pwd = Pathname.new(Dir.pwd)
18
+ path_name = Pathname.new(File.expand_path(__FILE__))
19
+ path_name = File.join(".", path_name.relative_path_from(pwd)) unless path_name.relative?
20
+ path_name.to_s
21
+ else # assume both are expanded
22
+ __FILE__
23
+ end
24
+
25
+ # './lib' in project dir, or '/usr/local/blahblah' if installed
26
+ MICRONAUT_DIR = File.expand_path(File.dirname(File.dirname(file)))
27
+
28
+ def self.filter_backtrace(backtrace)
29
+ return ["No backtrace"] unless backtrace
30
+
31
+ new_backtrace = []
32
+ backtrace.each_with_index do |line, index|
33
+ break if line.rindex(MICRONAUT_DIR, 0) && index > 2
34
+ new_backtrace << line
35
+ end
36
+
37
+ new_backtrace = backtrace.reject { |line| line.rindex(MICRONAUT_DIR, 0) } if new_backtrace.empty?
38
+ new_backtrace = backtrace.dup if new_backtrace.empty?
39
+ new_backtrace
40
+ end
41
+
42
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spicycode-micronaut
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Chad Humphries
8
+ autorequire: micronaut
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-11-21 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: mocha
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ description: An excellent replacement for the wheel...
25
+ email: chad@spicycode.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - README
32
+ - LICENSE
33
+ files:
34
+ - LICENSE
35
+ - README
36
+ - Rakefile
37
+ - lib/autotest
38
+ - lib/autotest/discover.rb
39
+ - lib/autotest/micronaut.rb
40
+ - lib/micronaut
41
+ - lib/micronaut/example_group.rb
42
+ - lib/micronaut/example_runner.rb
43
+ - lib/micronaut/example_world.rb
44
+ - lib/micronaut/exceptions.rb
45
+ - lib/micronaut/expectations
46
+ - lib/micronaut/expectations/differs
47
+ - lib/micronaut/expectations/differs/default.rb
48
+ - lib/micronaut/expectations/handler.rb
49
+ - lib/micronaut/expectations/object_extensions.rb
50
+ - lib/micronaut/expectations/string_and_symbol_extensions.rb
51
+ - lib/micronaut/expectations/wrap_expectation.rb
52
+ - lib/micronaut/expectations.rb
53
+ - lib/micronaut/extensions
54
+ - lib/micronaut/extensions/kernel.rb
55
+ - lib/micronaut/matchers
56
+ - lib/micronaut/matchers/be.rb
57
+ - lib/micronaut/matchers/be_close.rb
58
+ - lib/micronaut/matchers/change.rb
59
+ - lib/micronaut/matchers/eql.rb
60
+ - lib/micronaut/matchers/equal.rb
61
+ - lib/micronaut/matchers/errors.rb
62
+ - lib/micronaut/matchers/exist.rb
63
+ - lib/micronaut/matchers/generated_descriptions.rb
64
+ - lib/micronaut/matchers/has.rb
65
+ - lib/micronaut/matchers/have.rb
66
+ - lib/micronaut/matchers/include.rb
67
+ - lib/micronaut/matchers/match.rb
68
+ - lib/micronaut/matchers/method_missing.rb
69
+ - lib/micronaut/matchers/operator_matcher.rb
70
+ - lib/micronaut/matchers/raise_error.rb
71
+ - lib/micronaut/matchers/respond_to.rb
72
+ - lib/micronaut/matchers/satisfy.rb
73
+ - lib/micronaut/matchers/simple_matcher.rb
74
+ - lib/micronaut/matchers/throw_symbol.rb
75
+ - lib/micronaut/matchers.rb
76
+ - lib/micronaut/mocking
77
+ - lib/micronaut/mocking/with_mocha.rb
78
+ - lib/micronaut.rb
79
+ - examples/example_helper.rb
80
+ - examples/lib
81
+ - examples/lib/micronaut
82
+ - examples/lib/micronaut/example_group_example.rb
83
+ - examples/lib/micronaut/example_runner_example.rb
84
+ - examples/lib/micronaut/expectations
85
+ - examples/lib/micronaut/expectations/differs
86
+ - examples/lib/micronaut/expectations/differs/default_example.rb
87
+ - examples/lib/micronaut/expectations/extensions
88
+ - examples/lib/micronaut/expectations/extensions/object_example.rb
89
+ - examples/lib/micronaut/expectations/fail_with_example.rb
90
+ - examples/lib/micronaut/expectations/wrap_expectation_example.rb
91
+ - examples/lib/micronaut/matchers
92
+ - examples/lib/micronaut_example.rb
93
+ has_rdoc: true
94
+ homepage: http://spicycode.com
95
+ post_install_message:
96
+ rdoc_options: []
97
+
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: "0"
105
+ version:
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: "0"
111
+ version:
112
+ requirements: []
113
+
114
+ rubyforge_project:
115
+ rubygems_version: 1.2.0
116
+ signing_key:
117
+ specification_version: 2
118
+ summary: An excellent replacement for the wheel...
119
+ test_files: []
120
+