uspec 0.1.1 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +11 -0
- data/.travis.yml +10 -2
- data/README.markdown +39 -39
- data/lib/uspec.rb +7 -2
- data/lib/uspec/cli.rb +23 -7
- data/lib/uspec/dsl.rb +21 -5
- data/lib/uspec/result.rb +115 -0
- data/lib/uspec/stats.rb +8 -1
- data/lib/uspec/terminal.rb +47 -0
- data/lib/uspec/version.rb +1 -1
- data/uspec.gemspec +12 -4
- data/uspec/cli_spec.rb +4 -4
- data/uspec/result_spec.rb +40 -0
- data/uspec/uspec_spec.rb +8 -4
- metadata +40 -8
- data/lib/uspec/formatter.rb +0 -90
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65de448e566c6f625bd228e6581a0ee78bd8811a0189e04f4588d7474201e516
|
4
|
+
data.tar.gz: 62ba89fc56bdd1fb21cf2709ab8441ed0ad9cbe3f5426ce1719d8c36933161d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9353937b8b7e4b44ed2ea214fcb69ce1c0558d7774e10dedd4d071e20ad10f1fca8485e0063bacdf614d25389a9893439f4bafd0617347fd91649b85c9284d1
|
7
|
+
data.tar.gz: 87f381e5c1f7f715c28543f47531589ef8344266d648e729c9d6fb01d7f9bfb7a79a966b2437c7f76e8a7d995dc0d378563b819881cb8b46b92e0b5dbbccee00
|
data/.editorconfig
ADDED
data/.travis.yml
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
3
|
rvm:
|
4
|
-
- 2.
|
4
|
+
- 2.6.3
|
5
|
+
- 2.5.5
|
6
|
+
- 2.4.6
|
7
|
+
- 2.3.8
|
8
|
+
- 2.2.10
|
9
|
+
- 2.1.10
|
10
|
+
|
5
11
|
- 2.0.0
|
6
12
|
- 1.9.3
|
7
13
|
- 1.9.2
|
8
|
-
|
9
14
|
- jruby-19mode
|
10
15
|
- ruby-head
|
11
16
|
|
@@ -17,6 +22,9 @@ script: bundle exec uspec
|
|
17
22
|
|
18
23
|
matrix:
|
19
24
|
allow_failures:
|
25
|
+
- rvm: 2.0.0
|
26
|
+
- rvm: 1.9.3
|
27
|
+
- rvm: 1.9.2
|
20
28
|
- rvm: ruby-head
|
21
29
|
- rvm: jruby-19mode
|
22
30
|
|
data/README.markdown
CHANGED
@@ -11,21 +11,36 @@ Philosophy / Why Uspec?
|
|
11
11
|
|
12
12
|
> Uspec is just Ruby!
|
13
13
|
|
14
|
-
Unlike other testing frameworks there's no need for special matchers,
|
15
|
-
there can only be one assertion per test,
|
14
|
+
Unlike other testing frameworks there's no need for special matchers,
|
15
|
+
there can only be one assertion per test,
|
16
16
|
and you never have to worry that your tests lack assertions.
|
17
17
|
|
18
|
-
That's because when the `spec` block is evaluated the return value is used (in a very ruby-like way)
|
19
|
-
to determine the
|
18
|
+
That's because when the `spec` block is evaluated the return value is used (in a very ruby-like way)
|
19
|
+
to determine if the test has passed or failed. Standard Ruby comparisons are your friend!
|
20
20
|
No more digging around in your test framework's documentation to figure out what matcher you're supposed to use.
|
21
21
|
This also means *no monkey patching* core classes!
|
22
22
|
|
23
|
-
Uspec's output is in beautiful ansi technicolor,
|
23
|
+
Uspec's output is in beautiful ansi technicolor,
|
24
24
|
with red for failures, green for successes, and yellow for pending specs. Here's a screenshot:
|
25
25
|
|
26
26
|
![Screenshot!](http://i.imgur.com/M2F5YvO.png)
|
27
27
|
|
28
|
-
Uspec is tiny, painless, and easy to use. Download it and give it a
|
28
|
+
Uspec is tiny, painless, and easy to use. Download it and give it a try!
|
29
|
+
|
30
|
+
Example
|
31
|
+
-------
|
32
|
+
|
33
|
+
Uspec is **just Ruby**. The DSL is minimal - there's only one method to remember!
|
34
|
+
|
35
|
+
Writing a spec is easy:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
spec 'AwesomeMcCoolname.generate creates a cool name' do
|
39
|
+
AwesomeMcCoolname.generate.include? 'Cool'
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
That's it!
|
29
44
|
|
30
45
|
Installation
|
31
46
|
------------
|
@@ -38,7 +53,7 @@ And then execute:
|
|
38
53
|
|
39
54
|
$ bundle
|
40
55
|
|
41
|
-
Or install it
|
56
|
+
Or install it directly with:
|
42
57
|
|
43
58
|
$ gem install uspec
|
44
59
|
|
@@ -46,46 +61,31 @@ Or install it yourself as:
|
|
46
61
|
Quickstart
|
47
62
|
----------
|
48
63
|
|
49
|
-
0. Create a `spec` directory to keep your specs in.
|
64
|
+
0. Create a `spec` (or `uspec`) directory to keep your specs in.
|
50
65
|
1. Name your specs ending with `_spec.rb`.
|
51
|
-
2. Write some specs in Ruby using the `spec` method.
|
66
|
+
2. Write some specs in Ruby using the `spec` method (example above).
|
52
67
|
2. Use the included `uspec` executable to run your specs.
|
53
68
|
|
54
|
-
**Hint:** A lot of people also put `require_relative 'spec_helper'` in their tests for
|
69
|
+
**Hint:** A lot of people also put `require_relative 'spec_helper'` in their tests for shared code between tests.
|
55
70
|
|
56
|
-
Usage
|
57
|
-
|
71
|
+
Commandline Usage
|
72
|
+
-----------------
|
58
73
|
|
59
|
-
```
|
74
|
+
```
|
60
75
|
$ uspec --help
|
61
76
|
uspec - minimalistic ruby testing framework
|
62
77
|
usage: uspec [<file_or_path>...]
|
63
78
|
```
|
64
79
|
|
65
|
-
- Without arguments the `uspec` command will automatially look for `spec` directories and load any `*_spec.rb` files inside them.
|
80
|
+
- Without arguments the `uspec` command will automatially look for `spec` and `uspec` directories and load any `*_spec.rb` files inside them.
|
66
81
|
- You can also pass in arbitrary files and it will attempt to run them as specs.
|
67
|
-
- If you pass in directories `uspec` will
|
68
|
-
- Uspec will return
|
69
|
-
|
70
|
-
Syntax
|
71
|
-
------
|
72
|
-
|
73
|
-
Uspec is **just Ruby**. The DSL is minimal - there's only one method to remember!
|
74
|
-
|
75
|
-
Writing a spec is easy:
|
76
|
-
|
77
|
-
```ruby
|
78
|
-
spec 'AwesomeMcCoolname.generate creates a cool name' do
|
79
|
-
AwesomeMcCoolname.generate.include? 'Cool'
|
80
|
-
end
|
81
|
-
```
|
82
|
-
|
83
|
-
That's it!
|
82
|
+
- If you pass in directories `uspec` will scan for and run any specs inside them.
|
83
|
+
- Uspec will return the number of failures as its status code to the commandline, 0 if none.
|
84
84
|
|
85
85
|
Output
|
86
86
|
------
|
87
87
|
|
88
|
-
|
88
|
+
Wonder what Uspec looks like?
|
89
89
|
|
90
90
|
### Success
|
91
91
|
|
@@ -190,8 +190,8 @@ What if you want to test that an error has occured? Just use Ruby!
|
|
190
190
|
spec 'calling AwesomeMcCoolname.awesomeness without specifying the awesomeness level should explode' do
|
191
191
|
begin
|
192
192
|
AwesomeMcCoolname.awesomeness
|
193
|
-
rescue => error
|
194
|
-
error.
|
193
|
+
rescue ArgumentError => error
|
194
|
+
error.message.include?("Needs awesomeness level!") || raise
|
195
195
|
end
|
196
196
|
end
|
197
197
|
```
|
@@ -212,7 +212,7 @@ require 'uspec'
|
|
212
212
|
|
213
213
|
class MyFoo
|
214
214
|
extend Uspec::DSL
|
215
|
-
|
215
|
+
|
216
216
|
def assert
|
217
217
|
spec 'foo is valid' do
|
218
218
|
false
|
@@ -223,19 +223,19 @@ end
|
|
223
223
|
MyFoo.new.assert
|
224
224
|
```
|
225
225
|
|
226
|
-
If there are any specs that fail, your application will exit with
|
226
|
+
If there are any specs that fail, your application will exit with an error code equal to the number of failures.
|
227
227
|
|
228
228
|
```
|
229
229
|
$ ruby foo.rb
|
230
230
|
-- foo is valid: false
|
231
231
|
$ echo $?
|
232
|
-
|
232
|
+
1
|
233
233
|
```
|
234
234
|
|
235
235
|
Uspec is just Ruby
|
236
236
|
------------------
|
237
237
|
|
238
|
-
If for some reason you don't want to use the `uspec` command, you can `require 'uspec'` and `extend Uspec::DSL`.
|
238
|
+
If for some reason you don't want to use the `uspec` command, you can `require 'uspec'` and `extend Uspec::DSL`.
|
239
239
|
From there you can just run the file with ruby: `ruby my_test_spec.rb`
|
240
240
|
|
241
241
|
Contributing
|
@@ -250,4 +250,4 @@ Contributing
|
|
250
250
|
Author
|
251
251
|
------
|
252
252
|
|
253
|
-
> Anthony M. Cook 2013-
|
253
|
+
> Anthony M. Cook 2013-2019
|
data/lib/uspec.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require_relative 'uspec/version'
|
2
|
-
require_relative 'uspec/formatter'
|
3
2
|
require_relative 'uspec/dsl'
|
4
3
|
require_relative 'uspec/stats'
|
5
4
|
|
@@ -14,4 +13,10 @@ module Uspec
|
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
|
-
at_exit
|
16
|
+
at_exit do
|
17
|
+
failures = Uspec::Stats.exit_code
|
18
|
+
status = $!.respond_to?(:status) ? $!.status : 0
|
19
|
+
errors = $!.respond_to?(:cause) && $!.cause ? 1 : 0
|
20
|
+
code = [failures, status, errors].max
|
21
|
+
exit code
|
22
|
+
end
|
data/lib/uspec/cli.rb
CHANGED
@@ -4,7 +4,7 @@ require_relative '../uspec'
|
|
4
4
|
class Uspec::CLI
|
5
5
|
class << self
|
6
6
|
def usage
|
7
|
-
warn "uspec - minimalistic ruby testing framework"
|
7
|
+
warn "uspec v#{::Uspec::VERSION} - minimalistic ruby testing framework"
|
8
8
|
warn "usage: #{File.basename $0} [<file_or_path>...]"
|
9
9
|
end
|
10
10
|
|
@@ -14,7 +14,7 @@ class Uspec::CLI
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def invoke args
|
17
|
-
if (args & %w[-h --help -? /?]).empty? then
|
17
|
+
if (args & %w[-h --help -? /? -v --version]).empty? then
|
18
18
|
run_specs args
|
19
19
|
else
|
20
20
|
usage
|
@@ -44,6 +44,7 @@ class Uspec::CLI
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def run path
|
47
|
+
spec = nil
|
47
48
|
if path.directory? then
|
48
49
|
Pathname.glob(path.join('**', '**_spec.rb')).each do |spec|
|
49
50
|
run spec
|
@@ -54,11 +55,26 @@ class Uspec::CLI
|
|
54
55
|
else
|
55
56
|
warn "path not found: #{path}"
|
56
57
|
end
|
57
|
-
rescue
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
58
|
+
rescue Exception => error
|
59
|
+
|
60
|
+
error_file, error_line, _ = error.backtrace.first.split ?:
|
61
|
+
|
62
|
+
message = <<-MSG
|
63
|
+
#{error.class} : #{error.message}
|
64
|
+
|
65
|
+
Uspec encountered an error when loading a test file.
|
66
|
+
This is probably a typo in the test file or the file it is testing.
|
67
|
+
|
68
|
+
If you think this is a bug in Uspec please report it: https://github.com/acook/uspec/issues/new
|
69
|
+
|
70
|
+
Error occured when loading test file `#{spec || path}`.
|
71
|
+
The origin of the error may be in file `#{error_file}` on line ##{error_line}.
|
72
|
+
|
73
|
+
\t#{error.backtrace[0,3].join "\n\t"}
|
74
|
+
MSG
|
75
|
+
puts
|
76
|
+
warn message
|
77
|
+
Uspec::Stats.results << Uspec::Result.new(message, error, caller)
|
62
78
|
end
|
63
79
|
|
64
80
|
end
|
data/lib/uspec/dsl.rb
CHANGED
@@ -1,20 +1,36 @@
|
|
1
|
+
require_relative "result"
|
2
|
+
|
1
3
|
module Uspec
|
2
4
|
module DSL
|
3
5
|
module_function
|
4
6
|
def spec description
|
5
|
-
|
7
|
+
terminal = Uspec::Terminal
|
6
8
|
|
7
9
|
print ' -- ', description
|
8
10
|
|
9
|
-
return print(': ' +
|
11
|
+
return print(': ' + terminal.yellow('pending') + terminal.newline) unless block_given?
|
10
12
|
|
11
13
|
begin
|
12
|
-
|
13
|
-
rescue =>
|
14
|
+
raw_result = yield
|
15
|
+
rescue => raw_result
|
14
16
|
end
|
15
17
|
|
18
|
+
result = Result.new description, raw_result, caller
|
19
|
+
|
16
20
|
Uspec::Stats.results << result
|
17
|
-
|
21
|
+
|
22
|
+
print ': ', result.pretty, "\n"
|
23
|
+
rescue => error
|
24
|
+
message = <<-MSG
|
25
|
+
#{error.class} : #{error.message}
|
26
|
+
|
27
|
+
Uspec encountered an internal error, please report this bug: https://github.com/acook/uspec/issues/new
|
28
|
+
|
29
|
+
\t#{error.backtrace.join "\n\t"}
|
30
|
+
MSG
|
31
|
+
puts
|
32
|
+
warn message
|
33
|
+
Uspec::Stats.results << Uspec::Result.new(message, error, caller)
|
18
34
|
end
|
19
35
|
end
|
20
36
|
end
|
data/lib/uspec/result.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
require_relative "terminal"
|
2
|
+
|
3
|
+
module Uspec
|
4
|
+
class Result
|
5
|
+
include Terminal
|
6
|
+
|
7
|
+
def initialize spec, raw, source
|
8
|
+
@spec = spec
|
9
|
+
@raw = raw
|
10
|
+
@source = source
|
11
|
+
end
|
12
|
+
attr_reader :spec, :raw, :source
|
13
|
+
|
14
|
+
def pretty
|
15
|
+
if raw == true then
|
16
|
+
green raw
|
17
|
+
elsif raw == false then
|
18
|
+
red raw
|
19
|
+
elsif Exception === raw then
|
20
|
+
[
|
21
|
+
red('Exception'), vspace,
|
22
|
+
hspace, 'Spec encountered an Exception ', newline,
|
23
|
+
hspace, 'in spec at ', source.first, vspace,
|
24
|
+
hspace, message, vspace,
|
25
|
+
white(trace)
|
26
|
+
].join
|
27
|
+
else
|
28
|
+
[
|
29
|
+
red('Unknown Result'), vspace,
|
30
|
+
hspace, 'Spec did not return a boolean value ', newline,
|
31
|
+
hspace, 'in spec at ', source.first, vspace,
|
32
|
+
hspace, red(klassinfo), inspector, newline
|
33
|
+
].join
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def trace
|
38
|
+
raw.backtrace.inject(String.new) do |text, line|
|
39
|
+
text << "#{hspace}#{line}#{newline}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def message
|
44
|
+
"#{red klassinfo}#{raw.message}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def klassinfo
|
48
|
+
superklass ? "#{klass} < #{superklass}: " : "#{klass}: "
|
49
|
+
end
|
50
|
+
|
51
|
+
# Attempts to inspect an object
|
52
|
+
def inspector
|
53
|
+
klass && klass.public_method_defined?(:inspect) ? raw.inspect : "#<#{klass}:0x#{get_id}>"
|
54
|
+
rescue Exception => error
|
55
|
+
return "#<#{klass}:0x#{get_id}>" if error.message.include? get_id
|
56
|
+
|
57
|
+
error_file, error_line, _ = error.backtrace[4].split ?:
|
58
|
+
|
59
|
+
<<-MSG
|
60
|
+
|
61
|
+
#{error.class} : #{error.message}
|
62
|
+
|
63
|
+
Uspec detected a bug in your source code!
|
64
|
+
Calling #inspect on an object will recusively call #inspect on its instance variables and contents.
|
65
|
+
If one of those contained objects does not have an #inspect method you will see this message.
|
66
|
+
You will also get this message if your #inspect method or one of its callees raises an exception.
|
67
|
+
This is most likely to happen with BasicObject and its subclasses.
|
68
|
+
|
69
|
+
If you think this is a bug in Uspec please report it: https://github.com/acook/uspec/issues/new
|
70
|
+
|
71
|
+
Error may have occured in test `#{spec}` in file `#{error_file}` on line ##{error_line}.
|
72
|
+
|
73
|
+
\t#{error.backtrace.join "\n\t"}
|
74
|
+
MSG
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the class of the object if it isn't already a class
|
78
|
+
def klass
|
79
|
+
Module === raw ? raw : ancestor_klasses[1]
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns the superclass of the object
|
83
|
+
def superklass
|
84
|
+
ancestor_klasses[2]
|
85
|
+
end
|
86
|
+
|
87
|
+
# Gets the object ID of an object
|
88
|
+
def get_id
|
89
|
+
raw.__id__.to_s(16) rescue 0
|
90
|
+
end
|
91
|
+
|
92
|
+
# Obtain the singleton class of an object
|
93
|
+
def singleton
|
94
|
+
@singleton ||= (class << raw; self; end) rescue raw.class
|
95
|
+
end
|
96
|
+
|
97
|
+
def ancestor_klasses
|
98
|
+
@ancestor_klasses ||= ancestors.select{|a| a.is_a? Class}
|
99
|
+
end
|
100
|
+
|
101
|
+
# Collects the ancestors of an object
|
102
|
+
def ancestors
|
103
|
+
@ancestors ||= safe_send singleton, :ancestors
|
104
|
+
end
|
105
|
+
|
106
|
+
# Works around BasicObject and other objects that are missing/overwrite important methods
|
107
|
+
def safe_send object, method, *args, &block
|
108
|
+
(Module === object ? Module : Object).instance_method(method).bind(object).call(*args, &block)
|
109
|
+
end
|
110
|
+
|
111
|
+
def inspect
|
112
|
+
"#{self.class} for `#{spec}` -> #{pretty}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/lib/uspec/stats.rb
CHANGED
@@ -15,9 +15,16 @@ module Uspec
|
|
15
15
|
|
16
16
|
def exit_code
|
17
17
|
# checking for truthy isn't good enough, it must be exactly true!
|
18
|
-
failures = results.count{|result| result != true }
|
18
|
+
failures = results.count{|result| result.raw != true }
|
19
19
|
failures > 255 ? 255 : failures
|
20
20
|
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
<<-INFO
|
24
|
+
#{super} Failures: #{exit_code}
|
25
|
+
#{results.map{|r| r.inspect}.join "\n\t" }
|
26
|
+
INFO
|
27
|
+
end
|
21
28
|
end
|
22
29
|
end
|
23
30
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Uspec
|
2
|
+
module Terminal
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def colors
|
6
|
+
{
|
7
|
+
red: 1,
|
8
|
+
green: 2,
|
9
|
+
yellow: 3,
|
10
|
+
white: 7
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def color hue, text = nil
|
15
|
+
"#{esc "3#{colors[hue]};1"}#{text}#{normal unless text.nil?}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def esc seq
|
19
|
+
"\e[#{seq}m"
|
20
|
+
end
|
21
|
+
|
22
|
+
def normal text=nil
|
23
|
+
"#{esc 0}#{text}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def hspace
|
27
|
+
' '
|
28
|
+
end
|
29
|
+
|
30
|
+
def vspace
|
31
|
+
"#{newline}#{newline}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def newline
|
35
|
+
$/
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_missing name, *args, &block
|
39
|
+
if colors.keys.include? name then
|
40
|
+
color name, *args
|
41
|
+
else
|
42
|
+
super
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
data/lib/uspec/version.rb
CHANGED
data/uspec.gemspec
CHANGED
@@ -1,19 +1,27 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "uspec/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "uspec"
|
8
8
|
gem.version = Uspec::VERSION
|
9
|
-
gem.authors = ["Anthony Cook"]
|
10
|
-
gem.email = ["
|
9
|
+
gem.authors = ["Anthony M. Cook"]
|
10
|
+
gem.email = ["github@anthonymcook.com"]
|
11
11
|
gem.description = %q{Uspec is a shiny little spec framework for your apps! Unlike other testing frameworks there's no need for matchers, there can only be one assertion per test, and you never have to worry that your tests lack assertions.}
|
12
12
|
gem.summary = %q{a shiny little spec framework for your apps!}
|
13
13
|
gem.homepage = "http://github.com/acook/uspec#readme"
|
14
|
+
gem.license = "MIT"
|
14
15
|
|
15
16
|
gem.files = `git ls-files`.split($/)
|
16
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
19
|
gem.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# due to require_relative semantics in 1.9.x and issues with BasicObject support in 2.0
|
22
|
+
# technically should still work in 2.0 but some of the test suite won't pass
|
23
|
+
gem.required_ruby_version = ">= 2.1"
|
24
|
+
|
25
|
+
gem.add_development_dependency "pry"
|
26
|
+
gem.add_development_dependency "pry-doc"
|
19
27
|
end
|
data/uspec/cli_spec.rb
CHANGED
@@ -27,10 +27,10 @@ spec 'runs an individual spec' do
|
|
27
27
|
output.include? 'I love passing tests'
|
28
28
|
end
|
29
29
|
|
30
|
-
spec '
|
30
|
+
spec 'broken requires in test files count as test failures' do
|
31
31
|
path = Pathname.new(__FILE__).parent.join('test_specs', 'broken_require_spec')
|
32
32
|
|
33
|
-
capture do
|
33
|
+
output = capture do
|
34
34
|
exec "bin/uspec #{path}"
|
35
35
|
end
|
36
36
|
|
@@ -44,5 +44,5 @@ spec 'displays information about test file with broken require' do
|
|
44
44
|
exec "bin/uspec #{path}"
|
45
45
|
end
|
46
46
|
|
47
|
-
output.include?
|
48
|
-
end
|
47
|
+
output.include?('cannot load such file') || output
|
48
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative "uspec_helper"
|
2
|
+
|
3
|
+
bo = BasicObject.new
|
4
|
+
|
5
|
+
spec "#pretty doesn't die when given a BasicObject" do
|
6
|
+
result = Uspec::Result.new "BasicObject Result", bo, []
|
7
|
+
expected = "#<BasicObject:"
|
8
|
+
actual = result.pretty
|
9
|
+
actual.include?(expected) || actual
|
10
|
+
end
|
11
|
+
|
12
|
+
# If we don't prefix the classname with "::", Ruby defines it under an anonymous class
|
13
|
+
class ::TestObject < BasicObject; end
|
14
|
+
obj = TestObject.new
|
15
|
+
|
16
|
+
spec "ensure BasicObject subclasses work" do
|
17
|
+
result = Uspec::Result.new "BasicObject Subclass Result", obj, []
|
18
|
+
expected = "#<TestObject:"
|
19
|
+
actual = result.pretty
|
20
|
+
actual.include?(expected) || result.inspector
|
21
|
+
end
|
22
|
+
|
23
|
+
parent = [obj]
|
24
|
+
|
25
|
+
spec "ensure parent object of BasicObject subclasses get a useful error message" do
|
26
|
+
result = Uspec::Result.new "BasicObject Parent Result", parent, []
|
27
|
+
expected = "BasicObject and its subclasses"
|
28
|
+
actual = result.pretty
|
29
|
+
actual.include?(expected) || result.inspector
|
30
|
+
end
|
31
|
+
|
32
|
+
class ::InspectFail; def inspect; raise; end; end
|
33
|
+
inspect_fail = InspectFail.new
|
34
|
+
|
35
|
+
spec "display a useful error message when a user-defined inspect method fails" do
|
36
|
+
result = Uspec::Result.new "Inspect Fail Result", inspect_fail, []
|
37
|
+
expected = "raises an error"
|
38
|
+
actual = result.pretty
|
39
|
+
actual.include?(expected) || result.inspector
|
40
|
+
end
|
data/uspec/uspec_spec.rb
CHANGED
@@ -33,15 +33,19 @@ spec 'should not define DSL methods on arbitrary objects' do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
spec 'exit code is the number of failures' do
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
expected = 50
|
37
|
+
output = capture do
|
38
|
+
expected.times do |count|
|
39
|
+
spec "fail ##{count + 1}" do
|
39
40
|
false
|
40
41
|
end
|
41
42
|
end
|
43
|
+
|
44
|
+
puts(Uspec::Stats.inspect) unless Uspec::Stats.exit_code == expected
|
42
45
|
end
|
46
|
+
actual = $?.exitstatus
|
43
47
|
|
44
|
-
|
48
|
+
actual == expected || puts("", output) || $?
|
45
49
|
end
|
46
50
|
|
47
51
|
spec 'if more than 255 failures, exit status is 255' do
|
metadata
CHANGED
@@ -1,25 +1,54 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Anthony Cook
|
7
|
+
- Anthony M. Cook
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
12
|
-
dependencies:
|
11
|
+
date: 2019-06-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pry
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
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: pry-doc
|
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'
|
13
41
|
description: Uspec is a shiny little spec framework for your apps! Unlike other testing
|
14
42
|
frameworks there's no need for matchers, there can only be one assertion per test,
|
15
43
|
and you never have to worry that your tests lack assertions.
|
16
44
|
email:
|
17
|
-
-
|
45
|
+
- github@anthonymcook.com
|
18
46
|
executables:
|
19
47
|
- uspec
|
20
48
|
extensions: []
|
21
49
|
extra_rdoc_files: []
|
22
50
|
files:
|
51
|
+
- ".editorconfig"
|
23
52
|
- ".gitignore"
|
24
53
|
- ".ruby-gemset"
|
25
54
|
- ".ruby-version"
|
@@ -34,16 +63,19 @@ files:
|
|
34
63
|
- lib/uspec.rb
|
35
64
|
- lib/uspec/cli.rb
|
36
65
|
- lib/uspec/dsl.rb
|
37
|
-
- lib/uspec/
|
66
|
+
- lib/uspec/result.rb
|
38
67
|
- lib/uspec/stats.rb
|
68
|
+
- lib/uspec/terminal.rb
|
39
69
|
- lib/uspec/version.rb
|
40
70
|
- uspec.gemspec
|
41
71
|
- uspec/cli_spec.rb
|
72
|
+
- uspec/result_spec.rb
|
42
73
|
- uspec/test_specs/broken_require_spec
|
43
74
|
- uspec/uspec_helper.rb
|
44
75
|
- uspec/uspec_spec.rb
|
45
76
|
homepage: http://github.com/acook/uspec#readme
|
46
|
-
licenses:
|
77
|
+
licenses:
|
78
|
+
- MIT
|
47
79
|
metadata: {}
|
48
80
|
post_install_message:
|
49
81
|
rdoc_options: []
|
@@ -53,7 +85,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
85
|
requirements:
|
54
86
|
- - ">="
|
55
87
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
88
|
+
version: '2.1'
|
57
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
90
|
requirements:
|
59
91
|
- - ">="
|
data/lib/uspec/formatter.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
module Uspec
|
2
|
-
class Formatter
|
3
|
-
def colors
|
4
|
-
{
|
5
|
-
red: 1,
|
6
|
-
green: 2,
|
7
|
-
yellow: 3,
|
8
|
-
white: 7
|
9
|
-
}
|
10
|
-
end
|
11
|
-
|
12
|
-
def color hue, text = nil
|
13
|
-
esc("3#{colors[hue]};1") + "#{text}#{normal}"
|
14
|
-
end
|
15
|
-
|
16
|
-
def esc seq
|
17
|
-
"\e[#{seq}m"
|
18
|
-
end
|
19
|
-
|
20
|
-
def normal text=nil
|
21
|
-
esc(0) + text.to_s
|
22
|
-
end
|
23
|
-
|
24
|
-
def colorize result, source
|
25
|
-
if result == true then
|
26
|
-
green result
|
27
|
-
elsif result == false then
|
28
|
-
red result
|
29
|
-
elsif result.is_a? Exception then
|
30
|
-
[
|
31
|
-
red('Exception'), vspace,
|
32
|
-
hspace, 'Spec encountered an Exception ', newline,
|
33
|
-
hspace, 'in spec at ', source.first, vspace,
|
34
|
-
hspace, message(result), vspace,
|
35
|
-
white(trace result)
|
36
|
-
].join
|
37
|
-
else
|
38
|
-
[
|
39
|
-
red('Unknown Result'), vspace,
|
40
|
-
hspace, 'Spec did not return a boolean value ', newline,
|
41
|
-
hspace, 'in spec at ', source.first, vspace,
|
42
|
-
hspace, red(classinfo(result)), result.inspect, newline
|
43
|
-
].join
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def trace error
|
48
|
-
error.backtrace.inject(String.new) do |text, line|
|
49
|
-
text << hspace + line + newline
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def message error
|
54
|
-
red(classinfo error) + error.message
|
55
|
-
end
|
56
|
-
|
57
|
-
def classinfo object
|
58
|
-
"#{classify object} < #{superclass object}: "
|
59
|
-
end
|
60
|
-
|
61
|
-
def classify object
|
62
|
-
object.is_a?(Module) ? object : object.class
|
63
|
-
end
|
64
|
-
|
65
|
-
def superclass object
|
66
|
-
classify(object).superclass
|
67
|
-
end
|
68
|
-
|
69
|
-
def hspace
|
70
|
-
' '
|
71
|
-
end
|
72
|
-
|
73
|
-
def vspace
|
74
|
-
newline + newline
|
75
|
-
end
|
76
|
-
|
77
|
-
def newline
|
78
|
-
$/
|
79
|
-
end
|
80
|
-
|
81
|
-
def method_missing name, *args, &block
|
82
|
-
if colors.keys.include? name then
|
83
|
-
color name, *args
|
84
|
-
else
|
85
|
-
super
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|
90
|
-
end
|