uspec 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f6a6363a2a59ed141811ddbd906b6a47a1494a0b
4
- data.tar.gz: 5d21b182f77d0d4101d4a4236775e527aa05972d
2
+ SHA256:
3
+ metadata.gz: 641541f23b26b9c14b11950c55f9161aa89142aa41b8627a9f2dcbe54ac11584
4
+ data.tar.gz: a02353485421133ac4fa3eb639a7942992152faee3db2f484da4da56917014d6
5
5
  SHA512:
6
- metadata.gz: 28cd24aed39ea930141a5f0e72ed86c02221610ab610d8b8359e46d4002898b578a554bbf903b5f524e9552edf441f559ce004c356b4abd259215d3720f8df6b
7
- data.tar.gz: e54033546d92f8f89651e49df226c293d973952d77d4fd6d9bda32fb3f8f876d6d54cd14e7f7306ca266f6d83d9812f3d7ca9d036c8a7e3baa8fa25e5549df56
6
+ metadata.gz: 1776508a0bc6ca4da5e90167072244305b9994b407d75fce53048bda6cad1a439adee75ecb0ddf534728f6ab6ad268a44588013a57f225df74f38a0e1c85a5c8
7
+ data.tar.gz: 1b39cb64033e21f466ee0a8edaea706e20589f92b3cbae80eb41e624c3dca9f24f1c376f277a7c5061f8b5d20608ea49cf1de71b9014409d4d5bc28b6d1ad702
data/.editorconfig ADDED
@@ -0,0 +1,11 @@
1
+ # EditorConfig is awesome: https://EditorConfig.org
2
+
3
+ root = true
4
+
5
+ [*]
6
+ end_of_line = lf
7
+ insert_final_newline = true
8
+ indent_style = space
9
+ indent_size = 2
10
+ charset = utf-8
11
+ trim_trailing_whitespace = true
data/.rubocop.yml ADDED
@@ -0,0 +1,56 @@
1
+ # Rubocop override settings
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.0
5
+
6
+ Metrics/LineLength:
7
+ Max: 120
8
+ Exclude:
9
+ - config_module.gemspec
10
+ - "uspec/**/*"
11
+
12
+ Naming/PredicateName:
13
+ Enabled: false
14
+
15
+ Style/PreferredHashMethods:
16
+ Exclude:
17
+ - "**/*"
18
+
19
+ Style/Documentation:
20
+ Enabled: false
21
+
22
+ Style/MethodDefParentheses:
23
+ Enabled: false
24
+
25
+ Style/ParallelAssignment:
26
+ Enabled: false
27
+
28
+ Style/SingleLineMethods:
29
+ Enabled: false
30
+
31
+ Style/Alias:
32
+ Enabled: false
33
+
34
+ Style/CaseEquality:
35
+ Enabled: false
36
+
37
+ Style/SymbolArray:
38
+ Enabled: false
39
+
40
+ Bundler/OrderedGems:
41
+ Enabled: false
42
+
43
+ Style/StringLiterals:
44
+ EnforcedStyle: double_quotes
45
+
46
+ Style/StringLiteralsInInterpolation:
47
+ EnforcedStyle: double_quotes
48
+
49
+ Layout/AccessModifierIndentation:
50
+ EnforcedStyle: outdent
51
+
52
+ Style/EnforcedStyleForMultiline:
53
+ EnforcedStyle: consistent_comma
54
+
55
+ Naming/RescuedExceptionsVariableName:
56
+ PreferredName: error
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.2.3
1
+ 2.3.7
data/.travis.yml CHANGED
@@ -1,11 +1,16 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 2.2.3
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
@@ -3,29 +3,45 @@ Uspec
3
3
 
4
4
  Uspec is a shiny little testing framework for your apps!
5
5
 
