rproof 0.0.1

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.md ADDED
@@ -0,0 +1,9 @@
1
+ Configuration to get Rproof working on your machine:
2
+
3
+ - clone this project into <local repositery folder>
4
+
5
+ - run gem install bundler if Bundler gem is not already install.
6
+
7
+ - in <local repositery folder>, run bundle install to install dependencies
8
+
9
+ - in <local repositery folder>/sample, run ruby run_rubyunit_test_sample to watch a simple test example
data/lib/rproof.rb ADDED
@@ -0,0 +1,16 @@
1
+ require_relative './rproof/abstract_reporter'
2
+ require_relative './rproof/assertion'
3
+ require_relative './rproof/censor'
4
+ require_relative './rproof/composite_reporter'
5
+ require_relative './rproof/live_reporter'
6
+ require_relative './rproof/located_info'
7
+ require_relative './rproof/test_result'
8
+ require_relative './rproof/test_runner'
9
+ require_relative './rproof/test_suite'
10
+ require_relative './rproof/test'
11
+ require_relative './rproof/xml_reporter'
12
+ require_relative './rproof/warning'
13
+
14
+ module Rproof
15
+
16
+ end
@@ -0,0 +1,37 @@
1
+ ########################################################################################################################
2
+ # Defines the interface of a reporter.
3
+ ########################################################################################################################
4
+
5
+ require_relative 'test_result'
6
+
7
+ module Rproof
8
+ class AbstractReporter
9
+ def report_campaign_begin
10
+ end
11
+
12
+ def report_suite_begin(id, name, description)
13
+ end
14
+
15
+ def report_test_begin(id, name, description)
16
+ end
17
+
18
+ def report_assertion(assertion)
19
+ end
20
+
21
+ def report_warning(warning)
22
+ end
23
+
24
+ def report_exception(exception)
25
+ end
26
+
27
+ def report_test_end(id, test_result)
28
+ end
29
+
30
+ def report_suite_end(id, test_results)
31
+ end
32
+
33
+ # test_results is either a Test_Result or a Test_Result Array
34
+ def report_campaign_end(test_results, start_time, end_time)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ ########################################################################################################################
2
+ # Stores assertion result information
3
+ ########################################################################################################################
4
+
5
+ require_relative 'located_info'
6
+
7
+ module Rproof
8
+ class Assertion < LocatedInfo
9
+ def initialize(expected, obtained, is_successful, comment)
10
+ super()
11
+ @expected = expected
12
+ @obtained = obtained
13
+ @is_successful = is_successful
14
+ @comment = comment
15
+ end
16
+ attr_reader :expected, :obtained, :is_successful, :comment
17
+ end
18
+ end
@@ -0,0 +1,52 @@
1
+ ########################################################################################################################
2
+ # Provide various assertion, warning and exception methods
3
+ ########################################################################################################################
4
+
5
+ require_relative 'abstract_reporter'
6
+ require_relative 'assertion'
7
+ require_relative 'test_result'
8
+ require_relative 'warning'
9
+
10
+ module Rproof
11
+ class Censor
12
+ def initialize(reporter, name, description)
13
+ @reporter = reporter
14
+ @test_result = TestResult.new name, description
15
+ end
16
+ attr_reader :test_result
17
+
18
+ def assert_different(expected, obtained, comment)
19
+ @test_result.add_assertion Assertion.new(expected, obtained, (obtained != expected), comment)
20
+ @reporter.report_assertion @test_result.assertions.last
21
+ end
22
+
23
+ def assert_equal(expected, obtained, comment)
24
+ @test_result.add_assertion Assertion.new(expected, obtained, (obtained == expected), comment)
25
+ @reporter.report_assertion @test_result.assertions.last
26
+ end
27
+
28
+ def assert_exception(expected, comment, &block)
29
+ error = nil
30
+ begin
31
+ block.call
32
+ rescue Exception => error
33
+ ensure
34
+ assert_equal(expected, error.class, comment)
35
+ end
36
+ end
37
+
38
+ def assert(statement, comment)
39
+ assert_equal true, statement, comment
40
+ end
41
+
42
+ def warning(message)
43
+ @test_result.add_warning Warning.new(message)
44
+ @reporter.report_warning @test_result.warnings.last
45
+ end
46
+
47
+ def log_exception(error)
48
+ @test_result.add_exception error
49
+ @reporter.report_exception @test_result.exceptions.last
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,53 @@
1
+ ########################################################################################################################
2
+ #
3
+ ########################################################################################################################
4
+
5
+ require_relative 'abstract_reporter'
6
+
7
+ module Rproof
8
+ class CompositeReporter < AbstractReporter
9
+ def initialize
10
+ @reporters = []
11
+ end
12
+
13
+ def add(reporter)
14
+ @reporters << reporter
15
+ end
16
+
17
+ def report_campaign_begin
18
+ @reporters.each { |r| r.report_campaign_begin }
19
+ end
20
+
21
+ def report_suite_begin(id, name, description)
22
+ @reporters.each { |r| r.report_suite_begin id, name, description }
23
+ end
24
+
25
+ def report_test_begin(id, name, description)
26
+ @reporters.each { |r| r.report_test_begin id, name, description }
27
+ end
28
+
29
+ def report_assertion(assertion)
30
+ @reporters.each { |r| r.report_assertion assertion }
31
+ end
32
+
33
+ def report_warning(warning)
34
+ @reporters.each { |r| r.report_warning warning }
35
+ end
36
+
37
+ def report_exception(exception)
38
+ @reporters.each { |r| r.report_exception exception }
39
+ end
40
+
41
+ def report_test_end(id, test_result)
42
+ @reporters.each { |r| r.report_test_end id, test_result }
43
+ end
44
+
45
+ def report_suite_end(id, test_results)
46
+ @reporters.each { |r| r.report_suite_end id, test_results }
47
+ end
48
+
49
+ def report_campaign_end(test_results, start_time, end_time)
50
+ @reporters.each { |r| r.report_campaign_end test_results, start_time, end_time }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,161 @@
1
+ ########################################################################################################################
2
+ # Implements a live reporter: assertion results are shown on-the-flow, with two verbose levels: dotted or full.
3
+ ########################################################################################################################
4
+
5
+ require 'colorize'
6
+
7
+ require_relative 'abstract_reporter'
8
+ require_relative 'assertion'
9
+
10
+ module Rproof
11
+ class LiveReporter < AbstractReporter
12
+
13
+ OK = '['.bold + 'OK'.green.bold + ']'.bold
14
+ KO = '['.bold + 'KO'.red.bold + ']'.bold
15
+ WA = '['.bold + 'W!'.yellow.bold + ']'.bold
16
+ WARNING = '/!\\ WARNING /!\\'.yellow.bold
17
+
18
+ STATUS = {
19
+ untested: 'untested'.bold.on_blue,
20
+ exception: 'exception'.bold.on_magenta,
21
+ failed: 'failed'.bold.red,
22
+ warning: 'succeed'.bold.green + ' with ' + 'warnings'.bold.yellow,
23
+ succeed: 'succeed'.bold.green
24
+ }
25
+
26
+ INDENT = " "
27
+
28
+ def initialize(verbose: false, cli_width: 80, justification: ([60, cli_width - 100].max))
29
+ @verbose = verbose
30
+ @justification = justification
31
+ end
32
+
33
+ def report_campaign_begin
34
+ if @verbose
35
+ puts "Running test campaign..."
36
+ end
37
+ end
38
+
39
+ def report_suite_begin(id, name, description)
40
+ end
41
+
42
+ def report_test_begin(id, name, description)
43
+ if @verbose
44
+ puts
45
+ puts '-' * 120
46
+ puts "Running #{name}"
47
+ puts description
48
+ puts
49
+ end
50
+ end
51
+
52
+ def report_assertion(assertion)
53
+ if @verbose
54
+ if assertion.is_successful
55
+ puts "#{INDENT}#{(assertion.comment + ' ').ljust(@justification, '_')} #{OK} obtained #{assertion.obtained.inspect}"
56
+ else
57
+ puts "#{INDENT}#{(assertion.comment + ' ').ljust(@justification, '_')} #{KO} expected #{assertion.expected.inspect}"
58
+ puts "#{INDENT}#{' ' * @justification} obtained #{assertion.obtained.inspect}"
59
+ end
60
+ end
61
+ end
62
+
63
+ def report_warning(warning)
64
+ if @verbose
65
+ puts "#{INDENT}#{WARNING} #{warning.message}"
66
+ end
67
+ end
68
+
69
+ def report_exception(exception)
70
+ if @verbose
71
+ puts "#{INDENT}exception: " + exception.message.bold.on_magenta
72
+ puts INDENT + exception.backtrace.join("\n#{INDENT}").bold.magenta
73
+ end
74
+ end
75
+
76
+ def report_test_end(id, test_result)
77
+ if @verbose
78
+ puts
79
+ puts "End: #{STATUS[test_result.status]}. #{test_result.successes_nb} successes, #{test_result.failures_nb} failures, #{test_result.warnings.count} warnings, #{test_result.exceptions.count} exceptions"
80
+ else
81
+ case
82
+ when !test_result.exceptions.empty? then dot = "E".bold.on_magenta
83
+ when !test_result.failures.empty? then dot = "F".bold.red
84
+ when !test_result.warnings.empty? then dot = "W".bold.yellow
85
+ else dot = "."
86
+ end
87
+ print dot
88
+ end
89
+ end
90
+
91
+ def report_suite_end(id, test_results)
92
+ end
93
+
94
+ def report_campaign_end(test_results, start_time, end_time)
95
+ if test_results.is_a? Array # if false, campaign was a single test
96
+ campaign_status = :succeed
97
+ successes_nb = 0
98
+ failures_nb = 0
99
+ warnings_nb = 0
100
+ exceptions_nb = 0
101
+
102
+ results = test_results.flatten
103
+ results.each do |result|
104
+ campaign_status = TestResult.get_worse_status campaign_status, result.status
105
+ successes_nb += result.successes_nb
106
+ failures_nb += result.failures_nb
107
+ warnings_nb += result.warnings.count
108
+ exceptions_nb += result.exceptions.count
109
+ end
110
+ if @verbose
111
+ puts
112
+ puts "End of campaign: #{STATUS[campaign_status]}. #{successes_nb} successes, #{failures_nb} failures, #{warnings_nb} warnings, #{exceptions_nb} exceptions"
113
+ else
114
+ puts
115
+ puts "#{STATUS[campaign_status]} in #{end_time - start_time}. #{successes_nb} successes, #{failures_nb} failures, #{warnings_nb} warnings, #{exceptions_nb} exceptions"
116
+ if warnings_nb > 0
117
+ puts
118
+ puts " warnings:"
119
+ results.each do |result|
120
+ result.warnings.each do |warning|
121
+ full_comment = "in #{warning.file}:#{warning.line}:#{warning.method}: #{warning.message} "
122
+ puts " #{full_comment.ljust(@justification, '_')} #{WA}"
123
+ end
124
+ end
125
+ end
126
+ if failures_nb > 0
127
+ puts
128
+ puts " failures:"
129
+ results.each do |result|
130
+ result.failures.each do |failure|
131
+ full_comment = "in #{failure.file}:#{failure.line}:#{failure.method}: #{failure.comment} "
132
+ puts " #{full_comment.ljust(@justification, '_')} #{KO} #{"expected".bold} #{failure.expected.inspect}, #{"obtained".bold} #{failure.obtained.inspect}"
133
+ end
134
+ end
135
+ end
136
+ if exceptions_nb > 0
137
+ print_header('exceptions')
138
+ print_exceptions(results)
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ private
145
+
146
+ def print_header(header)
147
+ puts
148
+ puts " #{header}:"
149
+ end
150
+
151
+ def print_exceptions(results)
152
+ results.each do |result|
153
+ result.exceptions.each do |exception|
154
+ puts " " + exception.message.bold.on_magenta
155
+ puts " " + exception.backtrace.join("\n ").bold.magenta
156
+ end
157
+ end
158
+ end
159
+
160
+ end
161
+ end
@@ -0,0 +1,28 @@
1
+ ########################################################################################################################
2
+ # Determines and stored location data for a test information
3
+ ########################################################################################################################
4
+
5
+ require 'pathname'
6
+
7
+ module Rproof
8
+ class LocatedInfo
9
+ def initialize
10
+ @pathname = nil
11
+ @file = nil
12
+ @line = nil
13
+ @method = nil
14
+ caller.each do |line|
15
+ matches = line.match /^.*\.rb/
16
+ pathname = Pathname.new(matches[0])
17
+ if not pathname.to_s.match(/lib\/(censor)|(assertion)|(warning)\.rb$/) and nil == @file # ignore lib files, until test definition file
18
+ @pathname = pathname
19
+ @file = pathname.basename
20
+ matches = line.match /^.*\.rb:(\d*):in `([^']*)'/
21
+ @line = matches[1]
22
+ @method = matches[2]
23
+ end
24
+ end
25
+ end
26
+ attr_reader :pathname, :file, :line, :method
27
+ end
28
+ end
@@ -0,0 +1,41 @@
1
+ ########################################################################################################################
2
+ # Define an atomic test. This class has to be inherited in child classes, where the developer writes test code.
3
+ ########################################################################################################################
4
+
5
+ require_relative 'abstract_reporter'
6
+ require_relative 'censor'
7
+
8
+ module Rproof
9
+ class Test
10
+ def initialize(reporter, name, description = nil)
11
+ @id = object_id
12
+ @reporter = reporter
13
+ @name = name
14
+ @description = description
15
+ @censor = Censor.new reporter, name, description
16
+ end
17
+
18
+ def setup
19
+ end
20
+
21
+ def run
22
+ raise "This method has to be overriden. Please redefine 'run' method with your test code."
23
+ end
24
+
25
+ def clean_up
26
+ end
27
+
28
+ def execute
29
+ @reporter.report_test_begin(@id, @name, @description)
30
+ begin
31
+ setup
32
+ run
33
+ clean_up
34
+ rescue Exception => e
35
+ @censor.log_exception e
36
+ end
37
+ @reporter.report_test_end(@id, @censor.test_result)
38
+ @censor.test_result
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,63 @@
1
+ require_relative 'assertion'
2
+
3
+ module Rproof
4
+ class TestResult
5
+ def initialize(name, description)
6
+ @name = name
7
+ @description = description
8
+ @assertions = []
9
+ @warnings = []
10
+ @exceptions = []
11
+ end
12
+ attr_reader :name, :description, :assertions, :warnings, :exceptions
13
+
14
+ def add_assertion(assertion)
15
+ @assertions << assertion
16
+ end
17
+
18
+ def add_warning(warning)
19
+ @warnings << warning
20
+ end
21
+
22
+ def add_exception(exception)
23
+ @exceptions << exception
24
+ end
25
+
26
+ def successes_nb
27
+ successes.count
28
+ end
29
+
30
+ def failures_nb
31
+ failures.count
32
+ end
33
+
34
+ def successes
35
+ @assertions.select { |assertion| assertion.is_successful }
36
+ end
37
+
38
+ def failures
39
+ @assertions.select { |assertion| not assertion.is_successful }
40
+ end
41
+
42
+ def status
43
+ if @exceptions.count > 0
44
+ :exception
45
+ elsif failures_nb > 0
46
+ :failed
47
+ else
48
+ :succeed
49
+ end
50
+ end
51
+
52
+ # Return worse status between the two
53
+ def self.get_worse_status(status_1, status_2)
54
+ if [status_1, status_2].include? :exception
55
+ :exception
56
+ elsif [status_1, status_2].include? :failed
57
+ :failed
58
+ else
59
+ :succeed
60
+ end
61
+ end
62
+ end
63
+ end