cutest 1.0.0.beta → 1.0.0.beta1

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.
@@ -6,12 +6,9 @@ Forking tests.
6
6
  Description
7
7
  -----------
8
8
 
9
- Run tests in separate processes to avoid shared state.
10
-
11
- Each test file is run in a forked process and. Once a failure is found in a
12
- file, you get a debugger and the ability to fix the error in place. If you
13
- choose to quit the debugger, the rest of the file is skipped. This way, doing
14
- TDD is easier and running your test suite feels faster.
9
+ Each test file is run in a forked process to avoid shared state. Once a failure
10
+ is found, you get a report detailing what failed and how to locate the error
11
+ and the rest of the file is skipped.
15
12
 
16
13
  You can use the `scope` command around tests: it guarantees that no instance
17
14
  variables are shared between tests.
@@ -35,12 +32,11 @@ block as a parameter to the `test` blocks.
35
32
  The `test` method executes the passed block after running `prepare` and
36
33
  `setup`. This is where assertions must be declared.
37
34
 
38
- Two assertions are available: `assert` and `assert_raise`. The first accepts a
39
- value and raises an `AssertionFailed` exception if it's false or nil, and the
40
- later receives an expected exception and a block: the block is executed and
41
- the raised exception is compared with the expected one. An `AssertionFailed`
42
- exception is raised if the block runs fine or if the raised exception doesn't
43
- match the expectation.
35
+ Three assertions are available: `assert`, that accepts a value and raises
36
+ if it's false or nil; `assert_equal`, that raises if its arguments are not
37
+ equal; and `assert_raise`, that executes a passed block and compares the raised
38
+ exception to the expected one. In all cases, if the expectation is no met, an
39
+ `AssertionFailed` exception is raised.
44
40
 
45
41
  Usage
46
42
  -----
@@ -115,24 +111,23 @@ running them.
115
111
  Handling errors
116
112
  ---------------
117
113
 
