tunit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5769b36f6ff1b870f97abe003b76ec180c387e17
4
+ data.tar.gz: 6c35816f53a6e5e5b3e1f310482338e7f263ff79
5
+ SHA512:
6
+ metadata.gz: 9aeb067328c6d07e694215c0b77794a78645e4e49f71a806e9d13a0713be5b300f0585472fa893d410a6133862ba5724da8bac2f1116358bd9fff171567d37d1
7
+ data.tar.gz: 7b6754bb52f757ccfe7d1a2bb344f7fee592d2a29da47dbe896a8113b6e21a028380c050ea4fb7da851914946c6367111fcaa45abd83e964d5b11f14c93a73c4
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tunit.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Teo Ljungberg
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,113 @@
1
+ # Tunit
2
+
3
+ `tunit` is my take on building a testing framework, it's heavily influenced by
4
+ [minitest](https://github.com/seattlerb/minitest).
5
+
6
+
7
+ _NOTE_ This is very unstable and is just a playground for my ideas.
8
+
9
+ ## Credit
10
+ Since this is heavily influenced by
11
+ [Ryan Davis](https://twitter.com/the_zenspider)' minitest there are a lot of
12
+ similarities between the two frameworks.
13
+
14
+ I wanted to see how much code and effort are needed to build a testing
15
+ framework of my own, while looking at the learnings of minitest.
16
+
17
+ ## Usage
18
+ ### Unit
19
+
20
+ I personally _love_ TDD frameworks like minitest, so I tried to mimic their
21
+ behaviour and patterns as close as I possibly could. As with minitest, this is
22
+ just plain ruby.
23
+
24
+ ```ruby
25
+ class BlahTest < Tunit::Test
26
+ def setup
27
+ self.blah = Blah.new
28
+ end
29
+ attr_accessor :blah
30
+
31
+ def test_the_answer_to_everything
32
+ assert_equal 42, blah.the_ultimate_answer
33
+ end
34
+
35
+ def test_packing_list
36
+ assert_includes blah.packing_list, "towel"
37
+ end
38
+
39
+ def test_that_will_be_skipped
40
+ skip "test this later"
41
+ end
42
+ end
43
+ ```
44
+
45
+ What's important to me is that `BlahTest` is just a simple subclass, and
46
+ `test_the_answer_to_everything` is a simple method. Assertions and
47
+ lazily-loaded variables are just methods, everything is just a simple method
48
+ definition away.
49
+
50
+ I'm a strong believer in that you should only mock and stub things so you can
51
+ assert on something else. That's why a `test`-method must have assertions in
52
+ `tunit`
53
+
54
+ ```ruby
55
+ class EmptyTest < Tunit::Test
56
+ def test_im_going_to_fail
57
+ end
58
+
59
+ def test_so_will_i
60
+ 1 + 1 == 2
61
+ end
62
+ end
63
+ ```
64
+
65
+ ### Spec
66
+ There is also a small Spec DSL that follows along with tunit
67
+
68
+ ```ruby
69
+ require 'tunit/autorun'
70
+
71
+ Example = Class.new
72
+
73
+ describe Example do
74
+ describe 'passing tests' do
75
+ it 'even' do
76
+ assert 2.even?
77
+ end
78
+
79
+ it 'passed once more' do
80
+ assert_includes [1, 2], 2
81
+ end
82
+ end
83
+
84
+ describe 'failing tests' do
85
+ it 'fails on empty tests' do
86
+ end
87
+
88
+ it 'fails hard' do
89
+ refute 2.even?
90
+ end
91
+ end
92
+
93
+ describe 'skipps' do
94
+ it 'skippedy skip' do
95
+ skip
96
+ end
97
+
98
+ it 'skips with a message' do
99
+ skip 'here!'
100
+ end
101
+ end
102
+ end
103
+ ```
104
+
105
+ That's it, no magic let's or subjects. Just `it` and `describe` blocks
106
+
107
+ ## Contributing
108
+
109
+ 1. Fork it ( http://github.com/teoljungberg/tunit/fork )
110
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
111
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
112
+ 4. Push to the branch (`git push origin my-new-feature`)
113
+ 5. Create new Pull Request
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ ENV["RUBYOPT"] = "-w"
6
+ t.pattern = "test/**/*_test.rb"
7
+ t.libs << "test"
8
+ end
9
+ task :default => :test
@@ -0,0 +1,35 @@
1
+ $:<< File.join(File.dirname(__FILE__), 'lib')
2
+ require 'tunit/autorun'
3
+
4
+ Example = Class.new
5
+
6
+ describe Example do
7
+ describe 'passing tests' do
8
+ it 'even' do
9
+ assert 2.even?
10
+ end
11
+
12
+ it 'passed once more' do
13
+ assert_includes [1, 2], 2
14
+ end
15
+ end
16
+
17
+ describe 'failing tests' do
18
+ it 'fails on empty tests' do
19
+ end
20
+
21
+ it 'fails hard' do
22
+ refute 2.even?
23
+ end
24
+ end
25
+
26
+ describe 'skipps' do
27
+ it 'skippedy skip' do
28
+ skip
29
+ end
30
+
31
+ it 'skips with a message' do
32
+ skip 'here!'
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ $:<< File.join(File.dirname(__FILE__), 'lib')
2
+ require 'tunit/autorun'
3
+
4
+ class ExampleTest < Tunit::Test
5
+ def test_pass
6
+ assert 2.even?
7
+ end
8
+
9
+ def test_pass_one_more
10
+ assert_includes [1, 2], 2
11
+ end
12
+
13
+ def test_empty
14
+ end
15
+
16
+ def test_skip
17
+ skip
18
+ end
19
+
20
+ def test_skip_with_message
21
+ skip 'here!'
22
+ end
23
+ end
@@ -0,0 +1,83 @@
1
+ require "tunit/compound_reporter"
2
+ require "tunit/summary_reporter"
3
+ require "tunit/progress_reporter"
4
+ require "tunit/test"
5
+ require "tunit/version"
6
+
7
+ require 'optparse'
8
+
9
+ module Tunit
10
+ meta_klass = (class << self; self; end)
11
+ meta_klass.send :attr_accessor, :reporter
12
+
13
+ # Let io be override-able in tests
14
+ meta_klass.send :attr_accessor, :io
15
+ self.io = $stdout
16
+
17
+ # Make sure that autorun is loaded after each test class has been loaded
18
+ meta_klass.send :attr_accessor, :installed_at_exit
19
+ self.installed_at_exit ||= false
20
+
21
+ def self.autorun
22
+ at_exit {
23
+ next if $! and not ($!.kind_of? SystemExit and $!.success?)
24
+
25
+ exit_code = nil
26
+
27
+ at_exit {
28
+ exit exit_code || false
29
+ }
30
+
31
+ exit_code = Tunit.run ARGV
32
+ } unless self.installed_at_exit
33
+ self.installed_at_exit = true
34
+ end
35
+
36
+ def self.run args = []
37
+ options = process_args! args
38
+
39
+ self.reporter = CompoundReporter.new
40
+ reporter << SummaryReporter.new(options[:io], options)
41
+ reporter << ProgressReporter.new(options[:io], options)
42
+
43
+ reporter.start
44
+ dispatch! reporter, options
45
+ reporter.report
46
+
47
+ reporter.passed?
48
+ end
49
+
50
+ private
51
+
52
+ def self.dispatch! reporter, options
53
+ Runnable.runnables.each do |runnable|
54
+ runnable.run reporter, options
55
+ end
56
+ end
57
+
58
+ def self.process_args! args = []
59
+ options = { io: io }
60
+
61
+ OptionParser.new do |opts|
62
+ opts.banner = "Tunit options:"
63
+ opts.version = Tunit::VERSION
64
+
65
+ opts.on "-h", "--help", "Display this help." do
66
+ puts opts
67
+ exit
68
+ end
69
+
70
+ opts.on "-n", "--name PATTERN", "Filter run on /pattern/ or string." do |pattern|
71
+ options[:filter] = pattern
72
+ end
73
+
74
+ opts.on "-v", "--verbose", "Verbose. Show progress processing files." do
75
+ options[:verbose] = true
76
+ end
77
+
78
+ opts.parse! args
79
+ end
80
+
81
+ options
82
+ end
83
+ end
@@ -0,0 +1,43 @@
1
+ module Tunit
2
+ class Assertion < Exception
3
+ def error
4
+ self
5
+ end
6
+
7
+ def location
8
+ last_before_assertion = ""
9
+ self.backtrace.reverse_each do |line|
10
+ break if line =~ /in .(assert|refute|pass|raise)/
11
+ last_before_assertion = line
12
+ end
13
+ last_before_assertion.sub(/:in .*$/, "")
14
+ end
15
+
16
+ def result_code
17
+ result_label[0, 1]
18
+ end
19
+
20
+ def result_label
21
+ "Failure"
22
+ end
23
+ end
24
+
25
+ class Empty < Assertion
26
+ # Where was the empty test
27
+ attr_accessor :location
28
+
29
+ def result_code
30
+ "_"
31
+ end
32
+
33
+ def result_label
34
+ "Empty"
35
+ end
36
+ end
37
+
38
+ class Skip < Assertion
39
+ def result_label
40
+ "Skipped"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,68 @@
1
+ require 'tunit/assertion_errors'
2
+
3
+ module Tunit
4
+ module Assertions
5
+ def skip msg = nil, bt = caller
6
+ method_responsible = bt[0][/`.*'/][1..-2]
7
+ msg ||= "Skipped '#{method_responsible}'"
8
+ fail ::Tunit::Skip, msg, bt
9
+ end
10
+
11
+ def assert test, msg = nil
12
+ msg ||= "Failed assertion, no message given."
13
+ self.assertions += 1
14
+ unless test
15
+ msg = msg.call if Proc === msg
16
+ fail ::Tunit::Assertion, msg
17
+ end
18
+ true
19
+ end
20
+
21
+ def assert_equal exp, act, msg = nil
22
+ msg ||= "Failed assertion, no message given."
23
+ assert exp == act, msg
24
+ end
25
+
26
+ def assert_includes collection, obj, msg = nil
27
+ msg ||= "Expected #{collection.inspect} to include #{obj}"
28
+ assert_respond_to collection, :include?
29
+ assert collection.include?(obj), msg
30
+ end
31
+
32
+ def assert_respond_to obj, meth, msg = nil
33
+ msg ||= "Expected #{obj.inspect} (#{obj.class}) to respond to ##{meth}"
34
+ assert obj.respond_to?(meth), msg
35
+ end
36
+
37
+ def assert_instance_of klass, obj, msg = nil
38
+ msg ||= "Expected #{obj.inspect} to be an instance of #{klass}, not #{obj.class}"
39
+ assert obj.instance_of?(klass), msg
40
+ end
41
+
42
+ def refute test, msg = nil
43
+ msg ||= "Failed assertion, no message given."
44
+ ! assert !test, msg
45
+ end
46
+
47
+ def refute_equal exp, act, msg = nil
48
+ msg ||= "Failed assertion, no message given."
49
+ refute exp == act, msg
50
+ end
51
+
52
+ def refute_includes collection, obj, msg = nil
53
+ msg ||= "Expected #{collection.inspect} to not include #{obj}"
54
+ assert_respond_to collection, :include?
55
+ refute collection.include?(obj), msg
56
+ end
57
+
58
+ def refute_respond_to obj, meth, msg = nil
59
+ msg ||= "Expected #{obj.inspect} (#{obj.class}) to not respond to #{meth}"
60
+ refute obj.respond_to?(meth), msg
61
+ end
62
+
63
+ def refute_instance_of klass, obj, msg = nil
64
+ msg ||= "Expected #{obj.inspect} not to be an instance of #{klass}"
65
+ refute obj.instance_of?(klass), msg
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,8 @@
1
+ require "tunit/test"
2
+ require "tunit/spec"
3
+ require "tunit/compound_reporter"
4
+ require "tunit/summary_reporter"
5
+ require "tunit/progress_reporter"
6
+ require "tunit"
7
+
8
+ Tunit.autorun