6
- [![Build Status](https://travis-ci.org/acook/uspec.png?branch=master)](https://travis-ci.org/acook/uspec)
7
- [![Code Climate](https://codeclimate.com/github/acook/uspec.png)](https://codeclimate.com/github/acook/uspec)
6
+ [![Gem Version](https://img.shields.io/gem/v/uspec.svg?style=for-the-badge)](https://rubygems.org/gems/uspec/)
7
+ [![Build Status](https://img.shields.io/travis/acook/uspec.svg?style=for-the-badge)](https://travis-ci.org/acook/uspec)
8
+ [![Code Climate](https://img.shields.io/codeclimate/maintainability/acook/uspec.svg?style=for-the-badge)](https://codeclimate.com/github/acook/uspec)
8
9
 
9
10
  Philosophy / Why Uspec?
10
11
  -----------------------
11
12
 
12
13
  > Uspec is just Ruby!
13
14
 
14
- Unlike other testing frameworks there's no need for special matchers,
15
- there can only be one assertion per test,
15
+ Unlike other testing frameworks there's no need for special matchers,
16
+ there can only be one assertion per test,
16
17
  and you never have to worry that your tests lack assertions.
17
18
 
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 validity of the statement. Standard Ruby comparisons are your friend!
19
+ That's because when the `spec` block is evaluated the return value is used (in a very ruby-like way)
20
+ to determine if the test has passed or failed. Standard Ruby comparisons are your friend!
20
21
  No more digging around in your test framework's documentation to figure out what matcher you're supposed to use.
21
22
  This also means *no monkey patching* core classes!
22
23
 
23
- Uspec's output is in beautiful ansi technicolor,
24
+ Uspec's output is in beautiful ansi technicolor,
24
25
  with red for failures, green for successes, and yellow for pending specs. Here's a screenshot:
25
26
 
26
27
  ![Screenshot!](http://i.imgur.com/M2F5YvO.png)
27
28
 
28
- Uspec is tiny, painless, and easy to use. Download it and give it a shot. :)
29
+ Uspec is tiny, painless, and easy to use. Download it and give it a try!
30
+
31
+ Example
32
+ -------
33
+
34
+ Uspec is **just Ruby**. The DSL is minimal - there's only one method to remember!
35
+
36
+ Writing a spec is easy:
37
+
38
+ ```ruby
39
+ spec 'AwesomeMcCoolname.generate creates a cool name' do
40
+ AwesomeMcCoolname.generate.include? 'Cool'
41
+ end
42
+ ```
43
+
44
+ That's it!
29
45
 
30
46
  Installation
31
47
  ------------
@@ -38,7 +54,7 @@ And then execute:
38
54
 
39
55
  $ bundle
40
56
 
41
- Or install it yourself as:
57
+ Or install it directly with:
42
58
 
43
59
  $ gem install uspec
44
60
 
@@ -46,46 +62,31 @@ Or install it yourself as:
46
62
  Quickstart
47
63
  ----------
48
64
 
49
- 0. Create a `spec` directory to keep your specs in.
65
+ 0. Create a `uspec` directory to keep your specs in.
50
66
  1. Name your specs ending with `_spec.rb`.
51
- 2. Write some specs in Ruby using the `spec` method.
67
+ 2. Write some specs in Ruby using the `spec` method (example above).
52
68
  2. Use the included `uspec` executable to run your specs.
53
69
 
54
- **Hint:** A lot of people also put `require_relative 'spec_helper'` in their tests for global start up code.
70
+ **Hint:** A lot of people also put `require_relative 'spec_helper'` at the top of their test files for sharing code between tests.
55
71
 
56
- Usage
57
- -----
72
+ Commandline Usage
73
+ -----------------
58
74
 
59
- ```
75
+ ```
60
76
  $ uspec --help
61
77
  uspec - minimalistic ruby testing framework
62
78
  usage: uspec [<file_or_path>...]
63
79
  ```
64
80
 
65
- - Without arguments the `uspec` command will automatially look for `spec` directories and load any `*_spec.rb` files inside them.
81
+ - Without arguments the `uspec` command will automatially look for a `uspec` directory and load any `*_spec.rb` files inside them.
66
82
  - You can also pass in arbitrary files and it will attempt to run them as specs.
67
- - If you pass in directories `uspec` will find and run any specs inside them.
68
- - Uspec will return `0` if all specs pass and `255` if any fail.
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!
83
+ - If you pass in directories `uspec` will scan for and run any specs inside them.
84
+ - Uspec will return the number of failures as its status code to the commandline, 0 if none.
84
85
 
85
86
  Output
86
87
  ------
87
88
 
88
- Examples of Uspec's output below!
89
+ A brief explanation of `uspec`'s output to show you what it can do!
89
90
 
90
91
  ### Success
91
92
 
@@ -157,7 +158,7 @@ When you run the test Uspec will helpfully display:
157
158
  Tips & Tricks
158
159
  -------------
159
160
 
160
- Because there's no matchers and only one method there's no reference documentation to look at, so here are some ideas to get you going!
161
+ Because there's no matchers and only one method there's no need for specialized reference documentation, but here are some ideas to get you going!
161
162
 
162
163
  ### String matching
163
164
 
@@ -190,8 +191,8 @@ What if you want to test that an error has occured? Just use Ruby!
190
191
  spec 'calling AwesomeMcCoolname.awesomeness without specifying the awesomeness level should explode' do
191
192
  begin
192
193
  AwesomeMcCoolname.awesomeness
193
- rescue => error
194
- error.class == ArgumentError || raise
194
+ rescue ArgumentError => error
195
+ error.message.include?("Needs awesomeness level!") || raise
195
196
  end
196
197
  end
197
198
  ```
@@ -200,6 +201,11 @@ If there's no error, then Uspec will see the result of the method call (whatever
200
201
  If the wrong Exception is raised, then because of reraising (by just calling `raise` without parameters),
201
202
  Ruby will dutifully pass along the error for Uspec to display.
202
203
 
204
+ Mocks, Spies, Stubs, and More!
205
+ -----------------------
206
+
207
+ Since `uspec` is a very straight forward testing utility it is easy to use any of the standard Ruby mocking frameworks with it. However, the [Impasta gem](https://github.com/acook/impasta) was made specifically for simple but comprehensive mocking, stubbing, and spying.
208
+
203
209
  Assertions & Debugging
204
210
  ----------------------
205
211
 
@@ -212,7 +218,7 @@ require 'uspec'
212
218
 
213
219
  class MyFoo
214
220
  extend Uspec::DSL
215
-
221
+
216
222
  def assert
217
223
  spec 'foo is valid' do
218
224
  false
@@ -223,19 +229,20 @@ end
223
229
  MyFoo.new.assert
224
230
  ```
225
231
 
226
- If there are any specs that fail, your application will exit with a `255``.
232
+ Assertions will be displayed as they occur, success or failure along with any informative output.
233
+ If there are any specs that fail, when your application exits its error code will equal the number of failures.
227
234
 
228
235
  ```
229
236
  $ ruby foo.rb
230
237
  -- foo is valid: false
231
238
  $ echo $?
232
- 255
239
+ 1
233
240
  ```
234
241
 
235
242
  Uspec is just Ruby
236
243
  ------------------
237
244
 
238
- If for some reason you don't want to use the `uspec` command, you can `require 'uspec'` and `extend Uspec::DSL`.
245
+ If for some reason you don't want to use the `uspec` command, you can `require 'uspec'` and `extend Uspec::DSL`.
239
246
  From there you can just run the file with ruby: `ruby my_test_spec.rb`
240
247
 
241
248
  Contributing
@@ -250,4 +257,4 @@ Contributing
250
257
  Author
251
258
  ------
252
259
 
253
- > Anthony M. Cook 2013-2016
260
+ > Anthony M. Cook 2013-2020
data/bin/uspec CHANGED
@@ -1,9 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative '../lib/uspec/exec'
4
-
5
- if (ARGV & %w{-h --help -? /? /help}).empty? then
6
- Uspec::Exec.run_specs ARGV
7
- else
8
- Uspec::Exec.usage
9
- end
3
+ require_relative '../lib/uspec/cli'
4
+ Uspec::CLI.invoke ARGV
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 { exit Uspec::Stats.exit_code }
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 ADDED
@@ -0,0 +1,80 @@
1
+ require 'pathname'
2
+ require_relative '../uspec'
3
+
4
+ class Uspec::CLI
5
+ class << self
6
+ def usage
7
+ warn "uspec v#{::Uspec::VERSION} - minimalistic ruby testing framework"
8
+ warn "usage: #{File.basename $0} [<file_or_path>...]"
9
+ end
10
+
11
+ def run_specs paths
12
+ uspec_cli = self.new paths
13
+ uspec_cli.run_paths
14
+ end
15
+
16
+ def invoke args
17
+ if (args & %w[-h --help -? /? -v --version]).empty? then
18
+ run_specs args
19
+ else
20
+ usage
21
+ end
22
+ end
23
+ end
24
+
25
+ def initialize paths
26
+ @paths = paths
27
+ @pwd = Pathname.pwd.freeze
28
+ end
29
+
30
+ def paths
31
+ if @paths.empty? then
32
+ ['spec', 'uspec', 'test'].each do |path|
33
+ @paths << path if Pathname.new(path).directory?
34
+ end
35
+ end
36
+
37
+ @paths
38
+ end
39
+
40
+ def run_paths
41
+ paths.each do |path|
42
+ run @pwd.join path
43
+ end
44
+ end
45
+
46
+ def run path
47
+ spec = nil
48
+ if path.directory? then
49
+ Pathname.glob(path.join('**', '**_spec.rb')).each do |spec|
50
+ run spec
51
+ end
52
+ elsif path.exist? then
53
+ puts "#{path.basename path.extname}:"
54
+ Uspec::DSL.instance_eval(path.read, path.to_s)
55
+ else
56
+ warn "path not found: #{path}"
57
+ end
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)
78
+ end
79
+
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
- formatter = Uspec::Formatter.new
7
+ terminal = Uspec::Terminal
6
8
 
7
9
  print ' -- ', description
8
10
 
9
- return print(': ' + formatter.yellow('pending') + formatter.vspace) unless block_given?
11
+ return print(': ' + terminal.yellow('pending') + terminal.newline) unless block_given?
10
12
 
11
13
  begin
12
- result = yield
13
- rescue => result
14
+ raw_result = yield
15
+ rescue Exception => raw_result
14
16
  end
15
17
 
18
+ result = Result.new description, raw_result, caller
19
+
16
20
  Uspec::Stats.results << result
17
- print ': ', formatter.colorize(result, caller), "\n"
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
@@ -0,0 +1,93 @@
1
+ require_relative "terminal"
2
+ require "toisb"
3
+
4
+ module Uspec
5
+ class Result
6
+ include Terminal
7
+
8
+ def initialize spec, raw, source
9
+ @spec = spec
10
+ @raw = raw
11
+ @source = source
12
+ @handler = ::TOISB.wrap raw
13
+ end
14
+ attr_reader :spec, :raw, :source, :handler
15
+
16
+ def pretty
17
+ if raw == true then
18
+ green raw
19
+ elsif raw == false then
20
+ red raw
21
+ elsif Exception === raw then
22
+ [
23
+ red('Exception'), vspace,
24
+ hspace, 'Spec encountered an Exception ', newline,
25
+ hspace, 'in spec at ', source.first, vspace,
26
+ hspace, message, vspace,
27
+ white(trace)
28
+ ].join
29
+ else
30
+ [
31
+ red('Failed'), vspace,
32
+ hspace, 'Spec did not return a boolean value ', newline,
33
+ hspace, 'in spec at ', source.first, vspace,
34
+ hspace, red(subklassinfo), inspector, newline
35
+ ].join
36
+ end
37
+ end
38
+
39
+ def trace
40
+ raw.backtrace.inject(String.new) do |text, line|
41
+ text << "#{hspace}#{line}#{newline}"
42
+ end
43
+ end
44
+
45
+ def message
46
+ "#{red subklassinfo}#{raw.message}"
47
+ end
48
+
49
+ def subklassinfo
50
+ "#{handler.subklassinfo}: "
51
+ end
52
+
53
+ # Attempts to inspect an object
54
+ def inspector
55
+ if String === raw && raw.include?(?\n) then
56
+ # if object is a multiline string, display it escaped and unescaped
57
+ [
58
+ handler.inspector!, vspace,
59
+ hspace, yellow('"""'), newline,
60
+ raw, normal, newline,
61
+ hspace, yellow('"""')
62
+ ].join
63
+ else
64
+ handler.inspector!
65
+ end
66
+ rescue Exception => error
67
+ return handler.simple_inspector if error.message.include? handler.get_id
68
+
69
+ error_file, error_line, _ = error.backtrace[4].split ?:
70
+
71
+ <<-MSG
72
+
73
+ #{error.class} : #{error.message}
74
+
75
+ Uspec detected a bug in your source code!
76
+ Calling #inspect on an object will recusively call #inspect on its instance variables and contents.
77
+ If one of those contained objects does not have an #inspect method you will see this message.
78
+ You will also get this message if your #inspect method or one of its callees raises an exception.
79
+ This is most likely to happen with BasicObject and its subclasses.
80
+
81
+ If you think this is a bug in Uspec please report it: https://github.com/acook/uspec/issues/new
82
+
83
+ Error may have occured in test `#{spec}` in file `#{error_file}` on line ##{error_line}.
84
+
85
+ \t#{error.backtrace.join "\n\t"}
86
+ MSG
87
+ end
88
+
89
+ def inspect
90
+ "#{self.class} for `#{spec}` -> #{pretty}"
91
+ end
92
+ end
93
+ end
data/lib/uspec/stats.rb CHANGED
@@ -14,9 +14,17 @@ module Uspec
14
14
  end
15
15
 
16
16
  def exit_code
17
- failures = results.count{|result| !result }
17
+ # checking for truthy isn't good enough, it must be exactly true!
18
+ failures = results.count{|result| result.raw != true }
18
19
  failures > 255 ? 255 : failures
19
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
20
28
  end
21
29
  end
22
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
@@ -1,3 +1,3 @@
1
1
  module Uspec
2
- VERSION = '0.1.0'
2
+ VERSION = '0.3.0'
3
3
  end
data/uspec.gemspec CHANGED
@@ -1,19 +1,29 @@
1
1
  # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'uspec/version'
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 = ["anthonymichaelcook@gmail.com"]
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_dependency "that_object_is_so_basic", "~> 0.0.5"
26
+
27
+ gem.add_development_dependency "pry"
28
+ gem.add_development_dependency "pry-doc"
19
29
  end
data/uspec/cli_spec.rb ADDED
@@ -0,0 +1,48 @@
1
+ require_relative 'uspec_helper'
2
+ require 'open3'
3
+
4
+ spec 'shows usage' do
5
+ output = capture do
6
+ exec 'bin/uspec -h'
7
+ end
8
+
9
+ output.include? 'usage'
10
+ end
11
+
12
+ spec 'runs a path of specs' do
13
+ output = capture do
14
+ path = Pathname.new(__FILE__).parent.parent.join('example_specs').to_s
15
+ Uspec::CLI.run_specs Array(path)
16
+ end
17
+
18
+ output.include?('I love passing tests') || output
19
+ end
20
+
21
+ spec 'runs an individual spec' do
22
+ output = capture do
23
+ path = Pathname.new(__FILE__).parent.parent.join('example_specs', 'example_spec.rb').to_s
24
+ Uspec::CLI.run_specs Array(path)
25
+ end
26
+
27
+ output.include?('I love passing tests') || output
28
+ end
29
+
30
+ spec 'broken requires in test files count as test failures' do
31
+ path = Pathname.new(__FILE__).parent.join('test_specs', 'broken_require_spec')
32
+
33
+ output = capture do
34
+ exec "bin/uspec #{path}"
35
+ end
36
+
37
+ $?.exitstatus == 1 || $?
38
+ end
39
+
40
+ spec 'displays information about test file with broken require' do
41
+ path = Pathname.new(__FILE__).parent.join('test_specs', 'broken_require_spec')
42
+
43
+ output = capture do
44
+ exec "bin/uspec #{path}"
45
+ end
46
+
47
+ output.include?('cannot load such file') || output
48
+ end
@@ -0,0 +1,70 @@
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 = "#<BasicObject/TestObject:"
19
+ actual = result.pretty
20
+ actual.include?(expected) || result.pretty
21
+ end
22
+
23
+ spec "display basic info about Object" do
24
+ result = Uspec::Result.new "Object Result", Object.new, []
25
+ expected = "Object < BasicObject"
26
+ actual = result.pretty
27
+ actual.include?(expected) || result.pretty
28
+ end
29
+
30
+ spec "display basic info about Array" do
31
+ result = Uspec::Result.new "Array Result", [], []
32
+ expected = "Array < Object"
33
+ actual = result.pretty
34
+ actual.include?(expected) || result.pretty
35
+ end
36
+
37
+ spec "display basic info about Array class" do
38
+ result = Uspec::Result.new "Array Class Result", Array, []
39
+ #expected = "Class < ???" # TODO: Make classes display nicer in TOISB
40
+ expected = "#<Class:Object> < #<Class:BasicObject>: \e[0mArray"
41
+ actual = result.pretty
42
+ actual.include?(expected) || result.pretty
43
+ end
44
+
45
+ parent = [obj]
46
+
47
+ spec "ensure parent object of BasicObject subclasses get a useful error message" do
48
+ result = Uspec::Result.new "BasicObject Parent Result", parent, []
49
+ expected = "BasicObject and its subclasses"
50
+ actual = result.pretty
51
+ actual.include?(expected) || result.inspector
52
+ end
53
+
54
+ class ::InspectFail; def inspect; raise RuntimeError, "This error is intentional and part of the test."; end; end
55
+ inspect_fail = InspectFail.new
56
+
57
+ spec "display a useful error message when a user-defined inspect method fails" do
58
+ result = Uspec::Result.new "Inspect Fail Result", inspect_fail, []
59
+ expected = "raises an exception"
60
+ actual = result.pretty
61
+ actual.include?(expected) || result.inspector
62
+ end
63
+
64
+ spec "display strings more like their actual contents" do
65
+ expected = "this string:\nshould display \e[42;2mproperly"
66
+ result = Uspec::Result.new "Inspect Fail Result", expected, []
67
+ actual = result.pretty
68
+ actual.include?(expected) || result.inspector
69
+ end
70
+
@@ -0,0 +1 @@
1
+ require_relative "nonexistant"
data/uspec/uspec_spec.rb CHANGED
@@ -10,6 +10,16 @@ spec 'catches errors' do
10
10
  output.include? 'Exception'
11
11
  end
12
12
 
13
+ spec 'catches even non-StandardError-subclass exceptions' do
14
+ output = capture do
15
+ spec 'not implemented error' do
16
+ raise ::NotImplementedError, 'test exception'
17
+ end
18
+ end
19
+
20
+ output.include? 'Exception'
21
+ end
22
+
13
23
  spec 'complains when spec block returns non boolean' do
14
24
  output = capture do
15
25
  spec 'whatever' do
@@ -17,7 +27,7 @@ spec 'complains when spec block returns non boolean' do
17
27
  end
18
28
  end
19
29
 
20
- output.include? 'Unknown Result'
30
+ output.include? 'Failed'
21
31
  end
22
32
 
23
33
  spec 'marks test as pending when no block supplied' do
@@ -33,19 +43,27 @@ spec 'should not define DSL methods on arbitrary objects' do
33
43
  end
34
44
 
35
45
  spec 'exit code is the number of failures' do
36
- capture do
37
- 50.times do
38
- spec 'fail' do
46
+ expected = 50
47
+ output = capture do
48
+ Uspec::Stats.clear_results! # because we're forking, we will have a copy of the current results
49
+
50
+ expected.times do |count|
51
+ spec "fail ##{count + 1}" do
39
52
  false
40
53
  end
41
54
  end
55
+
56
+ puts(Uspec::Stats.inspect) unless Uspec::Stats.exit_code == expected
42
57
  end
58
+ actual = $?.exitstatus
43
59
 
44
- $?.exitstatus == 50 || $?
60
+ actual == expected || puts("", output) || $?
45
61
  end
46
62
 
47
63
  spec 'if more than 255 failures, exit status is 255' do
48
64
  capture do
65
+ Uspec::Stats.clear_results! # because we're forking, we will have a copy of the current results
66
+
49
67
  500.times do
50
68
  spec 'fail' do
51
69
  false
metadata CHANGED
@@ -1,26 +1,70 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
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: 2016-12-22 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-02-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: that_object_is_so_basic
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
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'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-doc
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
13
55
  description: Uspec is a shiny little spec framework for your apps! Unlike other testing
14
56
  frameworks there's no need for matchers, there can only be one assertion per test,
15
57
  and you never have to worry that your tests lack assertions.
16
58
  email:
17
- - anthonymichaelcook@gmail.com
59
+ - github@anthonymcook.com
18
60
  executables:
19
61
  - uspec
20
62
  extensions: []
21
63
  extra_rdoc_files: []
22
64
  files:
65
+ - ".editorconfig"
23
66
  - ".gitignore"
67
+ - ".rubocop.yml"
24
68
  - ".ruby-gemset"
25
69
  - ".ruby-version"
26
70
  - ".travis.yml"
@@ -32,17 +76,21 @@ files:
32
76
  - example_specs/example_spec.rb
33
77
  - example_specs/spec_helper.rb
34
78
  - lib/uspec.rb
79
+ - lib/uspec/cli.rb
35
80
  - lib/uspec/dsl.rb
36
- - lib/uspec/exec.rb
37
- - lib/uspec/formatter.rb
81
+ - lib/uspec/result.rb
38
82
  - lib/uspec/stats.rb
83
+ - lib/uspec/terminal.rb
39
84
  - lib/uspec/version.rb
40
85
  - uspec.gemspec
41
- - uspec/exec_spec.rb
86
+ - uspec/cli_spec.rb
87
+ - uspec/result_spec.rb
88
+ - uspec/test_specs/broken_require_spec
42
89
  - uspec/uspec_helper.rb
43
90
  - uspec/uspec_spec.rb
44
91
  homepage: http://github.com/acook/uspec#readme
45
- licenses: []
92
+ licenses:
93
+ - MIT
46
94
  metadata: {}
47
95
  post_install_message:
48
96
  rdoc_options: []
@@ -52,17 +100,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
52
100
  requirements:
53
101
  - - ">="
54
102
  - !ruby/object:Gem::Version
55
- version: '0'
103
+ version: '2.1'
56
104
  required_rubygems_version: !ruby/object:Gem::Requirement
57
105
  requirements:
58
106
  - - ">="
59
107
  - !ruby/object:Gem::Version
60
108
  version: '0'
61
109
  requirements: []
62
- rubyforge_project:
63
- rubygems_version: 2.6.8
110
+ rubygems_version: 3.0.4
64
111
  signing_key:
65
112
  specification_version: 4
66
113
  summary: a shiny little spec framework for your apps!
67
114
  test_files: []
68
- has_rdoc:
data/lib/uspec/exec.rb DELETED
@@ -1,51 +0,0 @@
1
- require 'pathname'
2
- require_relative '../uspec'
3
-
4
- class Uspec::Exec
5
- class << self
6
- def usage
7
- warn "uspec - minimalistic ruby testing framework"
8
- warn "usage: #{File.basename $0} [<file_or_path>...]"
9
- end
10
-
11
- def run_specs paths
12
- uspec_exec = self.new paths
13
- uspec_exec.run_paths
14
- end
15
- end
16
-
17
- def initialize paths
18
- @paths = paths
19
- @pwd = Pathname.pwd.freeze
20
- end
21
-
22
- def paths
23
- if @paths.empty? then
24
- ['spec', 'uspec', 'test'].each do |path|
25
- @paths << path if Pathname.new(path).directory?
26
- end
27
- end
28
-
29
- @paths
30
- end
31
-
32
- def run_paths
33
- paths.each do |path|
34
- run @pwd.join path
35
- end
36
- end
37
-
38
- def run path
39
- if path.directory? then
40
- Pathname.glob(path.join('**', '**_spec.rb')).each do |spec|
41
- run spec
42
- end
43
- elsif path.exist? then
44
- puts "#{path.basename path.extname}:"
45
- Uspec::DSL.instance_eval(path.read, path.to_s)
46
- else
47
- warn "path not found: #{path}"
48
- end
49
- end
50
-
51
- end
@@ -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
data/uspec/exec_spec.rb DELETED
@@ -1,27 +0,0 @@
1
- require_relative 'uspec_helper'
2
-
3
- spec 'shows usage' do
4
- output = capture do
5
- exec 'bin/uspec -h'
6
- end
7
-
8
- output.include? 'usage'
9
- end
10
-
11
- spec 'runs a path of specs' do
12
- output = capture do
13
- path = Pathname.new(__FILE__).parent.parent.join('example_specs').to_s
14
- Uspec::Exec.run_specs Array(path)
15
- end
16
-
17
- output.include? 'I love passing tests'
18
- end
19
-
20
- spec 'runs an individual spec' do
21
- output = capture do
22
- path = Pathname.new(__FILE__).parent.parent.join('example_specs', 'example_spec.rb').to_s
23
- Uspec::Exec.run_specs Array(path)
24
- end
25
-
26
- output.include? 'I love passing tests'
27
- end