118
- If you get an error when running the tests, you will see a debugger prompt:
119
-
120
- Exception: Cutest::AssertionFailed
121
- Type continue to retry or edit to modify the source
122
- .Breakpoint 1 at test/setup.rb:14
123
- [12, 16] in test/setup.rb
124
- 12
125
- 13 test "should preserve the original values from the setup" do |params|
126
- => 14 assert 24 == params[:a]
127
- 15 end
128
- 16
129
- test/setup.rb:14
130
- assert 24 == params[:a]
131
- (rdb:1)
132
-
133
- Instead of a getting a report of the error, you get to interact with it live
134
- and even fix it: if you type `edit`, the file is opened in your editor. Once
135
- you fix the code and save it, the debugger will reload it and retry.
114
+ If you get an error when running the tests, this is what you will see:
115
+
116
+ Exception: assert_equal 24, params[:a] # 24 != 23
117
+ test/setup.rb +14
118
+
119
+ Command Line Interface
120
+ ----------------------
121
+
122
+ The tool `cutest` accepts a list of files and sends them to `Cutest.run`. If
123
+ you need to require a file or library before running the tests, as is the case
124
+ with test helpers, use the `-r` flag:
125
+
126
+ $ cutest -r test/helper.rb test/*_test.rb
127
+
128
+ If you want to check which version you are running, try the `-v` flag.
129
+
130
+ If you want to require ruby-debug, use the `--debug` flag.
136
131
 
137
132
  Installation
138
133
  ------------
data/bin/cutest CHANGED
@@ -3,7 +3,7 @@
3
3
  require File.expand_path("../lib/cutest", File.dirname(__FILE__))
4
4
 
5
5
  if ARGV.empty?
6
- puts "usage: cutest [-r lib] [-v] file ..."
6
+ puts "usage: cutest [-r lib] [-v] [--debug] file ..."
7
7
  exit
8
8
  end
9
9
 
@@ -13,7 +13,7 @@ class Cutest
13
13
  # http://github.com/soveran/clap
14
14
  # http://rubygems.org/gems/clap
15
15
  class Clap
16
- VERSION = "0.0.1"
16
+ VERSION = "0.0.2"
17
17
 
18
18
  attr :argv
19
19
  attr :opts
@@ -23,7 +23,7 @@ class Cutest
23
23
  end
24
24
 
25
25
  def initialize(argv, opts)
26
- @argv = argv.reverse.dup
26
+ @argv = argv.dup
27
27
  @opts = opts
28
28
  end
29
29
 
@@ -31,13 +31,24 @@ class Cutest
31
31
  args = []
32
32
 
33
33
  while argv.any?
34
- item = argv.pop
35
34
 
36
- if opts[item]
35
+ item = argv.shift
36
+ flag = opts[item]
37
+
38
+ if flag
39
+
40
+ # Work around lambda semantics in 1.8.7.
41
+ arity = [flag.arity, 0].max
42
+
43
+ # Raise if there are not enough parameters
44
+ # available for the flag.
45
+ if argv.size < arity
46
+ raise ArgumentError
47
+ end
37
48
 
38
49
  # Call the lambda with N items from argv,
39
50
  # where N is the lambda's arity.
40
- opts[item].call(*argv.pop(opts[item].arity))
51
+ flag.call(*argv.shift(arity))
41
52
  else
42
53
 
43
54
  # Collect the items that don't correspond to
@@ -52,7 +63,8 @@ class Cutest
52
63
  end
53
64
 
54
65
  files = Cutest::Clap.run ARGV,
55
- "-r" => lambda { |file| require file },
56
- "-v" => lambda { puts Cutest::VERSION }
66
+ "-r" => lambda { |file| require file },
67
+ "-v" => lambda { puts Cutest::VERSION },
68
+ "--debug" => lambda { ENV["DEBUG"] = true }
57
69
 
58
70
  Cutest.run(Dir[*files]) if files.any?
@@ -1,11 +1,11 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cutest"
3
- s.version = "1.0.0.beta"
3
+ s.version = "1.0.0.beta1"
4
4
  s.summary = "Forking tests."
5
5
  s.description = "Run tests in separate processes to avoid shared state."
6
6
  s.authors = ["Damian Janowski", "Michel Martens"]
7
7
  s.email = ["djanowski@dimaion.com", "michel@soveran.com"]
8
8
  s.homepage = "http://github.com/djanowski/cutest"
9
- s.files = ["LICENSE", "README.markdown", "Rakefile", "lib/cutest.rb", "cutest.gemspec", "test/assert.rb", "test/assert_raise.rb", "test/prepare.rb", "test/run.rb", "test/scopes.rb", "test/setup.rb"]
9
+ s.files = ["LICENSE", "README.markdown", "Rakefile", "lib/cutest.rb", "cutest.gemspec", "test/assert.rb", "test/assert_equal.rb", "test/assert_raise.rb", "test/prepare.rb", "test/run.rb", "test/scopes.rb", "test/setup.rb"]
10
10
  s.executables.push "cutest"
11
11
  end
@@ -1,59 +1,56 @@
1
- begin
2
- require "ruby-debug"
3
- rescue LoadError
4
- puts "Cutest needs ruby-debug, but it couldn't be required."
5
- puts "Please install ruby-debug or ruby-debug19 and try again."
6
- exit
7
- end
1
+ class Cutest
2
+ VERSION = "1.0.0.beta1"
8
3
 
9
- Debugger.settings[:autoeval] = 1
10
- Debugger.settings[:autolist] = 1
11
- Debugger.settings[:listsize] = 5
12
- Debugger.settings[:reload_source_on_change] = 1
4
+ if ENV["DEBUG"]
5
+ begin
6
+ require "ruby-debug"
7
+ rescue LoadError
8
+ puts "Cutest needs ruby-debug, but it couldn't be required."
9
+ puts "Please install ruby-debug or ruby-debug19 and try again."
10
+ exit
11
+ end
13
12
 
14
- class Cutest
15
- VERSION = "1.0.0.beta"
13
+ Debugger.settings[:autoeval] = 1
14
+ Debugger.settings[:autolist] = 1
15
+ Debugger.settings[:listsize] = 5
16
+ Debugger.settings[:reload_source_on_change] = 1
17
+ end
16
18
 
17
19
  def self.run(files)
18
- trap("INT") { exit }
19
- trap("TERM") { exit }
20
-
21
20
  files.each do |file|
22
- Debugger.start do
21
+ stdin, stdout = IO.pipe
23
22
 
24
- loop do
25
- stdin, stdout = IO.pipe
23
+ fork do
24
+ stdin.close
26
25
 
27
- fork do
28
- stdin.close
26
+ begin
27
+ load(file)
29
28
 
30
- begin
31
- load(file)
29
+ rescue LoadError, SyntaxError
30
+ puts ["\n", error([file, $!.message])]
31
+ exit
32
32
 
33
- rescue LoadError, SyntaxError
34
- puts ["\n", error([file, $!.message])]
35
- exit
33
+ rescue Exception
34
+ fn, ln = $!.backtrace.first.split(":")
35
+ message = File.readlines(fn)[ln.to_i - 1]
36
+ stdout.write("#{fn}\n#{ln}\n#{error(message.strip)} # #{$!.message}")
37
+ end
36
38
 
37
- rescue Exception
38
- fn, ln = $!.backtrace.first.split(":")
39
- stdout.write("#{fn}\n#{ln}\n#{error($!)}\n#{hint}")
40
- end
41
- end
39
+ stdout.close
40
+ end
42
41
 
43
- stdout.close
42
+ stdout.close
44
43
 
45
- Process.wait
44
+ Process.wait
46
45
 
47
- output = stdin.read
46
+ output = stdin.read
48
47
 
49
- unless output.empty?
50
- fn, ln, error, hint = output.split("\n")
51
- Debugger.add_breakpoint(fn, ln.to_i)
52
- puts ["\n", error, hint]
53
- else
54
- break
55
- end
56
- end
48
+ stdin.close
49
+
50
+ unless output.empty?
51
+ fn, ln, error = output.split("\n")
52
+
53
+ puts "\n#{error}\n#{fn} +#{ln}"
57
54
  end
58
55
  end
59
56
 
@@ -64,11 +61,6 @@ class Cutest
64
61
  "\033[01;36mException: \033[01;33m#{e}\033[00m"
65
62
  end
66
63
 
67
- def self.hint
68
- "\033[01;36mType \033[0;33mcontinue\033[0;36m to retry " +
69
- "or \033[0;33medit\033[0;36m to modify the source\033[00m"
70
- end
71
-
72
64
  class AssertionFailed < StandardError
73
65
  end
74
66
 
@@ -86,8 +78,8 @@ end
86
78
  module Kernel
87
79
  private
88
80
 
89
- # Use Thread.current[:cutest] to store information about test preparation and
90
- # setup.
81
+ # Use Thread.current[:cutest] to store information about test preparation
82
+ # and setup.
91
83
  Thread.current[:cutest] ||= { :prepare => [] }
92
84
 
93
85
  # Shortcut to access Thread.current[:cutest].
@@ -101,31 +93,31 @@ private
101
93
  Cutest::Scope.new(&block).call
102
94
  end
103
95
 
104
- # Prepare the environment in order to run the tests. This method can be called
105
- # many times, and each new block is appended to a list of preparation blocks.
106
- # When a test is executed, all the preparation blocks are ran in the order they
107
- # were declared. If called without a block, it returns the array of preparation
108
- # blocks.
96
+ # Prepare the environment in order to run the tests. This method can be
97
+ # called many times, and each new block is appended to a list of
98
+ # preparation blocks. When a test is executed, all the preparation blocks
99
+ # are ran in the order they were declared. If called without a block, it
100
+ # returns the array of preparation blocks.
109
101
  def prepare(&block)
110
102
  cutest[:prepare] << block if block_given?
111
103
  cutest[:prepare]
112
104
  end
113
105
 
114
- # Setup parameters for the tests. The block passed to setup is evaluated before
115
- # running each test, and the result of the setup block is passed to the test as
116
- # a parameter. If the setup and the tests are declared at the same level (in
117
- # the global scope or in a sub scope), it is possible to use instance
118
- # variables, but the parameter passing pattern is recommended to ensure there
119
- # are no side effects.
106
+ # Setup parameters for the tests. The block passed to setup is evaluated
107
+ # before running each test, and the result of the setup block is passed to
108
+ # the test as a parameter. If the setup and the tests are declared at the
109
+ # same level (in the global scope or in a sub scope), it is possible to use
110
+ # instance variables, but the parameter passing pattern is recommended to
111
+ # ensure there are no side effects.
120
112
  #
121
113
  # If the setup blocks are declared in the global scope and the tests are
122
114
  # declared in sub scopes, the parameter passing usage is required.
123
115
  #
124
- # Setup blocks can be defined many times, but each new definition overrides the
125
- # previous one. It is recommended to split the tests in many different files
126
- # (the report is per file, not per assertion). Usually one setup block per file
127
- # is enough, but nothing forbids having different scopes with different setup
128
- # blocks.
116
+ # Setup blocks can be defined many times, but each new definition overrides
117
+ # the previous one. It is recommended to split the tests in many different
118
+ # files (the report is per file, not per assertion). Usually one setup
119
+ # block per file is enough, but nothing forbids having different scopes
120
+ # with different setup blocks.
129
121
  def setup(&block)
130
122
  cutest[:setup] = block if block_given?
131
123
  cutest[:setup]
@@ -136,8 +128,8 @@ private
136
128
 
137
129
  # Call the prepare and setup blocks before executing the test. Even
138
130
  # though the assertions can live anywhere (it's not mandatory to put them
139
- # inside test blocks), it is necessary to wrap them in test blocks in order to
140
- # execute preparation and setup blocks.
131
+ # inside test blocks), it is necessary to wrap them in test blocks in order
132
+ # to execute preparation and setup blocks.
141
133
  def test(name = nil, &block)
142
134
  cutest[:test] = name
143
135
 
@@ -147,7 +139,13 @@ private
147
139
 
148
140
  # Assert that value is not nil or false.
149
141
  def assert(value)
150
- flunk unless value
142
+ flunk("assertion failed") unless value
143
+ print "."
144
+ end
145
+
146
+ # Assert that two values are equal.
147
+ def assert_equal(value, other)
148
+ flunk("#{value} != #{other}") unless value == other
151
149
  print "."
152
150
  end
153
151
 
@@ -157,15 +155,15 @@ private
157
155
  yield
158
156
  rescue => exception
159
157
  ensure
160
- flunk unless exception.kind_of?(expected)
158
+ flunk("got #{exception} instead") unless exception.kind_of?(expected)
161
159
  print "."
162
160
  end
163
161
  end
164
162
 
165
163
  # Stop the tests and raise an error where the message is the last line
166
164
  # executed before flunking.
167
- def flunk
168
- exception = Cutest::AssertionFailed.new
165
+ def flunk(message = nil)
166
+ exception = Cutest::AssertionFailed.new(message)
169
167
  exception.set_backtrace([caller[1]])
170
168
 
171
169
  raise exception
@@ -0,0 +1,9 @@
1
+ test do
2
+ assert_equal 1, 1
3
+ end
4
+
5
+ test "raises if the assertion fails" do
6
+ assert_raise(Cutest::AssertionFailed) do
7
+ assert_equal 1, 2
8
+ end
9
+ end
@@ -11,7 +11,7 @@ test "if the params are modified..." do |params|
11
11
  end
12
12
 
13
13
  test "...it should preserve the original values from the setup" do |params|
14
- assert 23 == params[:a]
14
+ assert_equal 23, params[:a]
15
15
  end
16
16
 
17
17
  setup do
metadata CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
6
6
  - 1
7
7
  - 0
8
8
  - 0
9
- - beta
10
- version: 1.0.0.beta
9
+ - beta1
10
+ version: 1.0.0.beta1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Damian Janowski
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-10-10 00:00:00 -03:00
19
+ date: 2010-10-30 00:00:00 -03:00
20
20
  default_executable:
21
21
  dependencies: []
22
22
 
@@ -37,6 +37,7 @@ files:
37
37
  - lib/cutest.rb
38
38
  - cutest.gemspec
39
39
  - test/assert.rb
40
+ - test/assert_equal.rb
40
41
  - test/assert_raise.rb
41
42
  - test/prepare.rb
42
43
  - test/run.rb