expectations 0.0.5 → 0.0.7
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.
- data/README +4 -4
- data/lib/expectations/behavior_based_expectation.rb +22 -0
- data/lib/expectations/expectation.rb +6 -39
- data/lib/expectations/mocha.rb +9 -9
- data/lib/expectations/mock_recorder.rb +30 -0
- data/lib/expectations/object.rb +3 -1
- data/lib/expectations/results.rb +4 -5
- data/lib/expectations/state_based_expectation.rb +15 -0
- data/lib/expectations/string.rb +15 -0
- data/lib/expectations/suite.rb +2 -3
- data/lib/expectations/suite_results.rb +12 -1
- data/lib/expectations.rb +4 -0
- data/rakefile.rb +4 -4
- data/test/expectations/expectation_test.rb +0 -4
- data/test/expectations/string_test.rb +7 -0
- data/test/sample_expectations_test.rb +1 -1
- metadata +7 -2
data/README
CHANGED
@@ -16,13 +16,13 @@ expectations is designed to encourage unit testing best practices such as
|
|
16
16
|
- provide one syntax for setting up state based or behavior based expectation
|
17
17
|
- focus on readability by providing no mechanism for describing an expectation other than the code in the expectation.
|
18
18
|
|
19
|
-
Mocking is done utilizing Mocha
|
19
|
+
Mocking is done utilizing Mocha[http://mocha.rubyforge.org]
|
20
20
|
|
21
21
|
by Jay[http://blog.jayfields.com] Fields[http://blog.jayfields.com]
|
22
22
|
|
23
23
|
== Download and Installation
|
24
24
|
|
25
|
-
You can download
|
25
|
+
You can download expectations from here[http://rubyforge.org/projects/expectations] or install it with the following command.
|
26
26
|
|
27
27
|
$ gem install expectations
|
28
28
|
|
@@ -55,8 +55,8 @@ expectations can be used for state based and behavior based testing.
|
|
55
55
|
end
|
56
56
|
|
57
57
|
# Behavior based test on a concrete mock
|
58
|
-
expect Object.to_receive(:deal)
|
59
|
-
Object.deal
|
58
|
+
expect Object.to_receive(:deal) do
|
59
|
+
Object.deal
|
60
60
|
end
|
61
61
|
|
62
62
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Expectations::BehaviorBasedExpectation
|
2
|
+
include Mocha::Standalone
|
3
|
+
|
4
|
+
def execute
|
5
|
+
begin
|
6
|
+
mocha_setup
|
7
|
+
instance_exec expected.mock, &block
|
8
|
+
mock.verify
|
9
|
+
self.extend(Expectations::Results::Fulfilled)
|
10
|
+
rescue Mocha::ExpectationError => ex
|
11
|
+
self.extend(Expectations::Results::BehaviorFailure)
|
12
|
+
self.message = ex.message
|
13
|
+
rescue Exception => ex
|
14
|
+
self.extend(Expectations::Results::BehaviorBasedError)
|
15
|
+
self.exception = ex
|
16
|
+
ensure
|
17
|
+
mocha_teardown
|
18
|
+
end
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -1,48 +1,15 @@
|
|
1
1
|
class Expectations::Expectation
|
2
|
-
include Mocha::Standalone
|
3
2
|
|
4
3
|
attr_accessor :expected, :block, :file, :line, :actual
|
4
|
+
|
5
5
|
def initialize(expected, &block)
|
6
6
|
self.expected, self.block = expected, block
|
7
7
|
self.file, self.line = eval "[__FILE__, __LINE__]", block.binding
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
def behavior_based_execute
|
15
|
-
begin
|
16
|
-
mock = expected.instance_variable_get(:@mock)
|
17
|
-
mock.expectations.expectations.clear
|
18
|
-
mock.add_expectation(expected)
|
19
|
-
mocha_setup
|
20
|
-
instance_exec mock, &block
|
21
|
-
mock.verify
|
22
|
-
self.extend(Expectations::Results::Fulfilled)
|
23
|
-
rescue Mocha::ExpectationError => ex
|
24
|
-
self.extend(Expectations::Results::BehaviorFailure)
|
25
|
-
self.message = ex.message
|
26
|
-
rescue Exception => ex
|
27
|
-
self.extend(Expectations::Results::BehaviorBasedError)
|
28
|
-
self.exception = ex
|
29
|
-
ensure
|
30
|
-
mocha_teardown
|
31
|
-
end
|
32
|
-
self
|
33
|
-
end
|
34
|
-
|
35
|
-
def state_based_execute
|
36
|
-
begin
|
37
|
-
self.actual = block.call
|
38
|
-
return self.extend(Expectations::Results::Fulfilled) if expected == actual
|
39
|
-
rescue Exception => ex
|
40
|
-
return self.extend(Expectations::Results::Fulfilled) if expected == ex.class
|
41
|
-
self.extend(Expectations::Results::StateBasedError)
|
42
|
-
self.exception = ex
|
43
|
-
self.actual = ex.class if expected.is_a?(Class) && expected < StandardError
|
44
|
-
return self
|
8
|
+
if expected.is_a?(Expectations::MockRecorder)
|
9
|
+
extend(Expectations::BehaviorBasedExpectation)
|
10
|
+
else
|
11
|
+
extend(Expectations::StateBasedExpectation)
|
45
12
|
end
|
46
|
-
self.extend(Expectations::Results::StateBasedFailure)
|
47
13
|
end
|
14
|
+
|
48
15
|
end
|
data/lib/expectations/mocha.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
module Mocha
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
1
|
+
# module Mocha
|
2
|
+
# class Mock
|
3
|
+
# attr_reader :expectations
|
4
|
+
# alias to_receive expects
|
5
|
+
# end
|
6
|
+
# class ExpectationList
|
7
|
+
# attr_reader :expectations
|
8
|
+
# end
|
9
|
+
# end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Expectations::MockRecorder
|
2
|
+
attr_accessor :target
|
3
|
+
def initialize(target, method)
|
4
|
+
self.target = target
|
5
|
+
events << MockEvent.new(:expects, [method])
|
6
|
+
end
|
7
|
+
|
8
|
+
def events
|
9
|
+
@events ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_missing(method, *args)
|
13
|
+
events << MockEvent.new(method, args)
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def mock
|
18
|
+
events.inject(target) do |result, element|
|
19
|
+
result.send(element.method, *element.args)
|
20
|
+
end
|
21
|
+
target
|
22
|
+
end
|
23
|
+
|
24
|
+
class MockEvent
|
25
|
+
attr_accessor :method, :args
|
26
|
+
def initialize(method, args)
|
27
|
+
self.method, self.args = method, args
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/expectations/object.rb
CHANGED
data/lib/expectations/results.rb
CHANGED
@@ -25,7 +25,9 @@ module Expectations::Results
|
|
25
25
|
include Expectations::Results
|
26
26
|
char "F"
|
27
27
|
def message
|
28
|
-
"expected: <#{expected.inspect}> got: <#{actual.inspect}>"
|
28
|
+
result = "expected: <#{expected.inspect}> got: <#{actual.inspect}>"
|
29
|
+
result += "\nstring details: #{expected.diff(actual)}" if expected.is_a?(String) && actual.is_a?(String)
|
30
|
+
result
|
29
31
|
end
|
30
32
|
end
|
31
33
|
end
|
@@ -55,11 +57,8 @@ end
|
|
55
57
|
|
56
58
|
module Expectations::Results
|
57
59
|
module StateBasedError
|
58
|
-
attr_accessor :exception
|
60
|
+
attr_accessor :exception, :message
|
59
61
|
include Expectations::Results
|
60
62
|
char "E"
|
61
|
-
def message
|
62
|
-
"expected: <#{expected.inspect}> got: <#{actual.inspect}>"
|
63
|
-
end
|
64
63
|
end
|
65
64
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Expectations::StateBasedExpectation
|
2
|
+
def execute
|
3
|
+
begin
|
4
|
+
self.actual = block.call
|
5
|
+
return self.extend(Expectations::Results::Fulfilled) if expected == actual
|
6
|
+
rescue Exception => ex
|
7
|
+
return self.extend(Expectations::Results::Fulfilled) if expected == ex.class
|
8
|
+
self.extend(Expectations::Results::StateBasedError)
|
9
|
+
self.exception = ex
|
10
|
+
self.message = "expected: <#{expected.inspect}> got: <#{ex.class.inspect}>" if expected.is_a?(Class) && expected < StandardError
|
11
|
+
return self
|
12
|
+
end
|
13
|
+
self.extend(Expectations::Results::StateBasedFailure)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class String
|
2
|
+
def diff(other)
|
3
|
+
(0..self.size).inject("") do |result, index|
|
4
|
+
if self[index, 1] == other[index, 1]
|
5
|
+
result += self[index, 1]
|
6
|
+
else
|
7
|
+
result += "[#{self[index, 1]}|#{other[index, 1]}], mismatch at index #{index}\n"
|
8
|
+
result += "trailing expected: <#{self[index+1, self.size - index]}>\n"
|
9
|
+
result += "trailing actual: <#{other[index+1, other.size - index]}>"
|
10
|
+
return result
|
11
|
+
end
|
12
|
+
result
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/expectations/suite.rb
CHANGED
@@ -43,7 +43,8 @@ class Expectations::SuiteResults
|
|
43
43
|
out.puts "file <#{error.file}>"
|
44
44
|
out.puts "line <#{error.line}>"
|
45
45
|
out.puts "error <#{error.exception.message}>"
|
46
|
-
out.puts "#{error.
|
46
|
+
out.puts "trace #{filter_backtrace(error.exception.backtrace)}"
|
47
|
+
out.puts "#{error.message}" if error.message && error.message.any?
|
47
48
|
out.puts "\n"
|
48
49
|
end
|
49
50
|
out.puts "\n--Failures--" if failures.any?
|
@@ -55,4 +56,14 @@ class Expectations::SuiteResults
|
|
55
56
|
end
|
56
57
|
end
|
57
58
|
end
|
59
|
+
|
60
|
+
def filter_backtrace(trace)
|
61
|
+
patterns_to_strip = [/\/expectations\/lib\/expectations\//, /\/lib\/ruby\/1\.8\//]
|
62
|
+
result = patterns_to_strip.inject(trace) do |result, element|
|
63
|
+
result = result.select { |line| line !~ element}
|
64
|
+
end
|
65
|
+
result.collect do |line|
|
66
|
+
"\n #{line}"
|
67
|
+
end
|
68
|
+
end
|
58
69
|
end
|
data/lib/expectations.rb
CHANGED
@@ -11,9 +11,13 @@ require 'mocha/standalone'
|
|
11
11
|
require 'singleton'
|
12
12
|
require 'benchmark'
|
13
13
|
require File.expand_path(File.dirname(__FILE__) + '/expectations/object')
|
14
|
+
require File.expand_path(File.dirname(__FILE__) + '/expectations/string')
|
14
15
|
require File.expand_path(File.dirname(__FILE__) + '/expectations/mocha')
|
15
16
|
require File.expand_path(File.dirname(__FILE__) + '/expectations/suite')
|
16
17
|
require File.expand_path(File.dirname(__FILE__) + '/expectations/suite_runner')
|
17
18
|
require File.expand_path(File.dirname(__FILE__) + '/expectations/suite_results')
|
18
19
|
require File.expand_path(File.dirname(__FILE__) + '/expectations/expectation')
|
20
|
+
require File.expand_path(File.dirname(__FILE__) + '/expectations/behavior_based_expectation')
|
21
|
+
require File.expand_path(File.dirname(__FILE__) + '/expectations/state_based_expectation')
|
22
|
+
require File.expand_path(File.dirname(__FILE__) + '/expectations/mock_recorder')
|
19
23
|
require File.expand_path(File.dirname(__FILE__) + '/expectations/results')
|
data/rakefile.rb
CHANGED
@@ -16,8 +16,6 @@ Rake::RDocTask.new do |task|
|
|
16
16
|
task.rdoc_files.include('README', 'lib/**/*.rb')
|
17
17
|
end
|
18
18
|
|
19
|
-
task :rdoc => :readme
|
20
|
-
|
21
19
|
desc "Generate README"
|
22
20
|
task :readme do
|
23
21
|
%x[erb README_TEMPLATE > README]
|
@@ -25,7 +23,9 @@ end
|
|
25
23
|
|
26
24
|
|
27
25
|
desc "Upload RDoc to RubyForge"
|
28
|
-
task :publish_rdoc
|
26
|
+
task :publish_rdoc do
|
27
|
+
Rake::Task[:readme].invoke
|
28
|
+
Rake::Task[:rdoc].invoke
|
29
29
|
Rake::SshDirPublisher.new("jaycfields@rubyforge.org", "/var/www/gforge-projects/expectations", "doc").upload
|
30
30
|
end
|
31
31
|
|
@@ -41,7 +41,7 @@ specification = Gem::Specification.new do |s|
|
|
41
41
|
expect NoMethodError do
|
42
42
|
Object.invalid_method_call
|
43
43
|
end."
|
44
|
-
s.version = "0.0.
|
44
|
+
s.version = "0.0.7"
|
45
45
|
s.author = 'Jay Fields'
|
46
46
|
s.description = "A lightweight unit testing framework. Tests (expectations) will be written as follows
|
47
47
|
expect 2 do
|
@@ -13,10 +13,6 @@ Expectations do
|
|
13
13
|
Expectations::Expectation.new(1) { raise }.execute.is_a?(Expectations::Results::StateBasedError)
|
14
14
|
end
|
15
15
|
|
16
|
-
expect NoMethodError do
|
17
|
-
Expectations::Expectation.new(ArgumentError) { Object.no_method }.execute.actual
|
18
|
-
end
|
19
|
-
|
20
16
|
expect "undefined method `no_method' for Object:Class" do
|
21
17
|
Expectations::Expectation.new(ArgumentError) { Object.no_method }.execute.exception.to_s
|
22
18
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: expectations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jay Fields
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2008-01-06 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -22,10 +22,14 @@ extensions: []
|
|
22
22
|
extra_rdoc_files:
|
23
23
|
- README
|
24
24
|
files:
|
25
|
+
- lib/expectations/behavior_based_expectation.rb
|
25
26
|
- lib/expectations/expectation.rb
|
26
27
|
- lib/expectations/mocha.rb
|
28
|
+
- lib/expectations/mock_recorder.rb
|
27
29
|
- lib/expectations/object.rb
|
28
30
|
- lib/expectations/results.rb
|
31
|
+
- lib/expectations/state_based_expectation.rb
|
32
|
+
- lib/expectations/string.rb
|
29
33
|
- lib/expectations/suite.rb
|
30
34
|
- lib/expectations/suite_results.rb
|
31
35
|
- lib/expectations/suite_runner.rb
|
@@ -33,6 +37,7 @@ files:
|
|
33
37
|
- test/all_tests.rb
|
34
38
|
- test/expectations/expectation_test.rb
|
35
39
|
- test/expectations/results_test.rb
|
40
|
+
- test/expectations/string_test.rb
|
36
41
|
- test/expectations/suite_results_test.rb
|
37
42
|
- test/expectations/suite_test.rb
|
38
43
|
- test/sample_expectations_test.rb
|