totally-osom-tests 0.0.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 +15 -0
- data/README.md +28 -0
- data/bin/tots +3 -0
- data/lib/totally-osom-tests.rb +6 -0
- data/lib/tots.rb +20 -0
- data/lib/tots/asserts.rb +58 -0
- data/lib/tots/autorun.rb +16 -0
- data/lib/tots/cli.rb +62 -0
- data/lib/tots/matcher.rb +16 -0
- data/lib/tots/matcher/awesome.rb +42 -0
- data/lib/tots/printer.rb +126 -0
- data/lib/tots/printer/dots.rb +61 -0
- data/lib/tots/printer/emoji.rb +55 -0
- data/lib/tots/runner.rb +21 -0
- data/lib/tots/spec.rb +101 -0
- data/lib/tots/test.rb +31 -0
- data/lib/tots/watcher.rb +33 -0
- data/test/test_helper.rb +11 -0
- data/test/tots/assert_test.rb +113 -0
- data/test/tots/matcher/awesome_test.rb +80 -0
- data/test/tots/matcher_test.rb +7 -0
- data/test/tots/spec_test.rb +18 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OTI5YzFkNjE0MjkyMzVmMGMyYWYwYTViNjc0YzAyYzU1NjJiNmMwYw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZDQ1ODhjNTc5NGFiYzJlNTlkMTZlNDg0MmJhN2UyOTVhZThkZTQ2YQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NTQ5NTFlMTQ1Nzc3MDkyMTcyZTliZTY1YjY4NTI1YmZmNjdjMDRiNjRlY2E1
|
10
|
+
ODhiODNiOWUyZmZjOWQwYTI4YjFhNWUzMzI0YjZiNzNkYmMzOWZlODUzODIw
|
11
|
+
NjE0ZGVjYTY3NjBiZmI2NjJjOGU0MDJjNGNiNWJmNDU4OTI1NTc=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZTgzZTBlZGFmNzZhZjIxNTllNGVmNDY3ZTc5ZjVlZWU5NGZhMDVmZDRlNGI2
|
14
|
+
ZWVmN2Y3MjgzNDRiODc1YTY4MDFlODdlNzFiYzViMWYxMWQ3NzY0NDdhOWNm
|
15
|
+
OTU5NzAxNDczNWM5YjgxZmQ4YWRjODJhYjNmNTExOTczMzhmM2E=
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Totaly Osom Tests
|
2
|
+
|
3
|
+
__NOTE__: This is purely an excersize in awesomeness. If you need testing framework
|
4
|
+
for a real-life project, please use rspec/test_case/whatever.
|
5
|
+
|
6
|
+
## The Goal
|
7
|
+
|
8
|
+
1. Zero hassle TDD experiense
|
9
|
+
2. Simplified BDD specs syntax
|
10
|
+
3. Flexible internal structure
|
11
|
+
4. Easily extensible interface
|
12
|
+
|
13
|
+
|
14
|
+
## Credits
|
15
|
+
|
16
|
+
Most of the parts in this thing are "inspired" by the following projects:
|
17
|
+
|
18
|
+
1. [rspec](https://github.com/rspec/rspec)
|
19
|
+
2. [minitest](https://github.com/seattlerb/minitest)
|
20
|
+
3. [mocha](http://visionmedia.github.com/mocha)
|
21
|
+
4. [vows](http://vowsjs.org)
|
22
|
+
|
23
|
+
|
24
|
+
## Copyright
|
25
|
+
|
26
|
+
All the code in this repo is released under the terms of the MIT license
|
27
|
+
|
28
|
+
Copyright (C) 2013 Nikolay Nemshilov
|
data/bin/tots
ADDED
data/lib/tots.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# The main project's namespace
|
3
|
+
#
|
4
|
+
# Copyright (C) 2013 Nikolay Nemshilov
|
5
|
+
#
|
6
|
+
module TOTS
|
7
|
+
VERSION = '0.0.0'
|
8
|
+
end
|
9
|
+
|
10
|
+
require_relative './tots/asserts'
|
11
|
+
require_relative './tots/matcher'
|
12
|
+
require_relative './tots/matcher/awesome'
|
13
|
+
require_relative './tots/printer'
|
14
|
+
require_relative './tots/printer/dots'
|
15
|
+
require_relative './tots/printer/emoji'
|
16
|
+
require_relative './tots/watcher'
|
17
|
+
require_relative './tots/runner'
|
18
|
+
require_relative './tots/test'
|
19
|
+
require_relative './tots/spec'
|
20
|
+
|
data/lib/tots/asserts.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#
|
2
|
+
# The standard assertions
|
3
|
+
#
|
4
|
+
module TOTS::Asserts
|
5
|
+
def assert(smth, msg="No message given")
|
6
|
+
TOTS::Printer.asserting(msg)
|
7
|
+
|
8
|
+
unless smth
|
9
|
+
raise TOTS::Test::Fail, msg
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def assert_equal(v1, v2, msg=nil)
|
14
|
+
assert v1 == v2, msg || "#{v1.inspect} supposed to be equal to #{v2.inspect}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def assert_empty(v, msg=nil)
|
18
|
+
assert_respond_to v, :empty?
|
19
|
+
assert v.empty?, msg || "#{v.inspect} supposed to be empty"
|
20
|
+
end
|
21
|
+
|
22
|
+
def assert_respond_to(obj, method, msg=nil)
|
23
|
+
assert obj.respond_to?(method), msg || "#{obj.inspect} supposed to respond to the #{method} method"
|
24
|
+
end
|
25
|
+
|
26
|
+
def assert_nil(v, msg=nil)
|
27
|
+
assert v === nil, msg || "#{v.inspect} supposed to be nil"
|
28
|
+
end
|
29
|
+
|
30
|
+
def assert_includes(list, value, msg=nil)
|
31
|
+
assert_respond_to list, :include?
|
32
|
+
assert list.include?(value), msg || "#{list.inspect} supposed to include #{value.inspect}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def assert_match(obj, re, msg=nil)
|
36
|
+
assert_respond_to re, :=~
|
37
|
+
assert re =~ obj, msg || "#{obj.inspect} supposed to match #{re.inspect}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def assert_instance_of(obj, klass, msg=nil)
|
41
|
+
assert obj.instance_of?(klass), msg || "#{obj.inspect} supposed to be instance of #{klass}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def assert_raises(type, msg=nil, &block)
|
45
|
+
raise ArgumentError, "no block given" if !block_given?
|
46
|
+
|
47
|
+
begin
|
48
|
+
yield
|
49
|
+
|
50
|
+
assert false, msg || "expected to raise #{type}, but nothing was raised"
|
51
|
+
|
52
|
+
rescue Exception => e
|
53
|
+
if type && !(e.is_a?(type))
|
54
|
+
assert false, msg || "expected to raise #{type}, but got #{e.class} instead"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/tots/autorun.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#
|
2
|
+
# Just an auto-run hook
|
3
|
+
#
|
4
|
+
# Add this into your tests to be able to run them as plain ruby
|
5
|
+
#
|
6
|
+
# ```ruby
|
7
|
+
# require 'tots/autorun'
|
8
|
+
#
|
9
|
+
# describe Stuff do
|
10
|
+
# end
|
11
|
+
# ```
|
12
|
+
#
|
13
|
+
|
14
|
+
require_relative '../tots' unless defined?(TOTS)
|
15
|
+
|
16
|
+
at_exit { TOTS::Runner.start }
|
data/lib/tots/cli.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#
|
2
|
+
# A simple CLI for the `tots` cmd
|
3
|
+
#
|
4
|
+
require_relative '../tots/autorun'
|
5
|
+
|
6
|
+
args = {}
|
7
|
+
dirs = []
|
8
|
+
|
9
|
+
dirt = ARGV.dup
|
10
|
+
|
11
|
+
while arg = dirt.shift
|
12
|
+
case arg
|
13
|
+
when '-h', '--help'
|
14
|
+
puts <<-EOF.gsub(/(\A|\n)\s+\|/, "\\1")
|
15
|
+
|TOTS Runner Help:
|
16
|
+
|
|
17
|
+
| tots path[ path ...] [OPTSIONS]
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|OPTIONS:
|
21
|
+
|
|
22
|
+
| -h --help # show this help
|
23
|
+
| -w --watch # watch for changes in specified files/dires
|
24
|
+
| -r name --reporter name # specify the reporter
|
25
|
+
|
|
26
|
+
EOF
|
27
|
+
exit
|
28
|
+
|
29
|
+
when '-w', '--watch'
|
30
|
+
args['-w'] = true
|
31
|
+
|
32
|
+
when '-r', '--reporter'
|
33
|
+
args['-r'] = dirt.shift
|
34
|
+
|
35
|
+
else
|
36
|
+
# assuming it's a dir
|
37
|
+
dirs << arg
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# setting the reporter
|
42
|
+
TOTS::Printer.set args['-r'] if args['-r']
|
43
|
+
|
44
|
+
# figuring the paths
|
45
|
+
dirs << 'test' if dirs.empty?
|
46
|
+
|
47
|
+
dirs.map! do |name|
|
48
|
+
name = name.slice(0, name.size - 1) if name[name.size-1] == '/'
|
49
|
+
File.exists?(name) && File.directory?(name) ? "#{name}/**/*_test.rb" : name
|
50
|
+
end
|
51
|
+
|
52
|
+
# including the test files
|
53
|
+
$LOAD_PATH << "#{Dir.pwd}/test/" if File.exists?('test') && File.directory?('test')
|
54
|
+
|
55
|
+
require "test_helper" if File.exists?("test/test_helper.rb")
|
56
|
+
|
57
|
+
Dir[*dirs].each do |name|
|
58
|
+
require "#{Dir.pwd}/#{name}"
|
59
|
+
end
|
60
|
+
|
61
|
+
# watching for the changes
|
62
|
+
TOTS::Watcher.watch(dirs) if args.include?('-w')
|
data/lib/tots/matcher.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#
|
2
|
+
# Awesome matchers handler
|
3
|
+
#
|
4
|
+
# ```ruby
|
5
|
+
# describe TOTS::Matcher::Awesome do
|
6
|
+
# it "must provide awesome matchers" do
|
7
|
+
# 22.must == 22
|
8
|
+
# 22.must > 11
|
9
|
+
# 22.must =~ /2/
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
# ```
|
13
|
+
#
|
14
|
+
class TOTS::Matcher
|
15
|
+
def ==(value)
|
16
|
+
assert @object == value, "#{@object.inspect} supposed to be equal #{value.inspect}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def !=(value)
|
20
|
+
assert @object != value, "#{@object.inspect} supposed not to be equal #{value.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def =~(value)
|
24
|
+
assert value =~ @object, "#{@object.inspect} doesn't match #{value.inspect}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def >(value)
|
28
|
+
assert @object > value, "#{@object.inspect} supposed to be > than #{value.inspect}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def <(value)
|
32
|
+
assert @object < value, "#{@object.inspect} supposed to be < than #{value.inspect}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def >=(value)
|
36
|
+
assert @object >= value, "#{@object.inspect} supposed to be >= than #{value.inspect}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def <=(value)
|
40
|
+
assert @object <= value, "#{@object.inspect} supposed to be <= than #{value.inspect}"
|
41
|
+
end
|
42
|
+
end
|
data/lib/tots/printer.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#
|
4
|
+
# Generic printer
|
5
|
+
#
|
6
|
+
class TOTS::Printer
|
7
|
+
RED = '1'
|
8
|
+
GREEN = '2'
|
9
|
+
YELLOW = '3'
|
10
|
+
VIOLET = '4'
|
11
|
+
MARGETA = '5'
|
12
|
+
BLUE = '6'
|
13
|
+
GREY = '7;2'
|
14
|
+
|
15
|
+
def self.set(name)
|
16
|
+
@klass = const_get(name[0].upcase + name.slice(1, name.size - 1))
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.method_missing(*args)
|
20
|
+
@inst ||= (@klass || Dots).new
|
21
|
+
|
22
|
+
@inst.__send__(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@suites_count = 0
|
27
|
+
@tests_count = 0
|
28
|
+
@asserts_count = 0
|
29
|
+
@passed_count = 0
|
30
|
+
@fails_count = 0
|
31
|
+
@errors_count = 0
|
32
|
+
@skipped_count = 0
|
33
|
+
|
34
|
+
print "\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
def pass
|
38
|
+
raise "Should be implemented in a subclass"
|
39
|
+
end
|
40
|
+
|
41
|
+
def skip
|
42
|
+
raise "Should be implemented in a subclass"
|
43
|
+
end
|
44
|
+
|
45
|
+
def fail
|
46
|
+
raise "Should be implemented in a subclass"
|
47
|
+
end
|
48
|
+
|
49
|
+
def error
|
50
|
+
raise "Should be implemented in a subclass"
|
51
|
+
end
|
52
|
+
|
53
|
+
def summary
|
54
|
+
{
|
55
|
+
:Asserts => @asserts_count,
|
56
|
+
:Tests => @tests_count,
|
57
|
+
:Passed => @passed_count,
|
58
|
+
:Failed => @fails_count,
|
59
|
+
:Errored => @errors_count,
|
60
|
+
:Skipped => @skipped_count
|
61
|
+
|
62
|
+
}.map do |key, value|
|
63
|
+
"#{value} #{key}"
|
64
|
+
end.join(', ')
|
65
|
+
end
|
66
|
+
|
67
|
+
def waiting
|
68
|
+
raise "Should be implemented in a subclass"
|
69
|
+
end
|
70
|
+
|
71
|
+
def paint(string, color)
|
72
|
+
"\e[3#{color}m#{string}\e[0m"
|
73
|
+
end
|
74
|
+
|
75
|
+
def highlight(string, color)
|
76
|
+
"\e[4#{color}m#{string}\e[0m"
|
77
|
+
end
|
78
|
+
|
79
|
+
def testing(suite)
|
80
|
+
@suite = suite
|
81
|
+
|
82
|
+
@suites_count += 1
|
83
|
+
end
|
84
|
+
|
85
|
+
def running(test)
|
86
|
+
@tests_count += 1
|
87
|
+
end
|
88
|
+
|
89
|
+
def asserting(msg)
|
90
|
+
@asserts_count += 1
|
91
|
+
end
|
92
|
+
|
93
|
+
def passed
|
94
|
+
@passed_count += 1
|
95
|
+
pass
|
96
|
+
end
|
97
|
+
|
98
|
+
def failed(e)
|
99
|
+
@fails_count += 1
|
100
|
+
fail(e)
|
101
|
+
end
|
102
|
+
|
103
|
+
def errored(e)
|
104
|
+
@errors_count += 1
|
105
|
+
error(e)
|
106
|
+
end
|
107
|
+
|
108
|
+
def skipped
|
109
|
+
@skipped_count += 1
|
110
|
+
skip
|
111
|
+
end
|
112
|
+
|
113
|
+
def finish
|
114
|
+
summary
|
115
|
+
end
|
116
|
+
|
117
|
+
def watching(on)
|
118
|
+
if on
|
119
|
+
puts "\n"
|
120
|
+
@waiting = Thread.new { waiting }
|
121
|
+
else
|
122
|
+
@waiting.kill if @waiting
|
123
|
+
puts "\n"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#
|
4
|
+
# Your good old dots printer
|
5
|
+
#
|
6
|
+
class TOTS::Printer::Dots < TOTS::Printer
|
7
|
+
def pass
|
8
|
+
print paint(".", GREEN)
|
9
|
+
end
|
10
|
+
|
11
|
+
def skip
|
12
|
+
print paint('S', YELLOW)
|
13
|
+
end
|
14
|
+
|
15
|
+
def fail(e)
|
16
|
+
print paint('F', RED)
|
17
|
+
end
|
18
|
+
|
19
|
+
def error(e)
|
20
|
+
print paint('E', RED)
|
21
|
+
end
|
22
|
+
|
23
|
+
def summary
|
24
|
+
puts "\n\n"
|
25
|
+
|
26
|
+
if @fails_count == 0 && @errors_count == 0
|
27
|
+
print paint("✔ Osom! ", GREEN)
|
28
|
+
else
|
29
|
+
print paint("✖ Doh... ", RED)
|
30
|
+
end
|
31
|
+
|
32
|
+
puts paint(super, GREY)
|
33
|
+
end
|
34
|
+
|
35
|
+
CYLON_SIZE = 10
|
36
|
+
|
37
|
+
def waiting
|
38
|
+
puts "\n\n"
|
39
|
+
|
40
|
+
i = 0
|
41
|
+
|
42
|
+
while true
|
43
|
+
inc = 1 if i == 0
|
44
|
+
inc = -1 if i > (CYLON_SIZE - 3)
|
45
|
+
|
46
|
+
dots = Array.new(CYLON_SIZE).map{ |i| ' ' }
|
47
|
+
|
48
|
+
dots[i] = paint("■", RED)
|
49
|
+
dots[i - inc] = paint("■", RED + ";2") if i > 0
|
50
|
+
dots[i - 2 * inc] = paint("∙", RED + ";2") if i < CYLON_SIZE - 2 && i > 1
|
51
|
+
|
52
|
+
puts "\u001b[2A\r" + paint('Watching ', GREY) + dots.join('') + "\n\n"
|
53
|
+
|
54
|
+
sleep 0.07
|
55
|
+
|
56
|
+
i += inc
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#
|
4
|
+
# Emoji printer
|
5
|
+
#
|
6
|
+
class TOTS::Printer::Emoji < TOTS::Printer
|
7
|
+
GOOD = %w(🌵 🌴 🌲 🌳 🌿 🍀 🎄)
|
8
|
+
WAIT = %w(🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘)
|
9
|
+
|
10
|
+
def pass
|
11
|
+
print GOOD[rand(GOOD.size)] + " "
|
12
|
+
end
|
13
|
+
|
14
|
+
def skip
|
15
|
+
print '😴 '
|
16
|
+
end
|
17
|
+
|
18
|
+
def fail(e)
|
19
|
+
print '😡 '
|
20
|
+
end
|
21
|
+
|
22
|
+
def error(e)
|
23
|
+
print '💥 '
|
24
|
+
end
|
25
|
+
|
26
|
+
def summary
|
27
|
+
puts "\n\n"
|
28
|
+
|
29
|
+
if @fails_count == 0 && @errors_count == 0
|
30
|
+
print paint("😊 Happy! ", GREEN)
|
31
|
+
else
|
32
|
+
print paint("😱 Oh, no... ", RED)
|
33
|
+
end
|
34
|
+
|
35
|
+
puts paint(super, GREY)
|
36
|
+
end
|
37
|
+
|
38
|
+
CYLON_SIZE = 10
|
39
|
+
|
40
|
+
def waiting
|
41
|
+
puts "\n\n"
|
42
|
+
|
43
|
+
i = 0
|
44
|
+
|
45
|
+
while true
|
46
|
+
i = 0 if i > (WAIT.size - 1)
|
47
|
+
|
48
|
+
puts "\u001b[2A\r" + paint('Waiting ', GREY) + WAIT[i] + "\n\n"
|
49
|
+
|
50
|
+
sleep 0.08
|
51
|
+
|
52
|
+
i += 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/tots/runner.rb
ADDED
data/lib/tots/spec.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
#
|
2
|
+
# The spec unit
|
3
|
+
#
|
4
|
+
# Copyright (C) 2013 Nikolay Nemshilov
|
5
|
+
#
|
6
|
+
class TOTS::Spec
|
7
|
+
include TOTS::Asserts
|
8
|
+
|
9
|
+
# the tests stash
|
10
|
+
def self.tests
|
11
|
+
@tests ||= []
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.specs
|
15
|
+
@specs ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Sub-describe blocks catcher
|
20
|
+
#
|
21
|
+
def self.describe(*args, &block)
|
22
|
+
specs << Class.new(TOTS::Spec, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# alias for `describe`
|
27
|
+
#
|
28
|
+
def self.context(*args, &block)
|
29
|
+
describe(*args, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# The basic `it` thingy
|
34
|
+
#
|
35
|
+
# ```ruby
|
36
|
+
# describe Smth do
|
37
|
+
# it "must do stuff" do
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
# ```
|
41
|
+
#
|
42
|
+
def self.it(*args,&block)
|
43
|
+
if args.size == 0
|
44
|
+
self
|
45
|
+
else
|
46
|
+
tests << TOTS::Test.new(args + [block])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Quick, skip marking
|
52
|
+
#
|
53
|
+
# ```ruby
|
54
|
+
# describe Smth do
|
55
|
+
# it.skip "this test" do
|
56
|
+
# this_code.will_be(:skipped)
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
# ```
|
60
|
+
#
|
61
|
+
def self.skip(*args, &block)
|
62
|
+
it *args # skipping the block
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Runs the spec
|
67
|
+
#
|
68
|
+
def self.run
|
69
|
+
TOTS::Printer.testing self
|
70
|
+
|
71
|
+
suite = new
|
72
|
+
|
73
|
+
tests.each do |test|
|
74
|
+
TOTS::Printer.running test.name
|
75
|
+
|
76
|
+
begin
|
77
|
+
test.run(suite)
|
78
|
+
|
79
|
+
TOTS::Printer.passed
|
80
|
+
|
81
|
+
rescue TOTS::Test::Skip => e
|
82
|
+
TOTS::Printer.skipped
|
83
|
+
|
84
|
+
rescue TOTS::Test::Fail => e
|
85
|
+
TOTS::Printer.failed(e)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
specs.each(&:run)
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# the top-level describe
|
96
|
+
#
|
97
|
+
module Kernel
|
98
|
+
def describe(*args, &block)
|
99
|
+
TOTS::Runner << Class.new(TOTS::Spec, &block)
|
100
|
+
end
|
101
|
+
end
|
data/lib/tots/test.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#
|
2
|
+
# A single test case entity
|
3
|
+
#
|
4
|
+
class TOTS::Test
|
5
|
+
attr_accessor :name, :options, :block
|
6
|
+
|
7
|
+
class Skip < Exception; end
|
8
|
+
class Fail < Exception; end
|
9
|
+
|
10
|
+
def initialize(args)
|
11
|
+
@block = args.last.is_a?(Proc) ? args.pop : skip
|
12
|
+
@options = args.size > 1 && args.last.is_a?(Hash) ? args.pop : {}
|
13
|
+
@name = args[0] || 'no name given'
|
14
|
+
end
|
15
|
+
|
16
|
+
def skip
|
17
|
+
@block = Proc.new do
|
18
|
+
raise Skip
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(context)
|
23
|
+
test = self
|
24
|
+
|
25
|
+
context.instance_eval do
|
26
|
+
@test_options = test.options
|
27
|
+
instance_eval &test.block
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/lib/tots/watcher.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#
|
2
|
+
# File changes watcher
|
3
|
+
#
|
4
|
+
class TOTS::Watcher
|
5
|
+
|
6
|
+
def self.watch(paths)
|
7
|
+
@paths = paths
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.check
|
11
|
+
return if ! @paths
|
12
|
+
|
13
|
+
TOTS::Printer.watching(true)
|
14
|
+
|
15
|
+
setup; @watching = true if !@watching
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.setup
|
19
|
+
require 'rb-fsevent'
|
20
|
+
|
21
|
+
fsevent = FSEvent.new
|
22
|
+
fsevent.watch Dir.pwd do |directories|
|
23
|
+
TOTS::Printer.watching(false)
|
24
|
+
|
25
|
+
puts "Detected change inside: #{directories.inspect}\n"
|
26
|
+
|
27
|
+
TOTS::Runner.start
|
28
|
+
end
|
29
|
+
|
30
|
+
fsevent.run
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe TOTS::Spec do
|
4
|
+
|
5
|
+
describe "standard assertions" do
|
6
|
+
describe "assert" do
|
7
|
+
it "must pass with trues" do
|
8
|
+
assert true
|
9
|
+
end
|
10
|
+
|
11
|
+
it "must fail with false" do
|
12
|
+
assert_fails { assert(false) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "assert_equal" do
|
17
|
+
it "must pass with equal data" do
|
18
|
+
assert_equal 2, 2
|
19
|
+
end
|
20
|
+
|
21
|
+
it "must fail with different data" do
|
22
|
+
assert_fails { assert_equal(1,2) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "assert_empty" do
|
27
|
+
it "must pass correctly" do
|
28
|
+
assert_empty ''
|
29
|
+
end
|
30
|
+
|
31
|
+
it "must fail with a non-empty objects" do
|
32
|
+
assert_fails { assert_empty(' ') }
|
33
|
+
end
|
34
|
+
|
35
|
+
it "must fail with objects without the :empty? method" do
|
36
|
+
assert_fails { assert_empty(nil) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "assert_respond_to" do
|
41
|
+
it "must pass correctly" do
|
42
|
+
assert_respond_to '', :size
|
43
|
+
end
|
44
|
+
|
45
|
+
it "must fail when method is missing" do
|
46
|
+
assert_fails { assert_respond_to('', :non_existing_method) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "assert_nil" do
|
51
|
+
it "must pass correctly" do
|
52
|
+
assert_nil nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it "must fail with non nils" do
|
56
|
+
assert_fails { assert_nil(false) }
|
57
|
+
assert_fails { assert_nil('') }
|
58
|
+
assert_fails { assert_nil(0) }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "assert_includes" do
|
63
|
+
it "must pass correctly" do
|
64
|
+
assert_includes [1,2,3], 2
|
65
|
+
end
|
66
|
+
|
67
|
+
it "must fail correctly" do
|
68
|
+
assert_fails { assert_includes([1,2,3], 4) }
|
69
|
+
assert_fails { assert_includes(nil, 4) }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "assert_match" do
|
74
|
+
it "must pass correctly" do
|
75
|
+
assert_match "22", /2/
|
76
|
+
end
|
77
|
+
|
78
|
+
it "must fail correctly" do
|
79
|
+
assert_fails { assert_match("22", /3/) }
|
80
|
+
assert_fails { assert_match("22", nil) }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "assert_instance_of" do
|
85
|
+
it "must pass correctly" do
|
86
|
+
assert_instance_of '', String
|
87
|
+
end
|
88
|
+
|
89
|
+
it "must fail correctly" do
|
90
|
+
assert_fails { assert_instance_of('', Integer) }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "assert_raises" do
|
95
|
+
it "must pass when something raised" do
|
96
|
+
assert_raises(Exception) { raise Exception }
|
97
|
+
end
|
98
|
+
|
99
|
+
it "must fail when nothing raised" do
|
100
|
+
assert_fails do
|
101
|
+
assert_raises(Exception) { }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it "must fail when raised a different type of exception" do
|
106
|
+
assert_fails do
|
107
|
+
assert_raises(ArgumentError) { raise Exception }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe TOTS::Matcher do
|
4
|
+
|
5
|
+
describe "awesome matchers" do
|
6
|
+
describe "==" do
|
7
|
+
it "must assert properly" do
|
8
|
+
22.must == 22
|
9
|
+
end
|
10
|
+
|
11
|
+
it "must fail correctly" do
|
12
|
+
assert_fails { 22.must == 33 }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "!=" do
|
17
|
+
it "must assert correctly" do
|
18
|
+
22.must != 33
|
19
|
+
end
|
20
|
+
|
21
|
+
it "must fail correctly" do
|
22
|
+
assert_fails { 22.must != 22 }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "=~" do
|
27
|
+
it "must assert correctly" do
|
28
|
+
'22'.must =~ /2/
|
29
|
+
end
|
30
|
+
|
31
|
+
it "must fail correctly" do
|
32
|
+
assert_fails { '22'.must =~ /3/ }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ">" do
|
37
|
+
it "must assert properly" do
|
38
|
+
22.must > 11
|
39
|
+
end
|
40
|
+
|
41
|
+
it "must fail correctly" do
|
42
|
+
assert_fails { 22.must > 22 }
|
43
|
+
assert_fails { 22.must > 33 }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "<" do
|
48
|
+
it "must assert properly" do
|
49
|
+
22.must < 33
|
50
|
+
end
|
51
|
+
|
52
|
+
it "must fail correctly" do
|
53
|
+
assert_fails { 22.must < 22 }
|
54
|
+
assert_fails { 22.must < 11 }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe ">=" do
|
59
|
+
it "must assert properly" do
|
60
|
+
22.must >= 11
|
61
|
+
22.must >= 22
|
62
|
+
end
|
63
|
+
|
64
|
+
it "must fail correctly" do
|
65
|
+
assert_fails { 22.must >= 21 }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "<=" do
|
70
|
+
it "must assert properly" do
|
71
|
+
22.must <= 22
|
72
|
+
22.must <= 33
|
73
|
+
end
|
74
|
+
|
75
|
+
it "must fail correctly" do
|
76
|
+
assert_fails { 22.must <= 23 }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe TOTS::Spec do
|
4
|
+
|
5
|
+
it.skip "must be skipped" do
|
6
|
+
assert false, "this block should not be called"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "must allow to specify options", some: 'options' do
|
10
|
+
assert_equal @test_options, some: 'options'
|
11
|
+
end
|
12
|
+
|
13
|
+
context "sub-block" do
|
14
|
+
it "must be called too" do
|
15
|
+
assert true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: totally-osom-tests
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nikolay Nemshilov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: It's gonna be totally awesome!
|
14
|
+
email: nemshilov@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/totally-osom-tests.rb
|
20
|
+
- lib/tots/asserts.rb
|
21
|
+
- lib/tots/autorun.rb
|
22
|
+
- lib/tots/cli.rb
|
23
|
+
- lib/tots/matcher/awesome.rb
|
24
|
+
- lib/tots/matcher.rb
|
25
|
+
- lib/tots/printer/dots.rb
|
26
|
+
- lib/tots/printer/emoji.rb
|
27
|
+
- lib/tots/printer.rb
|
28
|
+
- lib/tots/runner.rb
|
29
|
+
- lib/tots/spec.rb
|
30
|
+
- lib/tots/test.rb
|
31
|
+
- lib/tots/watcher.rb
|
32
|
+
- lib/tots.rb
|
33
|
+
- test/test_helper.rb
|
34
|
+
- test/tots/assert_test.rb
|
35
|
+
- test/tots/matcher/awesome_test.rb
|
36
|
+
- test/tots/matcher_test.rb
|
37
|
+
- test/tots/spec_test.rb
|
38
|
+
- bin/tots
|
39
|
+
- README.md
|
40
|
+
homepage: http://github.com/MadRabbit/totally-osom-tests
|
41
|
+
licenses:
|
42
|
+
- MIT
|
43
|
+
metadata: {}
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 2.0.0
|
61
|
+
signing_key:
|
62
|
+
specification_version: 4
|
63
|
+
summary: Totally awesome testing framework for ruby
|
64
|
+
test_files: []
|