power_assert 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7444d3904ad2148eb3fc1f836d721d28f1c59fe4
4
+ data.tar.gz: 6aade4c736ebba939973db85fc33f9e276daf010
5
+ SHA512:
6
+ metadata.gz: 948cfe90a83135a15de3b7ac7d4dbdec085c352a2b04857b1e3e22e878a69eac63f54ca16d389aa6134037387b667e6ff8f7f3db3a94aeb3513f91c60d6e7f41
7
+ data.tar.gz: 666404c70ed0c62857490819241e169b994163d23972a62ff6f22b89372c47932aaec1647018d39f1824b823c1ea47a08a4db843816ad379499c41979d22c09b
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ Gemfile.lock
3
+ pkg/*
4
+ vendor/*
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.1
5
+ - ruby-head
data/BSDL ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (C) 2014 Kazuki Tsujimoto, All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ SUCH DAMAGE.
data/COPYING ADDED
@@ -0,0 +1,57 @@
1
+ Copyright (C) 2014 Kazuki Tsujimoto, All rights reserved.
2
+
3
+ You can redistribute it and/or modify it under either the terms of the
4
+ 2-clause BSDL (see the file BSDL), or the conditions below:
5
+
6
+ 1. You may make and give away verbatim copies of the source form of the
7
+ software without restriction, provided that you duplicate all of the
8
+ original copyright notices and associated disclaimers.
9
+
10
+ 2. You may modify your copy of the software in any way, provided that
11
+ you do at least ONE of the following:
12
+
13
+ a) place your modifications in the Public Domain or otherwise
14
+ make them Freely Available, such as by posting said
15
+ modifications to Usenet or an equivalent medium, or by allowing
16
+ the author to include your modifications in the software.
17
+
18
+ b) use the modified software only within your corporation or
19
+ organization.
20
+
21
+ c) give non-standard binaries non-standard names, with
22
+ instructions on where to get the original software distribution.
23
+
24
+ d) make other distribution arrangements with the author.
25
+
26
+ 3. You may distribute the software in object code or binary form,
27
+ provided that you do at least ONE of the following:
28
+
29
+ a) distribute the binaries and library files of the software,
30
+ together with instructions (in the manual page or equivalent)
31
+ on where to get the original distribution.
32
+
33
+ b) accompany the distribution with the machine-readable source of
34
+ the software.
35
+
36
+ c) give non-standard binaries non-standard names, with
37
+ instructions on where to get the original software distribution.
38
+
39
+ d) make other distribution arrangements with the author.
40
+
41
+ 4. You may modify and include the part of the software into any other
42
+ software (possibly commercial). But some files in the distribution
43
+ are not written by the author, so that they are not under these terms.
44
+
45
+ For the list of those files and their copying conditions, see the
46
+ file LEGAL.
47
+
48
+ 5. The scripts and library files supplied as input to or produced as
49
+ output from the software do not automatically fall under the
50
+ copyright of the software, but belong to whomever generated them,
51
+ and may be sold commercially, and may be aggregated with this
52
+ software.
53
+
54
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
55
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
56
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57
+ PURPOSE.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,8 @@
1
+ = power_assert
2
+ == About
3
+ Power Assert for Ruby.
4
+
5
+ == Related Projects
6
+ * {test-unit-power_assert}[https://github.com/k-tsj/test-unit-power_assert]
7
+
8
+ == Travis Build Status {<img src="https://secure.travis-ci.org/k-tsj/power_assert.png"/>}[http://travis-ci.org/k-tsj/power_assert]
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rake/testtask"
4
+ task :default => :test
5
+ Rake::TestTask.new do |t|
6
+ t.ruby_opts = ["-rpower_assert"]
7
+ t.test_files = FileList["test/test_*.rb"]
8
+ end
@@ -0,0 +1,3 @@
1
+ module PowerAssert
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,224 @@
1
+ # power_assert.rb
2
+ #
3
+ # Copyright (C) 2014 Kazuki Tsujimoto, All rights reserved.
4
+
5
+ require 'power_assert/version'
6
+
7
+ require 'ripper'
8
+ require 'pattern-match'
9
+
10
+ # NB: API is not fixed
11
+
12
+ module PowerAssert
13
+ class Context
14
+ Value = Struct.new(:name, :value, :column)
15
+ Ident = Struct.new(:type, :name, :column)
16
+
17
+ TARGET_CALLER_DIFF = {return: 5, c_return: 4}
18
+ TARGET_CALLER_INDEX = {return: 3, c_return: 2}
19
+
20
+ attr_reader :message_proc
21
+
22
+ def initialize(assertion_proc, assertion_method)
23
+ path = nil
24
+ lineno = nil
25
+ line = nil
26
+ methods = nil
27
+ refs = nil
28
+ method_ids = nil
29
+ return_values = []
30
+ @base_caller_length = -1
31
+ @assertion_proc = assertion_proc
32
+ @message_proc = -> {
33
+ @assertion_message ||=
34
+ @base_caller_length > 0 ? assertion_message(line, methods, return_values, refs, @assertion_proc.binding).freeze : nil
35
+ }
36
+ @proc_local_variables = assertion_proc ? assertion_proc.binding.eval('local_variables').map(&:to_s) : []
37
+ @trace = TracePoint.new(:return, :c_return) do |tp|
38
+ next if method_ids and ! method_ids.include?(tp.method_id)
39
+ locs = tp.binding.eval('caller_locations')
40
+ if locs.length - @base_caller_length == TARGET_CALLER_DIFF[tp.event]
41
+ idx = TARGET_CALLER_INDEX[tp.event]
42
+ path ||= locs[idx].path
43
+ lineno ||= locs[idx].lineno
44
+ line ||= open(path).each_line.drop(lineno - 1).first
45
+ unless methods
46
+ idents = extract_idents(Ripper.sexp(line), assertion_method)
47
+ methods, refs = idents.partition {|i| i.type == :method }
48
+ end
49
+ method_ids = methods.map(&:name).map(&:to_sym).uniq
50
+ if path == locs[idx].path and lineno == locs[idx].lineno
51
+ return_values << Value[tp.method_id.to_s, tp.return_value, nil]
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ def yield
58
+ do_yield(&@assertion_proc)
59
+ end
60
+
61
+ private
62
+
63
+ def do_yield
64
+ @trace.enable do
65
+ @base_caller_length = caller_locations.length
66
+ yield
67
+ end
68
+ end
69
+
70
+ def assertion_message(line, methods, return_values, refs, proc_binding)
71
+ set_column(line, methods, return_values)
72
+ ref_values = refs ? refs.map {|i| Value[i.name, proc_binding.eval(i.name), i.column] } : []
73
+ vals = (return_values + ref_values).find_all(&:column).sort_by(&:column).reverse
74
+ if vals.empty?
75
+ return line || ''
76
+ end
77
+ fmt = (vals[0].column + 1).times.map {|i| vals.find {|v| v.column == i } ? "%<#{i}>s" : ' ' }.join
78
+ ret = []
79
+ ret << line.chomp
80
+ ret << sprintf(fmt, vals.each_with_object({}) {|v, h| h[v.column.to_s.to_sym] = '|' }).chomp
81
+ vals.each do |i|
82
+ ret << sprintf(fmt,
83
+ vals.each_with_object({}) do |j, h|
84
+ h[j.column.to_s.to_sym] = [i.value.inspect, '|', ' '][i.column <=> j.column]
85
+ end).rstrip
86
+ end
87
+ ret.join("\n")
88
+ end
89
+
90
+ def set_column(line, methods, return_values)
91
+ methods &&= methods.dup
92
+ return_values.each do |val|
93
+ idx = methods.index {|method| method.name == val.name }
94
+ if idx and (m = methods.delete_at(idx)).column
95
+ val.column = m.column
96
+ else
97
+ ridx = return_values.rindex {|i| i.name == val.name and i.column }
98
+ method_name = val.name
99
+ re = /
100
+ #{'\b' if /\A\w/ =~ method_name}
101
+ #{Regexp.escape(method_name)}
102
+ #{'\b' if /\w\z/ =~ method_name}
103
+ /x
104
+ val.column = line.index(re, ridx ? return_values[ridx].column + 1 : 0)
105
+ end
106
+ end
107
+ end
108
+
109
+ def extract_idents(sexp, assertion_method = nil)
110
+ match(sexp) do
111
+ with(_[:program,
112
+ _[_[:method_add_block,
113
+ _[:method_add_arg, _[:fcall, _[:@ident, assertion_method.to_s, _]], _],
114
+ _[Or(:brace_block, :do_block), _, ss]]]]) do
115
+ ss.flat_map {|s| extract_idents(s) }
116
+ end
117
+ with(_[:program, _[s, *_]]) do
118
+ extract_idents(s)
119
+ end
120
+ with(_[:method_add_arg, s0, s1]) do
121
+ s0_methods = extract_idents(s0)
122
+ s0_methods[0..-2] + extract_idents(s1) + [s0_methods[-1]]
123
+ end
124
+ with(_[:arg_paren, s]) do
125
+ extract_idents(s)
126
+ end
127
+ with(_[:args_add_block, _[:args_add_star, ss0, *ss1], _]) do
128
+ (ss0 + ss1).flat_map {|s| extract_idents(s) }
129
+ end
130
+ with(_[:args_add_block, ss, _]) do
131
+ ss.flat_map {|s| extract_idents(s) }
132
+ end
133
+ with(_[:vcall, _[:@ident, name, _[_, column]]]) do
134
+ [Ident[@proc_local_variables.include?(name) ? :ref : :method, name, column]]
135
+ end
136
+ with(_[:fcall, s]) do
137
+ extract_idents(s)
138
+ end
139
+ with(_[:binary, *ss]) do
140
+ ss.flat_map {|s| extract_idents(s) }
141
+ end
142
+ with(_[:call, s0, _, s1]) do
143
+ [s0, s1].flat_map {|s| extract_idents(s) }
144
+ end
145
+ with(_[:method_add_block, s, _]) do
146
+ extract_idents(s)
147
+ end
148
+ with(_[:hash, s]) do
149
+ extract_idents(s)
150
+ end
151
+ with(_[:assoclist_from_args, ss]) do
152
+ ss.flat_map {|s| extract_idents(s) }
153
+ end
154
+ with(_[:bare_assoc_hash, ss]) do
155
+ ss.flat_map {|s| extract_idents(s) }
156
+ end
157
+ with(_[:assoc_new, *ss]) do
158
+ ss.flat_map {|s| extract_idents(s) }
159
+ end
160
+ with(_[:assoc_splat, s]) do
161
+ extract_idents(s)
162
+ end
163
+ with(_[:array, ss]) do
164
+ ss.flat_map {|s| extract_idents(s) }
165
+ end
166
+ with(_[:string_literal, s]) do
167
+ extract_idents(s)
168
+ end
169
+ with(_[:string_content, *ss]) do
170
+ ss.flat_map {|s| extract_idents(s) }
171
+ end
172
+ with(_[:string_embexpr, _[*ss]]) do
173
+ ss.flat_map {|s| extract_idents(s) }
174
+ end
175
+ with(_[:regexp_literal, ss, _]) do
176
+ ss.flat_map {|s| extract_idents(s) }
177
+ end
178
+ with(_[:command, *ss]) do
179
+ ss.flat_map {|s| extract_idents(s) }
180
+ end
181
+ with(_[:command_call, s0, _, s1, s2]) do
182
+ [s0, s2, s1].flat_map {|s| extract_idents(s) }
183
+ end
184
+ with(_[:assign, _, s]) do
185
+ extract_idents(s)
186
+ end
187
+ with(_[:massign, _, s]) do
188
+ extract_idents(s)
189
+ end
190
+ with(_[:paren, ss]) do
191
+ ss.flat_map {|s| extract_idents(s) }
192
+ end
193
+ with(_[:var_ref, _[:@kw, "self", _[_, column]]]) do
194
+ [Ident[:ref, "self", column]]
195
+ end
196
+ with(_[:var_ref, _[Or(:@const, :@cvar, :@ivar, :@gvar), ref_name, _[_, column]]]) do
197
+ [Ident[:ref, ref_name, column]]
198
+ end
199
+ with(_[:@ident, method_name, _[_, column]]) do
200
+ [Ident[:method, method_name, column]]
201
+ end
202
+ with(_[:@const, method_name, _[_, column]]) do
203
+ [Ident[:method, method_name, column]]
204
+ end
205
+ with(s & Symbol) do
206
+ [Ident[:method, s.to_s, nil]]
207
+ end
208
+ with(_) do
209
+ []
210
+ end
211
+ end
212
+ end
213
+ end
214
+ private_constant :Context
215
+
216
+ def start(assertion_proc, assertion_method: nil)
217
+ yield Context.new(assertion_proc, assertion_method)
218
+ end
219
+ module_function :start
220
+ end
221
+
222
+ RubyVM::InstructionSequence.compile_option = {
223
+ specialized_instruction: false
224
+ }
@@ -0,0 +1,22 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ require 'power_assert/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'power_assert'
6
+ s.version = PowerAssert::VERSION
7
+ s.authors = ['Kazuki Tsujimoto']
8
+ s.email = ['kazuki@callcc.net']
9
+ s.homepage = 'https://github.com/k-tsj/power_assert'
10
+ s.summary = %q{Power Assert for Ruby}
11
+ s.description = %q{Power Assert for Ruby}
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f) }
16
+ s.require_paths = ['lib']
17
+ s.add_runtime_dependency 'pattern-match'
18
+ s.add_development_dependency 'test-unit'
19
+ s.add_development_dependency 'rake'
20
+ s.extra_rdoc_files = ['README.rdoc']
21
+ s.rdoc_options = ['--main', 'README.rdoc']
22
+ end
@@ -0,0 +1,149 @@
1
+ require 'test/unit'
2
+ require 'power_assert'
3
+ require 'ripper'
4
+ require 'set'
5
+
6
+ class TestPowerAssert < Test::Unit::TestCase
7
+ EXTRACT_METHODS_TEST = [
8
+ [[[:method, "c", 4], [:method, "b", 2], [:method, "d", 8], [:method, "a", 0]],
9
+ 'a(b(c), d))'],
10
+
11
+ [[[:method, "a", 0], [:method, "b", 2], [:method, "d", 6], [:method, "c", 4]],
12
+ 'a.b.c(d)'],
13
+
14
+ [[[:method, "b", 2], [:method, "a", 0], [:method, "c", 5], [:method, "e", 9], [:method, "d", 7]],
15
+ 'a(b).c.d(e)'],
16
+
17
+ [[[:method, "b", 4], [:method, "a", 2], [:method, "c", 7], [:method, "e", 13], [:method, "g", 11], [:method, "d", 9], [:method, "f", 0]],
18
+ 'f(a(b).c.d(g(e)))'],
19
+
20
+ [[[:method, "c", 5], [:method, "e", 11], [:method, "a", 0]],
21
+ 'a(b: c, d: e)'],
22
+
23
+ [[[:method, "b", 2], [:method, "c", 7], [:method, "d", 10], [:method, "e", 15], [:method, "a", 0]],
24
+ 'a(b => c, d => e)'],
25
+
26
+ [[[:method, "b", 4], [:method, "d", 10]],
27
+ '{a: b, c: d}'],
28
+
29
+ [[[:method, "a", 1], [:method, "b", 6], [:method, "c", 9], [:method, "d", 14]],
30
+ '{a => b, c => d}'],
31
+
32
+ [[[:method, "a", 2], [:method, "b", 5], [:method, "c", 10], [:method, "d", 13]],
33
+ '[[a, b], [c, d]]'],
34
+
35
+ [[[:method, "a", 0], [:method, "b", 2], [:method, "c", 5]],
36
+ 'a b, c { d }'],
37
+
38
+ [[[:method, "a", 20]],
39
+ 'assertion_message { a }'],
40
+
41
+ [[[:method, "a", 0]],
42
+ 'a { b }'],
43
+
44
+ [[[:method, "c", 4], [:method, "B", 2], [:method, "d", 8], [:method, "A", 0]],
45
+ 'A(B(c), d)'],
46
+
47
+ [[[:method, "c", 6], [:method, "f", 17], [:method, "h", 25], [:method, "a", 0]],
48
+ 'a(b = c, (d, e = f), G = h)'],
49
+
50
+ [[[:method, "b", 2], [:method, "c", 6], [:method, "d", 9], [:method, "e", 12], [:method, "g", 18], [:method, "i", 24], [:method, "j", 29], [:method, "a", 0]],
51
+ 'a(b, *c, d, e, f: g, h: i, **j)'],
52
+
53
+ [[[:method, "a", 0], [:method, "==", nil], [:method, "b", 5], [:method, "+", nil], [:method, "c", 9]],
54
+ 'a == b + c'],
55
+
56
+ [[[:ref, "var", 0], [:ref, "var", 8], [:method, "var", 4]],
57
+ 'var.var(var)'],
58
+
59
+ [[[:ref, "B", 2], [:ref, "@c", 5], [:ref, "@@d", 9], [:ref, "$e", 14], [:method, "f", 18], [:method, "self", 20], [:ref, "self", 26], [:method, "a", 0]],
60
+ 'a(B, @c, @@d, $e, f.self, self)'],
61
+
62
+ [[[:method, "a", 0], [:method, "c", 4], [:method, "b", 2]],
63
+ 'a.b c'],
64
+
65
+ [[[:method, "b", 4]],
66
+ '"a#{b}c"'],
67
+
68
+ [[[:method, "b", 4]],
69
+ '/a#{b}c/'],
70
+ ]
71
+
72
+ EXTRACT_METHODS_TEST.each_with_index do |(expect, source), idx|
73
+ define_method("test_extract_methods_#{'%03d' % idx}") do
74
+ pa = PowerAssert.const_get(:Context).new(-> { var = nil; -> {} }.(), nil)
75
+ assert_equal expect, pa.send(:extract_idents, Ripper.sexp(source), :assertion_message).map(&:to_a), source
76
+ end
77
+ end
78
+
79
+ def assertion_message(&blk)
80
+ ::PowerAssert.start(blk, assertion_method: __method__) do |pa|
81
+ pa.yield
82
+ pa.message_proc.()
83
+ end
84
+ end
85
+
86
+ def test_assertion_message
87
+ a = 0
88
+ @b = 1
89
+ @@c = 2
90
+ $d = 3
91
+ assert_equal <<END.chomp, assertion_message {
92
+ String(a) + String(@b) + String(@@c) + String($d)
93
+ | | | | | | | | | | |
94
+ | | | | | | | | | | 3
95
+ | | | | | | | | | "3"
96
+ | | | | | | | | "0123"
97
+ | | | | | | | 2
98
+ | | | | | | "2"
99
+ | | | | | "012"
100
+ | | | | 1
101
+ | | | "1"
102
+ | | "01"
103
+ | 0
104
+ "0"
105
+ END
106
+ String(a) + String(@b) + String(@@c) + String($d)
107
+ }
108
+
109
+
110
+ assert_equal <<END.chomp, assertion_message {
111
+ "0".class == "3".to_i.times.map {|i| i + 1 }.class
112
+ | | | | | |
113
+ | | | | | Array
114
+ | | | | [1, 2, 3]
115
+ | | | #<Enumerator: 3:times>
116
+ | | 3
117
+ | false
118
+ String
119
+ END
120
+ "0".class == "3".to_i.times.map {|i| i + 1 }.class
121
+ }
122
+
123
+
124
+ assert_equal '', assertion_message {
125
+ false
126
+ }
127
+
128
+
129
+ assert_equal <<END.chomp,
130
+ assertion_message { "0".class }
131
+ |
132
+ String
133
+ END
134
+ assertion_message { "0".class }
135
+
136
+
137
+ assert_equal <<END.chomp, assertion_message {
138
+ Set.new == Set.new([0])
139
+ | | | | |
140
+ | | | | #<Set: {0}>
141
+ | | | Set
142
+ | | false
143
+ | #<Set: {}>
144
+ Set
145
+ END
146
+ Set.new == Set.new([0])
147
+ }
148
+ end
149
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: power_assert
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kazuki Tsujimoto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pattern-match
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: test-unit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Power Assert for Ruby
56
+ email:
57
+ - kazuki@callcc.net
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files:
61
+ - README.rdoc
62
+ files:
63
+ - ".gitignore"
64
+ - ".travis.yml"
65
+ - BSDL
66
+ - COPYING
67
+ - Gemfile
68
+ - README.rdoc
69
+ - Rakefile
70
+ - lib/power_assert.rb
71
+ - lib/power_assert/version.rb
72
+ - power_assert.gemspec
73
+ - test/test_power_assert.rb
74
+ homepage: https://github.com/k-tsj/power_assert
75
+ licenses: []
76
+ metadata: {}
77
+ post_install_message:
78
+ rdoc_options:
79
+ - "--main"
80
+ - README.rdoc
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.2.0
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Power Assert for Ruby
99
+ test_files: []