pangel-testy 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,296 @@
1
+ NAME
2
+ testy.rb
3
+
4
+ DESCRIPTION
5
+ a minimalist BDD testing framework for ruby that's mad at the world and
6
+ plans to kick its ass by ruthlessly removing lines of testing framework
7
+ code
8
+
9
+ SYNOPSIS
10
+ Testy.testing 'your code' do
11
+ test 'some behaviour' do |t|
12
+ ultimate = Ultimate.new
13
+ t.check :name, :expect => 42, :actual => ultimate.answer
14
+ end
15
+ end
16
+
17
+ GIT
18
+ open http://github.com/ahoward/testy/tree/master
19
+ git clone git://github.com/ahoward/testy.git
20
+
21
+ PRINCIPLES AND GOALS
22
+ . it.should.not.merely.be.a.unit.testing.with.a.clever.dsl
23
+
24
+ . testing should not require learning a framework. ruby is a great
25
+ framework so testy uses it instead, requiring programmers learn exactly 2
26
+ new method calls
27
+
28
+ . testing loc should not dwarf those of the application
29
+
30
+ . testing framework loc should not dwarf those of the application
31
+
32
+ . testing frameworks should *never* alter ruby built-ins nor add methods to
33
+ Object, Kernel, .et al
34
+
35
+ . the output of tests should be machine parsable for reporting and ci tools
36
+ to easily integrate with
37
+
38
+ . the output of tests should be beautiful so that humans can read it
39
+
40
+ . the shape of the test file should not insult the programmer so that tests
41
+ can double as sample code
42
+
43
+ . the testing framework should never alter exception semantics
44
+
45
+ . hi-jacking at_exit sucks ass
46
+
47
+ . the exit status of running a test suite should indicate the degree of its
48
+ failure state (testy returns the percent of failed tests using a non-zero
49
+ exit status)
50
+
51
+ . sample code should easily be able to double as a test suite, including
52
+ its output
53
+
54
+ . testing should improve your code and help your users, not make you want to
55
+ kill yourself
56
+
57
+ . using a format that aligns in terminal is sanity saving when comparing
58
+ output
59
+
60
+ . testing frameworks should provide as few shortcuts for making brittle
61
+ tightly coupled tests as possible
62
+
63
+ . test suites should be able to be created, manipulated, have their output
64
+ streamed to different ports, and even tested themselves - they should be
65
+ plain ol objects under the hood
66
+
67
+ SAMPLES
68
+
69
+ <========< samples/a.rb >========>
70
+
71
+ ~ > cat samples/a.rb
72
+
73
+ # simple use of testy involves simply writing code, and recording the result
74
+ # you expect against the actual result
75
+ #
76
+ # notice that the output is very pretty and that the exitstatus is 0 when all
77
+ # tests pass
78
+ #
79
+ require 'testy'
80
+
81
+ Testy.testing 'the kick-ass-ed-ness of testy' do
82
+
83
+ test 'the ultimate answer to life' do |result|
84
+ list = []
85
+
86
+ list << 42
87
+ result.check :a, :expect => 42, :actual => list.first
88
+
89
+ list << 42.0
90
+ result.check :b, 42.0, list.last
91
+ end
92
+
93
+ end
94
+
95
+ ~ > ruby samples/a.rb #=> exitstatus=0
96
+
97
+ ---
98
+ the kick-ass-ed-ness of testy:
99
+ the ultimate answer to life:
100
+ success:
101
+ a: 42
102
+ b: 42.0
103
+
104
+
105
+ <========< samples/b.rb >========>
106
+
107
+ ~ > cat samples/b.rb
108
+
109
+ # testy will handle unexpected results and exceptions thrown in your code in
110
+ # exactly the same way - by reporting on them in a beautiful fashion and
111
+ # continuing to run other tests. notice, however, that an unexpected result
112
+ # or raised exception will cause a non-zero exitstatus (the percent of tests
113
+ # that failed) for the suite as a whole. also note that previously
114
+ # accumulated expect/actual pairs are still reported on in the error report.
115
+ #
116
+ require 'testy'
117
+
118
+ Testy.testing 'the exception handling of testy' do
119
+
120
+ test 'raising an exception' do |result|
121
+ list = []
122
+
123
+ list << 42
124
+ result.check :a, :expect => 42, :actual => list.first
125
+
126
+ list.method_that_does_not_exist
127
+ end
128
+
129
+ test 'returning unexpected results' do |result|
130
+ result.check 'a', 42, 42
131
+ result.check :b, :expect => 'forty-two', :actual => 42.0
132
+ end
133
+
134
+ end
135
+
136
+ ~ > ruby samples/b.rb #=> exitstatus=100
137
+
138
+ ---
139
+ the exception handling of testy:
140
+ raising an exception:
141
+ failure:
142
+ error:
143
+ class: NoMethodError
144
+ message: undefined method `method_that_does_not_exist' for [42]:Array
145
+ backtrace:
146
+ - samples/b.rb:18:in `call'
147
+ - ./lib/testy.rb:130
148
+ - ./lib/testy.rb:113:in `instance_eval'
149
+ - ./lib/testy.rb:113
150
+ - /home/adri/.rvm/gems/ruby-1.8.7-p249/gems/orderedhash-0.0.6/lib/orderedhash.rb:65:in `each'
151
+ - /home/adri/.rvm/gems/ruby-1.8.7-p249/gems/orderedhash-0.0.6/lib/orderedhash.rb:65:in `each'
152
+ - ./lib/testy.rb:108
153
+ - ./lib/testy.rb:78:in `call'
154
+ - ./lib/testy.rb:78:in `context'
155
+ - ./lib/testy.rb:102:in `run'
156
+ - ./lib/testy.rb:167:in `testing'
157
+ - samples/b.rb:10
158
+ expect:
159
+ a: 42
160
+ actual:
161
+ a: 42
162
+ returning unexpected results:
163
+ failure:
164
+ expect:
165
+ a: 42
166
+ b: forty-two
167
+ actual:
168
+ a: 42
169
+ b: 42.0
170
+
171
+
172
+ <========< samples/c.rb >========>
173
+
174
+ ~ > cat samples/c.rb
175
+
176
+ # in some cases you may not even want to make test assertions and simply
177
+ # provide example code which should run without error, with testy it's not
178
+ # only easy to do this but the commanline supports --list to see which samples
179
+ # can be run and running a single or multiple tests based on name or pattern.
180
+ # notice that, when no assertions are made using 'result.check' the output of
181
+ # the test becomes the expected *and* actual and is therefore shown in the
182
+ # output as yaml. of course, if your samples have errors they are reported in
183
+ # the normal fashion and the tests will fail.
184
+ #
185
+ #
186
+ require 'testy'
187
+
188
+ Testy.testing 'some samplz for you' do
189
+ test 'foo sample' do
190
+ list = 1,2
191
+ list.last + list.first
192
+ end
193
+
194
+ test 'bar sample' do
195
+ list = 1,2
196
+ list.shift * list.pop
197
+ end
198
+
199
+ test 'foobar sample' do
200
+ list = 1,2
201
+ eval(list.reverse.join) * 2
202
+ end
203
+ end
204
+
205
+ # here are some examples of using the command line arguments on the above test
206
+ #
207
+ # cfp:~/src/git/testy > ruby samples/c.rb --list
208
+ # ---
209
+ # - foo sample
210
+ # - bar sample
211
+ # - foobar sample
212
+ #
213
+ # cfp:~/src/git/testy > ruby samples/c.rb foobar
214
+ # ---
215
+ # some samplz for you:
216
+ # foobar sample:
217
+ # success: 42
218
+ #
219
+ # cfp:~/src/git/testy > ruby samples/c.rb foo
220
+ # ---
221
+ # some samplz for you:
222
+ # foo sample:
223
+ # success: 3
224
+ # foobar sample:
225
+ # success: 42
226
+ #
227
+ # cfp:~/src/git/testy > ruby samples/c.rb bar
228
+ # ---
229
+ # some samplz for you:
230
+ # bar sample:
231
+ # success: 2
232
+
233
+ ~ > ruby samples/c.rb #=> exitstatus=0
234
+
235
+ ---
236
+ some samplz for you:
237
+ foo sample:
238
+ success: 3
239
+ bar sample:
240
+ success: 2
241
+ foobar sample:
242
+ success: 42
243
+
244
+
245
+ <========< samples/d.rb >========>
246
+
247
+ ~ > cat samples/d.rb
248
+
249
+ # of course testy includes smartly inherited contexts and context sensitive
250
+ # setup and teardown methods which stack as well.
251
+ #
252
+ require 'testy'
253
+
254
+ Testy.testing 'your bitchin lib' do
255
+ context 'A' do
256
+ setup{ @list = [40] }
257
+
258
+ test 'foo' do
259
+ @list << 2
260
+ @list.first + @list.last
261
+ end
262
+
263
+ test 'bar' do |t|
264
+ t.check :list, @list, [40]
265
+ end
266
+
267
+ context 'B' do
268
+ setup{ @list << 2 }
269
+ test(:bar){ @list.join.delete('0') }
270
+ end
271
+ end
272
+ end
273
+
274
+
275
+ # the context name is applied to the test name, so you can selectively run
276
+ # groups of tests from the command line
277
+ #
278
+ # cfp:~/src/git/testy > ruby -I lib samples/d.rb 'A - B'
279
+ # ---
280
+ # your bitchin lib:
281
+ # A - B - bar:
282
+ # success: "42"
283
+
284
+ ~ > ruby samples/d.rb #=> exitstatus=0
285
+
286
+ ---
287
+ your bitchin lib:
288
+ A - foo:
289
+ success: 42
290
+ A - bar:
291
+ success:
292
+ list:
293
+ - 40
294
+ A - B - bar:
295
+ success: "42"
296
+
@@ -0,0 +1,68 @@
1
+ NAME
2
+ testy.rb
3
+
4
+ DESCRIPTION
5
+ a minimalist BDD testing framework for ruby that's mad at the world and
6
+ plans to kick its ass by ruthlessly removing lines of testing framework
7
+ code
8
+
9
+ SYNOPSIS
10
+ Testy.testing 'your code' do
11
+ test 'some behaviour' do |t|
12
+ ultimate = Ultimate.new
13
+ t.check :name, :expect => 42, :actual => ultimate.answer
14
+ end
15
+ end
16
+
17
+ GIT
18
+ open http://github.com/ahoward/testy/tree/master
19
+ git clone git://github.com/ahoward/testy.git
20
+
21
+ PRINCIPLES AND GOALS
22
+ . it.should.not.merely.be.a.unit.testing.with.a.clever.dsl
23
+
24
+ . testing should not require learning a framework. ruby is a great
25
+ framework so testy uses it instead, requiring programmers learn exactly 2
26
+ new method calls
27
+
28
+ . testing loc should not dwarf those of the application
29
+
30
+ . testing framework loc should not dwarf those of the application
31
+
32
+ . testing frameworks should *never* alter ruby built-ins nor add methods to
33
+ Object, Kernel, .et al
34
+
35
+ . the output of tests should be machine parsable for reporting and ci tools
36
+ to easily integrate with
37
+
38
+ . the output of tests should be beautiful so that humans can read it
39
+
40
+ . the shape of the test file should not insult the programmer so that tests
41
+ can double as sample code
42
+
43
+ . the testing framework should never alter exception semantics
44
+
45
+ . hi-jacking at_exit sucks ass
46
+
47
+ . the exit status of running a test suite should indicate the degree of its
48
+ failure state (testy returns the percent of failed tests using a non-zero
49
+ exit status)
50
+
51
+ . sample code should easily be able to double as a test suite, including
52
+ its output
53
+
54
+ . testing should improve your code and help your users, not make you want to
55
+ kill yourself
56
+
57
+ . using a format that aligns in terminal is sanity saving when comparing
58
+ output
59
+
60
+ . testing frameworks should provide as few shortcuts for making brittle
61
+ tightly coupled tests as possible
62
+
63
+ . test suites should be able to be created, manipulated, have their output
64
+ streamed to different ports, and even tested themselves - they should be
65
+ plain ol objects under the hood
66
+
67
+ SAMPLES
68
+ @samples
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "pangel-testy"
8
+ gem.version = "0.5.0"
9
+ gem.platform = Gem::Platform::RUBY
10
+ gem.summary = %Q{testy}
11
+ gem.description = %Q{a minimalist BDD testing framework for ruby that's mad at the world and plans to kick its ass by ruthlessly removing lines of testing framework code.}
12
+
13
+ gem.has_rdoc = true
14
+ gem.add_dependency 'orderedhash'
15
+
16
+ gem.email = "ara.t.howard@gmail.com"
17
+ gem.homepage = "http://github.com/pangel/testy"
18
+ gem.authors = ["Ara T. Howard"]
19
+
20
+ # gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
26
+ end
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ begin
36
+ require 'rcov/rcovtask'
37
+ Rcov::RcovTask.new do |test|
38
+ test.libs << 'test'
39
+ test.pattern = 'test/**/test_*.rb'
40
+ test.verbose = true
41
+ end
42
+ rescue LoadError
43
+ task :rcov do
44
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
45
+ end
46
+ end
47
+
48
+ task :test => :check_dependencies
49
+
50
+ task :default => :test
51
+
52
+ require 'rake/rdoctask'
53
+ Rake::RDocTask.new do |rdoc|
54
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
55
+
56
+ rdoc.rdoc_dir = 'rdoc'
57
+ rdoc.title = "mygem #{version}"
58
+ rdoc.rdoc_files.include('README*')
59
+ rdoc.rdoc_files.include('lib/**/*.rb')
60
+ end
data/TODO ADDED
@@ -0,0 +1,4 @@
1
+ . holy crap i need to re-factor before the code gets any fuglier!
2
+
3
+ . make sure contexts stack
4
+ . make sure contexts start out clean
@@ -0,0 +1,43 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+
5
+ $VERBOSE=nil
6
+
7
+ def indent s, n = 2
8
+ ws = ' ' * n
9
+ s.gsub %r/^/, ws
10
+ end
11
+
12
+ template = IO::read 'README.tmpl'
13
+
14
+ samples = ''
15
+ prompt = '~ > '
16
+
17
+ Dir['sample*/*'].sort.each do |sample|
18
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
19
+
20
+ cmd = "cat #{ sample }"
21
+ samples << indent(prompt + cmd, 2) << "\n\n"
22
+ samples << indent(`#{ cmd }`, 4) << "\n"
23
+
24
+ cmd = "ruby #{ sample }"
25
+ #samples << indent(prompt + cmd, 2) << "\n\n"
26
+
27
+ cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -Ilib #{ sample })'"
28
+ out = `#{ cmd } 2>&1`
29
+ #samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
30
+
31
+ exitstatus = " #=> exitstatus=#{ $?.exitstatus }"
32
+ cmd = "ruby #{ sample }"
33
+ samples << indent(prompt + cmd + exitstatus, 2) << "\n\n"
34
+ samples << indent(out, 4) << "\n"
35
+
36
+ #samples << indent("\n#{ prompt } #{ $?.exitstatus } ### exitstatus\n")
37
+ end
38
+
39
+ #samples.gsub! %r/^/, ' '
40
+
41
+ readme = template.gsub %r/^\s*@samples\s*$/, samples
42
+ open('README', 'w'){|fd| fd.write readme}
43
+ print readme
@@ -0,0 +1,173 @@
1
+ require 'rubygems'
2
+ require 'orderedhash'
3
+ require 'yaml'
4
+
5
+ module Testy
6
+ def Testy.version() '0.5.0' end
7
+
8
+ class Test
9
+ class BadResult < StandardError
10
+ end
11
+
12
+ class OrderedHash < ::OrderedHash
13
+ def with_string_keys
14
+ oh = self.class.new
15
+ each_pair{|key, val| oh[key.to_s] = val}
16
+ oh
17
+ end
18
+ end
19
+
20
+ class Result
21
+ attr_accessor :expect
22
+ attr_accessor :actual
23
+
24
+ def initialize
25
+ @expect = OrderedHash.new
26
+ @actual = OrderedHash.new
27
+ end
28
+
29
+ def check(name, *args)
30
+ options = args.last.is_a?(Hash) ? args.pop : {}
31
+ value = args.size==0 ? (options[:expect]||options['expect']) : args.shift
32
+ expect[name.to_s] = value
33
+ value = args.size==0 ? (options[:actual]||options['actual']) : args.shift
34
+ actual[name.to_s] = value
35
+ end
36
+
37
+ def ok?
38
+ expect === actual
39
+ end
40
+
41
+ def empty?
42
+ expect.empty? and actual.empty?
43
+ end
44
+ end
45
+
46
+ attr_accessor :name
47
+ attr_accessor :tests
48
+ attr_accessor :block
49
+ attr_accessor :contexts
50
+
51
+ def initialize(*args, &block)
52
+ options = args.last.is_a?(Hash) ? args.pop : {}
53
+ @name = args.first || options[:name] || options['name']
54
+ @tests = OrderedHash.new
55
+ @contexts = OrderedHash.new
56
+ @block = block
57
+ end
58
+
59
+ def test(name, &block)
60
+ name = [contexts.values.map{|context| context.name}, name].flatten.compact.join(' - ')
61
+ @tests[name] = [context, block]
62
+ end
63
+
64
+ def size
65
+ @tests.size
66
+ end
67
+
68
+ class Context
69
+ [:name, :block, :setup, :teardown].each{|name| attr_accessor name}
70
+ def initialize(name = nil, setup = lambda{}, teardown = lambda{}, &block)
71
+ @name, @setup, @teardown, @block = name, setup, teardown, block
72
+ end
73
+ end
74
+
75
+ def context(name = nil, &block)
76
+ if block
77
+ @contexts[name] = Context.new(name, &block)
78
+ block.call
79
+ else
80
+ @contexts.values.last
81
+ end
82
+ end
83
+
84
+ def setup(&block)
85
+ context.setup = block
86
+ end
87
+
88
+ def teardown(&block)
89
+ context.teardown = block
90
+ end
91
+
92
+ def list
93
+ instance_eval(&@block) if @block
94
+ tests.map{|kv| kv.first.to_s}
95
+ end
96
+
97
+ def run(*args)
98
+ options = args.last.is_a?(Hash) ? args.pop : {}
99
+ port = options[:port]||options['port']||STDOUT
100
+ selectors = options[:selectors]||options['selectors']||[]
101
+
102
+ context do
103
+ instance_eval(&@block) if @block
104
+
105
+ report = OrderedHash.new
106
+ failures = 0
107
+
108
+ tests.each do |name, context_and_block|
109
+ next unless selectors.any?{|selector| selector===name} unless selectors.empty?
110
+
111
+ result = Result.new
112
+
113
+ dup.instance_eval do
114
+ context, block = context_and_block
115
+
116
+ contexts = []
117
+ tests.each do |n, cb|
118
+ c, b = cb
119
+ break if context==c
120
+ contexts << c
121
+ end
122
+ contexts << context
123
+
124
+ report[name] =
125
+ begin
126
+ value =
127
+ begin
128
+ contexts.each{|context| instance_eval(&context.setup)}
129
+ (class << self;self;end).module_eval{ define_method(:call, &block) }
130
+ call(result)
131
+ ensure
132
+ contexts.reverse.each{|context| instance_eval(&context.teardown)}
133
+ end
134
+ raise BadResult, name unless result.ok?
135
+ value = result.actual.with_string_keys unless result.empty?
136
+ begin; value.to_yaml; rescue; value=true; end
137
+ {'success' => value}
138
+ rescue Object => e
139
+ failures += 1
140
+ failure = OrderedHash.new
141
+ unless e.is_a?(BadResult)
142
+ error = OrderedHash.new
143
+ error['class'] = e.class.name
144
+ error['message'] = e.message.to_s
145
+ error['backtrace'] = e.backtrace||[]
146
+ failure['error'] = error
147
+ end
148
+ failure['expect'] = result.expect.with_string_keys
149
+ failure['actual'] = result.actual.with_string_keys
150
+ {'failure' => failure}
151
+ end
152
+ end
153
+ end
154
+ port << {name => report}.to_yaml
155
+ failures
156
+ end
157
+ end
158
+ end
159
+
160
+ def Testy.testing(*args, &block)
161
+ list = ARGV.delete('--list')||ARGV.delete('-l')
162
+ selectors = ARGV.map{|arg| eval(arg =~ %r|^/.*| ? arg : "/^#{ Regexp.escape(arg) }/")}
163
+ test = Test.new(*args, &block)
164
+ if list
165
+ y test.list
166
+ else
167
+ failures = test.run(:selectors => selectors)
168
+ size = test.size
169
+ pct_failed = size==0 || failures==0 ? 0 : [ ((failures/size.to_f)*100).to_i, 1 ].max
170
+ exit(pct_failed)
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,52 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{pangel-testy}
8
+ s.version = "0.5.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ara T. Howard"]
12
+ s.date = %q{2010-03-17}
13
+ s.description = %q{a minimalist BDD testing framework for ruby that's mad at the world and plans to kick its ass by ruthlessly removing lines of testing framework code.}
14
+ s.email = %q{ara.t.howard@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README",
17
+ "README.tmpl",
18
+ "TODO"
19
+ ]
20
+ s.files = [
21
+ "README",
22
+ "README.tmpl",
23
+ "Rakefile",
24
+ "TODO",
25
+ "gen_readme.rb",
26
+ "lib/testy.rb",
27
+ "pangel-testy.gemspec",
28
+ "samples/a.rb",
29
+ "samples/b.rb",
30
+ "samples/c.rb",
31
+ "samples/d.rb"
32
+ ]
33
+ s.homepage = %q{http://github.com/pangel/testy}
34
+ s.rdoc_options = ["--charset=UTF-8"]
35
+ s.require_paths = ["lib"]
36
+ s.rubygems_version = %q{1.3.6}
37
+ s.summary = %q{testy}
38
+
39
+ if s.respond_to? :specification_version then
40
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<orderedhash>, [">= 0"])
45
+ else
46
+ s.add_dependency(%q<orderedhash>, [">= 0"])
47
+ end
48
+ else
49
+ s.add_dependency(%q<orderedhash>, [">= 0"])
50
+ end
51
+ end
52
+
@@ -0,0 +1,21 @@
1
+ # simple use of testy involves simply writing code, and recording the result
2
+ # you expect against the actual result
3
+ #
4
+ # notice that the output is very pretty and that the exitstatus is 0 when all
5
+ # tests pass
6
+ #
7
+ require 'testy'
8
+
9
+ Testy.testing 'the kick-ass-ed-ness of testy' do
10
+
11
+ test 'the ultimate answer to life' do |result|
12
+ list = []
13
+
14
+ list << 42
15
+ result.check :a, :expect => 42, :actual => list.first
16
+
17
+ list << 42.0
18
+ result.check :b, 42.0, list.last
19
+ end
20
+
21
+ end
@@ -0,0 +1,26 @@
1
+ # testy will handle unexpected results and exceptions thrown in your code in
2
+ # exactly the same way - by reporting on them in a beautiful fashion and
3
+ # continuing to run other tests. notice, however, that an unexpected result
4
+ # or raised exception will cause a non-zero exitstatus (the percent of tests
5
+ # that failed) for the suite as a whole. also note that previously
6
+ # accumulated expect/actual pairs are still reported on in the error report.
7
+ #
8
+ require 'testy'
9
+
10
+ Testy.testing 'the exception handling of testy' do
11
+
12
+ test 'raising an exception' do |result|
13
+ list = []
14
+
15
+ list << 42
16
+ result.check :a, :expect => 42, :actual => list.first
17
+
18
+ list.method_that_does_not_exist
19
+ end
20
+
21
+ test 'returning unexpected results' do |result|
22
+ result.check 'a', 42, 42
23
+ result.check :b, :expect => 'forty-two', :actual => 42.0
24
+ end
25
+
26
+ end
@@ -0,0 +1,56 @@
1
+ # in some cases you may not even want to make test assertions and simply
2
+ # provide example code which should run without error, with testy it's not
3
+ # only easy to do this but the commanline supports --list to see which samples
4
+ # can be run and running a single or multiple tests based on name or pattern.
5
+ # notice that, when no assertions are made using 'result.check' the output of
6
+ # the test becomes the expected *and* actual and is therefore shown in the
7
+ # output as yaml. of course, if your samples have errors they are reported in
8
+ # the normal fashion and the tests will fail.
9
+ #
10
+ #
11
+ require 'testy'
12
+
13
+ Testy.testing 'some samplz for you' do
14
+ test 'foo sample' do
15
+ list = 1,2
16
+ list.last + list.first
17
+ end
18
+
19
+ test 'bar sample' do
20
+ list = 1,2
21
+ list.shift * list.pop
22
+ end
23
+
24
+ test 'foobar sample' do
25
+ list = 1,2
26
+ eval(list.reverse.join) * 2
27
+ end
28
+ end
29
+
30
+ # here are some examples of using the command line arguments on the above test
31
+ #
32
+ # cfp:~/src/git/testy > ruby samples/c.rb --list
33
+ # ---
34
+ # - foo sample
35
+ # - bar sample
36
+ # - foobar sample
37
+ #
38
+ # cfp:~/src/git/testy > ruby samples/c.rb foobar
39
+ # ---
40
+ # some samplz for you:
41
+ # foobar sample:
42
+ # success: 42
43
+ #
44
+ # cfp:~/src/git/testy > ruby samples/c.rb foo
45
+ # ---
46
+ # some samplz for you:
47
+ # foo sample:
48
+ # success: 3
49
+ # foobar sample:
50
+ # success: 42
51
+ #
52
+ # cfp:~/src/git/testy > ruby samples/c.rb bar
53
+ # ---
54
+ # some samplz for you:
55
+ # bar sample:
56
+ # success: 2
@@ -0,0 +1,34 @@
1
+ # of course testy includes smartly inherited contexts and context sensitive
2
+ # setup and teardown methods which stack as well.
3
+ #
4
+ require 'testy'
5
+
6
+ Testy.testing 'your bitchin lib' do
7
+ context 'A' do
8
+ setup{ @list = [40] }
9
+
10
+ test 'foo' do
11
+ @list << 2
12
+ @list.first + @list.last
13
+ end
14
+
15
+ test 'bar' do |t|
16
+ t.check :list, @list, [40]
17
+ end
18
+
19
+ context 'B' do
20
+ setup{ @list << 2 }
21
+ test(:bar){ @list.join.delete('0') }
22
+ end
23
+ end
24
+ end
25
+
26
+
27
+ # the context name is applied to the test name, so you can selectively run
28
+ # groups of tests from the command line
29
+ #
30
+ # cfp:~/src/git/testy > ruby -I lib samples/d.rb 'A - B'
31
+ # ---
32
+ # your bitchin lib:
33
+ # A - B - bar:
34
+ # success: "42"
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pangel-testy
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
10
+ platform: ruby
11
+ authors:
12
+ - Ara T. Howard
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-17 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: orderedhash
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ description: a minimalist BDD testing framework for ruby that's mad at the world and plans to kick its ass by ruthlessly removing lines of testing framework code.
33
+ email: ara.t.howard@gmail.com
34
+ executables: []
35
+
36
+ extensions: []
37
+
38
+ extra_rdoc_files:
39
+ - README
40
+ - README.tmpl
41
+ - TODO
42
+ files:
43
+ - README
44
+ - README.tmpl
45
+ - Rakefile
46
+ - TODO
47
+ - gen_readme.rb
48
+ - lib/testy.rb
49
+ - pangel-testy.gemspec
50
+ - samples/a.rb
51
+ - samples/b.rb
52
+ - samples/c.rb
53
+ - samples/d.rb
54
+ has_rdoc: true
55
+ homepage: http://github.com/pangel/testy
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options:
60
+ - --charset=UTF-8
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.3.6
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: testy
84
+ test_files: []
85
+