uspec 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.markdown +132 -0
- data/Rakefile +1 -0
- data/lib/uspec/dsl.rb +18 -0
- data/lib/uspec/formatter.rb +90 -0
- data/lib/uspec/version.rb +3 -0
- data/lib/uspec.rb +16 -0
- data/uspec/uspec_spec.rb +50 -0
- data/uspec.gemspec +19 -0
- metadata +58 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Anthony Cook
|
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.
|
data/README.markdown
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
Uspec
|
2
|
+
=====
|
3
|
+
|
4
|
+
Uspec is a shiny little testing framework for your apps!
|
5
|
+
|
6
|
+
Anthony M. Cook 2013
|
7
|
+
|
8
|
+
Philosophy / Why Uspec?
|
9
|
+
-----------------------
|
10
|
+
|
11
|
+
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
|
+
|
13
|
+
That's because when the `spec` block is evaluated the return value is used (in a very ruby-like way) to determine the validity of the statement. Standard Ruby comparisons are your friend! No more digging around in your test framework's documentation to figure out what matcher you're supposed to use.
|
14
|
+
|
15
|
+
You can't tell here in the docs, but Uspec's output is in beautiful ansi technicolor, with red for failures, green for successes, and yellow for pending specs. Download it and give it a show, its painless and uber easy to use. :)
|
16
|
+
|
17
|
+
Usage
|
18
|
+
-----
|
19
|
+
|
20
|
+
I suggest creating a `uspec` directory in your project folder to put your specs in. Then you'll need this incantation:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
require 'uspec'
|
24
|
+
extend Uspec
|
25
|
+
```
|
26
|
+
|
27
|
+
You can slot it in the top of your test file, or if you have other setup code you can put it in a `uspec_helper.rb` and `relative_require 'uspec_helper'` in them instead.
|
28
|
+
|
29
|
+
Then all you have to do is put in your specs:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
spec 'AwesomeMcCoolname.generate creates a cool name' do
|
33
|
+
AwesomeMcCoolname.generate.include? 'Cool'
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
If it passes:
|
38
|
+
|
39
|
+
```
|
40
|
+
-- AwesomeMcCoolname.generate creates a cool name: true
|
41
|
+
```
|
42
|
+
|
43
|
+
If it fails:
|
44
|
+
|
45
|
+
```
|
46
|
+
-- AwesomeMcCoolname.generate creates a cool name: false
|
47
|
+
```
|
48
|
+
|
49
|
+
If it throws an error:
|
50
|
+
|
51
|
+
```
|
52
|
+
-- AwesomeMcCoolname.generate creates a cool name: Exception
|
53
|
+
|
54
|
+
Encountered an Exception while running spec
|
55
|
+
at uspec/awesome_mc_coolname_spec.rb:3: in `<main>'
|
56
|
+
|
57
|
+
RuntimeError < StandardError: 'wtf'
|
58
|
+
|
59
|
+
/Users/Dude/Projects/Awesome/lib/awesome_mc_coolname.rb:18:in `explode'
|
60
|
+
uspec/awesome_mc_coolname_spec.rb:4:in `block in <main>'
|
61
|
+
```
|
62
|
+
|
63
|
+
If you create a spec that doesn't return a boolean value (`nil` doesn't count either!) like this:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
spec 'AwesomeMcCoolname.generate creates a cool name' do
|
67
|
+
AwesomeMcCoolname.generate =~ /Badass/
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
Then Uspec will let you know:
|
72
|
+
|
73
|
+
```
|
74
|
+
-- AwesomeMcCoolname.generate creates a badass name: Unknown Result
|
75
|
+
|
76
|
+
Spec did not return a boolean value
|
77
|
+
at uspec/awesome_mc_coolname_spec.rb:6: in `<main>'
|
78
|
+
|
79
|
+
Integer < Numeric: 5
|
80
|
+
```
|
81
|
+
|
82
|
+
If you aren't ready to fill out a spec, maybe as a reminder to add functionality later, just leave off the block and it will be marked as `pending`:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
spec 'a feature I have not implemented yet'
|
86
|
+
```
|
87
|
+
|
88
|
+
When you run the test Uspec will helpfully display:
|
89
|
+
|
90
|
+
```
|
91
|
+
-- a feature I have not implemented yet: pending
|
92
|
+
```
|
93
|
+
|
94
|
+
What if you want to test that an error has occured? Just use Ruby!
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
spec 'calling AwesomeMcCoolname.awesomeness without specifying the awesomeness level should explode' do
|
98
|
+
begin
|
99
|
+
AwesomeMcCoolname.awesomeness
|
100
|
+
rescue => error
|
101
|
+
error.class == ArgumentError || raise
|
102
|
+
end
|
103
|
+
end
|
104
|
+
```
|
105
|
+
|
106
|
+
If there's no error, then Uspec will see the result of the method call (whatever it might be).
|
107
|
+
If the wrong Exception is raised, then because of reraising (by just calling `raise` without parameters),
|
108
|
+
Ruby will dutifully pass along the error for Uspec to display.
|
109
|
+
|
110
|
+
Installation
|
111
|
+
------------
|
112
|
+
|
113
|
+
Add this line to your application's Gemfile:
|
114
|
+
|
115
|
+
gem 'uspec'
|
116
|
+
|
117
|
+
And then execute:
|
118
|
+
|
119
|
+
$ bundle
|
120
|
+
|
121
|
+
Or install it yourself as:
|
122
|
+
|
123
|
+
$ gem install uspec
|
124
|
+
|
125
|
+
Contributing
|
126
|
+
------------
|
127
|
+
|
128
|
+
1. Fork it
|
129
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
130
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
131
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
132
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/uspec/dsl.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Uspec
|
2
|
+
module DSL
|
3
|
+
def spec description
|
4
|
+
formatter = Uspec::Formatter.new
|
5
|
+
|
6
|
+
print ' -- ', description
|
7
|
+
|
8
|
+
return puts(': ' + formatter.yellow('pending') + formatter.vspace) unless block_given?
|
9
|
+
|
10
|
+
begin
|
11
|
+
result = yield
|
12
|
+
rescue => result
|
13
|
+
end
|
14
|
+
|
15
|
+
print ': ', formatter.colorize(result, caller), "\n"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,90 @@
|
|
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 if text}"
|
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
|
data/lib/uspec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative 'uspec/version'
|
2
|
+
require_relative 'uspec/formatter'
|
3
|
+
require_relative 'uspec/dsl'
|
4
|
+
|
5
|
+
module Uspec
|
6
|
+
def self.included object
|
7
|
+
warn 'Use extend instead of include.'
|
8
|
+
exit
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.extended object
|
12
|
+
object.extend Uspec::DSL
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
data/uspec/uspec_spec.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative '../lib/uspec'
|
2
|
+
extend Uspec
|
3
|
+
|
4
|
+
def capture
|
5
|
+
readme, writeme = IO.pipe
|
6
|
+
pid = fork do
|
7
|
+
$stdout.reopen writeme
|
8
|
+
readme.close
|
9
|
+
|
10
|
+
yield
|
11
|
+
end
|
12
|
+
|
13
|
+
writeme.close
|
14
|
+
output = readme.read
|
15
|
+
Process.waitpid(pid)
|
16
|
+
|
17
|
+
output
|
18
|
+
end
|
19
|
+
|
20
|
+
spec 'catches errors' do
|
21
|
+
output = capture do
|
22
|
+
spec 'exception' do
|
23
|
+
raise 'test exception'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
output.include? 'Exception'
|
28
|
+
end
|
29
|
+
|
30
|
+
spec 'complains when spec block returns non boolean' do
|
31
|
+
output = capture do
|
32
|
+
spec 'whatever' do
|
33
|
+
"string"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
output.include? 'Unknown Result'
|
38
|
+
end
|
39
|
+
|
40
|
+
spec 'marks test as pending when no block supplied' do
|
41
|
+
output = capture do
|
42
|
+
spec 'pending test'
|
43
|
+
end
|
44
|
+
|
45
|
+
output.include? 'pending'
|
46
|
+
end
|
47
|
+
|
48
|
+
spec 'should not define DSL methods on arbitrary objects' do
|
49
|
+
!(Array.respond_to? :spec)
|
50
|
+
end
|
data/uspec.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'uspec/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "uspec"
|
8
|
+
gem.version = Uspec::VERSION
|
9
|
+
gem.authors = ["Anthony Cook"]
|
10
|
+
gem.email = ["anthonymichaelcook@gmail.com"]
|
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
|
+
gem.summary = %q{a shiny little spec framework for your apps!}
|
13
|
+
gem.homepage = "http://github.com/acook/uspec#readme"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: uspec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Anthony Cook
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-08 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Uspec is a shiny little spec framework for your apps! Unlike other testing
|
15
|
+
frameworks there's no need for matchers, there can only be one assertion per test,
|
16
|
+
and you never have to worry that your tests lack assertions.
|
17
|
+
email:
|
18
|
+
- anthonymichaelcook@gmail.com
|
19
|
+
executables: []
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- .gitignore
|
24
|
+
- Gemfile
|
25
|
+
- LICENSE.txt
|
26
|
+
- README.markdown
|
27
|
+
- Rakefile
|
28
|
+
- lib/uspec.rb
|
29
|
+
- lib/uspec/dsl.rb
|
30
|
+
- lib/uspec/formatter.rb
|
31
|
+
- lib/uspec/version.rb
|
32
|
+
- uspec.gemspec
|
33
|
+
- uspec/uspec_spec.rb
|
34
|
+
homepage: http://github.com/acook/uspec#readme
|
35
|
+
licenses: []
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.8.25
|
55
|
+
signing_key:
|
56
|
+
specification_version: 3
|
57
|
+
summary: a shiny little spec framework for your apps!
|
58
|
+
test_files: []
|