rasta 0.1.8-x86-mswin32-60
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +32 -0
- data/README.txt +15 -0
- data/bin/rasta +4 -0
- data/examples/crud_worksheet.xls +0 -0
- data/examples/fixtures/ColumnLayout.rb +34 -0
- data/examples/fixtures/HtmlRegistration.rb +103 -0
- data/examples/fixtures/MathFunctions.rb +21 -0
- data/examples/fixtures/StringFunctions.rb +18 -0
- data/examples/fixtures/crud/CrudClass.rb +62 -0
- data/examples/fixtures/crud/CrudFixture.rb +37 -0
- data/examples/html/registration.html +102 -0
- data/examples/rasta_fixture.xls +0 -0
- data/examples/tests_in_column_layout.xls +0 -0
- data/examples/watir_example.xls +0 -0
- data/lib/rasta/extensions/rspec_extensions.rb +174 -0
- data/lib/rasta/fixture/base_fixture.rb +138 -0
- data/lib/rasta/fixture/rasta_fixture.rb +183 -0
- data/lib/rasta/fixture_runner.rb +195 -0
- data/lib/rasta/formatter/spreadsheet_formatter.rb +32 -0
- data/lib/rasta/spreadsheet.rb +528 -0
- data/lib/rasta/version.rb +9 -0
- data/lib/rasta.rb +198 -0
- data/test/fixtures/RastaTestFixture.rb +9 -0
- data/test/spreadsheets/rasta_fixture.xls +0 -0
- data/test/spreadsheets/spreadsheet_parsing.xls +0 -0
- data/test/test_bookmarks.rb +138 -0
- data/test/test_fixtures.rb +66 -0
- data/test/test_spreadsheet.rb +337 -0
- metadata +98 -0
@@ -0,0 +1,138 @@
|
|
1
|
+
|
2
|
+
module Rasta
|
3
|
+
module Fixture
|
4
|
+
module BaseFixture
|
5
|
+
def initialize_run(sheet)
|
6
|
+
@sheet = sheet
|
7
|
+
@metrics = Metrics.new
|
8
|
+
end
|
9
|
+
|
10
|
+
# Called by fixture.rb on each worksheet
|
11
|
+
def run
|
12
|
+
generate_rspec_tests
|
13
|
+
teardown_tests
|
14
|
+
end
|
15
|
+
|
16
|
+
# Call into rspec to run the current set of tests
|
17
|
+
# and then remove the example from the group which
|
18
|
+
# if we dont will run test 1 then test 1,2 then test 1,2,3
|
19
|
+
# and we'll get duplicate test results accordingly
|
20
|
+
def run_rspec_test
|
21
|
+
Spec::Runner.options.run_examples
|
22
|
+
Spec::Runner.options.remove_example_group(Spec::Runner.options.example_groups[0])
|
23
|
+
end
|
24
|
+
|
25
|
+
# This is called after all testcases are run
|
26
|
+
# for the worksheet.
|
27
|
+
def teardown_tests
|
28
|
+
@sheet.select_home_cell
|
29
|
+
end
|
30
|
+
|
31
|
+
# Allow access to the current failure count from RSpec
|
32
|
+
# which will let us change the tab color based on the test results
|
33
|
+
def current_failure_count
|
34
|
+
Spec::Runner.options.reporter.failure_count
|
35
|
+
end
|
36
|
+
|
37
|
+
# Iterate over spreadsheet cells, create the
|
38
|
+
# test fixtures and call your test. Generally
|
39
|
+
# you will need to iterate over the spreadsheet
|
40
|
+
# cells and once you have the information you need
|
41
|
+
# to actually run the rspec test you should
|
42
|
+
# use:
|
43
|
+
# select_output_cell(cell)
|
44
|
+
# This tells the reporter which spreadsheet
|
45
|
+
# cell should get the results
|
46
|
+
# create_rspec_test(test_fixture, cell)
|
47
|
+
# This is a method you create which will create
|
48
|
+
# rspec testcase(s) based on the inputs
|
49
|
+
# run_rspec_test
|
50
|
+
# This will run the test set up by create_test
|
51
|
+
def generate_rspec_tests
|
52
|
+
end
|
53
|
+
|
54
|
+
# This is the guts of the rspec test you want to call
|
55
|
+
# so for example something like
|
56
|
+
#
|
57
|
+
# describe 'test' do
|
58
|
+
# before(:all) do
|
59
|
+
# end
|
60
|
+
# it "testcase 1" do
|
61
|
+
# end
|
62
|
+
# it "testcase 2" do
|
63
|
+
# end
|
64
|
+
# ... etc ...
|
65
|
+
# after(:all) do
|
66
|
+
# end
|
67
|
+
# end
|
68
|
+
def create_rspec_test(args)
|
69
|
+
end
|
70
|
+
|
71
|
+
# This is how the fixture notifies the rspec reporter
|
72
|
+
# which spreadsheet cell to dump the results into
|
73
|
+
def select_output_cell(c)
|
74
|
+
Spec::Runner.options.reporter.set_current_spreadsheet_cell = c
|
75
|
+
end
|
76
|
+
|
77
|
+
# ==================================================
|
78
|
+
# Dont enable these, even in the base fixture or
|
79
|
+
# it could fail if the function is in a superclass of
|
80
|
+
# the test fixture. These are here to show what could
|
81
|
+
# be in the test fixture and if so we'll call them
|
82
|
+
|
83
|
+
# This is called by the fixture before any test
|
84
|
+
# is run on the worksheet so you can perform any
|
85
|
+
# setup needed
|
86
|
+
#def before_all
|
87
|
+
#end
|
88
|
+
|
89
|
+
# This method is called before each set of tests
|
90
|
+
# typically a row or column of tests or potentially
|
91
|
+
# before each cell, depending on the fixture
|
92
|
+
#def before_each
|
93
|
+
#end
|
94
|
+
|
95
|
+
# This method is called after each set of tests
|
96
|
+
# typically a row or column of tests or potentially
|
97
|
+
# after each cell, depending on the fixture
|
98
|
+
#def after_each
|
99
|
+
#end
|
100
|
+
|
101
|
+
# This is called by the fixture after all tests
|
102
|
+
# are run on the worksheet so you can perform any
|
103
|
+
# teardown needed
|
104
|
+
#def after_all
|
105
|
+
#end
|
106
|
+
# ==================================================
|
107
|
+
|
108
|
+
|
109
|
+
# Store metrics as the fixture is running
|
110
|
+
class Metrics
|
111
|
+
attr_accessor :attribute_count, :method_count, :record_count
|
112
|
+
def initialize
|
113
|
+
reset_page_counts
|
114
|
+
reset_record_counts
|
115
|
+
end
|
116
|
+
# Counts tracked on a worksheet scope
|
117
|
+
def reset_page_counts
|
118
|
+
@record_count = 0
|
119
|
+
end
|
120
|
+
# Counts tracked on a record scope
|
121
|
+
def reset_record_counts
|
122
|
+
@attribute_count = 0
|
123
|
+
@method_count = 0
|
124
|
+
end
|
125
|
+
def inc(attribute_name)
|
126
|
+
eval("@#{attribute_name.to_s} += 1")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Store any extention in the tab name. This can be used to pass
|
131
|
+
# additional information to the fixture
|
132
|
+
def tab_extension=(x)
|
133
|
+
@tab_extension = x
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'rasta/fixture/base_fixture'
|
3
|
+
|
4
|
+
module Rasta
|
5
|
+
module Fixture
|
6
|
+
module RastaFixture
|
7
|
+
include Rasta::Fixture::BaseFixture
|
8
|
+
attr_accessor :pending, :comment
|
9
|
+
|
10
|
+
GREEN = 35
|
11
|
+
RED = 40
|
12
|
+
|
13
|
+
def generate_rspec_tests
|
14
|
+
@metrics.reset_page_counts
|
15
|
+
@test_fixture = self
|
16
|
+
initial_failure_count = current_failure_count
|
17
|
+
|
18
|
+
try(:before_all)
|
19
|
+
@sheet.each do |record|
|
20
|
+
@metrics.reset_record_counts
|
21
|
+
@current_record = record
|
22
|
+
@metrics.inc(:record_count)
|
23
|
+
@test_fixture = self.dup #make a copy so attributes don't bleed between rows
|
24
|
+
try(:before_each)
|
25
|
+
record.each do |cell|
|
26
|
+
call_test_fixture(cell)
|
27
|
+
end
|
28
|
+
try(:after_each)
|
29
|
+
@test_fixture = self
|
30
|
+
end
|
31
|
+
try(:after_all)
|
32
|
+
|
33
|
+
update_tab_color(current_failure_count > initial_failure_count)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Check to see if the cell's header is an attribute
|
37
|
+
# or a method and call it or raise an error
|
38
|
+
def call_test_fixture(cell)
|
39
|
+
name = cell.header
|
40
|
+
return if cell.value.nil? || cell.header.nil?
|
41
|
+
if cell.header == 'pending'
|
42
|
+
@test_fixture.pending = cell.value
|
43
|
+
elsif self.methods.include?(name + '=')
|
44
|
+
call_fixture_attribute(name, cell.value)
|
45
|
+
else
|
46
|
+
# don't specifically check that the method
|
47
|
+
# exists so we can allow for things like
|
48
|
+
# dynamic methods. An exception still gets thrown
|
49
|
+
# so we should be able to handle missing methods
|
50
|
+
call_fixture_method(cell)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# For cell headers detected as test fixture
|
55
|
+
# attributes, set the attribute
|
56
|
+
def call_fixture_attribute(name, value)
|
57
|
+
@metrics.inc(:attribute_count)
|
58
|
+
@test_fixture.send("#{name}=", value)
|
59
|
+
end
|
60
|
+
|
61
|
+
# For cell headers detected as test fixture
|
62
|
+
# methods, call the method and run the rspec test
|
63
|
+
def call_fixture_method(cell)
|
64
|
+
@metrics.inc(:method_count)
|
65
|
+
create_rspec_test(cell)
|
66
|
+
run_rspec_test
|
67
|
+
end
|
68
|
+
|
69
|
+
# Given a cell that is a method call
|
70
|
+
# create an rspec test that can check the
|
71
|
+
# return value and handle any exceptions
|
72
|
+
def create_rspec_test(cell)
|
73
|
+
select_output_cell(cell)
|
74
|
+
test_method_name = "#{cell.header}()"
|
75
|
+
test_fixture = @test_fixture
|
76
|
+
describe "#{cell.sheet.name}[#{cell.name}]" do
|
77
|
+
include TestCaseHelperMethods
|
78
|
+
|
79
|
+
before(:all) do
|
80
|
+
@fixture = test_fixture
|
81
|
+
@cell = cell
|
82
|
+
@@actual_value = nil
|
83
|
+
# If the cell's value is an exception, parse it out so we can handle properly
|
84
|
+
@exception_expected = !(@cell.value.to_s =~ /^error\s*((?:(?!:\s).)*):?\s*(.*)/).nil?
|
85
|
+
if @exception_expected
|
86
|
+
@exception = eval($1) if $1 != ''
|
87
|
+
@exception_message = $2 if $2 != ''
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it "#{test_method_name} should handle exceptions" do
|
92
|
+
set_pending_status
|
93
|
+
check_for_errors
|
94
|
+
end
|
95
|
+
it "#{test_method_name} should == #{cell.value.to_s}" do
|
96
|
+
set_pending_status
|
97
|
+
check_test_result
|
98
|
+
end
|
99
|
+
|
100
|
+
after(:all) do
|
101
|
+
@fixture = nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def update_tab_color(result)
|
107
|
+
result ? @sheet.ole_object.Tab.ColorIndex = RED : @sheet.ole_object.Tab.ColorIndex = GREEN
|
108
|
+
end
|
109
|
+
private :update_tab_color
|
110
|
+
|
111
|
+
module TestCaseHelperMethods
|
112
|
+
@@actual_value = nil
|
113
|
+
def check_for_errors
|
114
|
+
if @exception_expected
|
115
|
+
if @exception
|
116
|
+
lambda{ @fixture.send @cell.header }.should raise_error(@exception, @exception_message)
|
117
|
+
else
|
118
|
+
lambda{ @fixture.send @cell.header }.should raise_error
|
119
|
+
end
|
120
|
+
else
|
121
|
+
lambda{ @@actual_value = @fixture.send @cell.header }.should_not raise_error
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def check_test_result
|
126
|
+
return if @exception_expected
|
127
|
+
# Allow spreadsheet values of nil be captured to
|
128
|
+
# run methods that do not have a return. This is done
|
129
|
+
# this way because if we tranlated the cell value to nil then
|
130
|
+
# we couldn't tell the difference between a cell=nil vs an empty cell
|
131
|
+
if @cell.value == 'nil'
|
132
|
+
expected_value = nil
|
133
|
+
else
|
134
|
+
expected_value = @cell.value
|
135
|
+
end
|
136
|
+
case expected_value
|
137
|
+
when /^(<=|>=|>|<)(.+)/
|
138
|
+
eval("@@actual_value.should #{$1} #{$2}")
|
139
|
+
when Regexp
|
140
|
+
@@actual_value.should =~ expected_value
|
141
|
+
else
|
142
|
+
@@actual_value.should == expected_value
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def set_pending_status
|
147
|
+
if @fixture.methods.include?('pending') and @fixture.pending
|
148
|
+
pending(@fixture.pending)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
# Call a method in the test fixture and if it
|
155
|
+
# throws an exception, create an rspec test. This
|
156
|
+
# is not for standard tests, but for setup and
|
157
|
+
# teardown tasks that should happen but are not part
|
158
|
+
# of the actual test cases.
|
159
|
+
def try(method)
|
160
|
+
return if !method
|
161
|
+
if @test_fixture.methods.include?(method.to_s)
|
162
|
+
begin
|
163
|
+
@test_fixture.send method
|
164
|
+
rescue SystemExit
|
165
|
+
exit
|
166
|
+
rescue Interrupt
|
167
|
+
exits
|
168
|
+
rescue => error_message
|
169
|
+
# If the method gets an error, re-raise the error
|
170
|
+
# in the context of rspec so the results pick it up
|
171
|
+
describe "#{@test_fixture.class}[#{@current_record.to_s}] #{method.to_s}()" do
|
172
|
+
it "should not throw an exception" do
|
173
|
+
lambda{raise error_message}.should_not raise_error
|
174
|
+
end
|
175
|
+
end
|
176
|
+
run_rspec_test
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
@@ -0,0 +1,195 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Rasta
|
4
|
+
|
5
|
+
module Fixture
|
6
|
+
|
7
|
+
# Load and run a fixture, indicated by the spreadsheet tab name
|
8
|
+
class FixtureLoader
|
9
|
+
|
10
|
+
def initialize(sheet, loaded_classes)
|
11
|
+
|
12
|
+
# We're making an assumption here
|
13
|
+
# that the fixture class matches the
|
14
|
+
# spreadsheet tab name for the fixture
|
15
|
+
base_sheet_name = sheet.name.dup
|
16
|
+
base_sheet_name.gsub!(/#.*/, '')
|
17
|
+
|
18
|
+
# If the tab name has a dotted extension, grab it
|
19
|
+
tab_extension = base_sheet_name[/\..*/].sub(/^./,'') if base_sheet_name[/\..*/]
|
20
|
+
|
21
|
+
# Remove any extension found from the name
|
22
|
+
base_sheet_name.gsub!(/\..*/, '')
|
23
|
+
|
24
|
+
# Get a reference to the loaded class
|
25
|
+
classname = find_class_by_name(base_sheet_name, loaded_classes)
|
26
|
+
|
27
|
+
# Instantiate the test fixture
|
28
|
+
begin
|
29
|
+
fixture = classname.new
|
30
|
+
fixture.initialize_run(sheet)
|
31
|
+
fixture.tab_extension = tab_extension
|
32
|
+
rescue ArgumentError => e
|
33
|
+
raise ArgumentError, "Unable to load class #{@classname}. Make sure the class includes the Rasta fixture: #{e.inspect + e.backtrace.join("\n")}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Run the test fixture
|
37
|
+
fixture.run
|
38
|
+
fixture = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_class_by_name(classname, loaded_classes)
|
42
|
+
config = Configuration.instance
|
43
|
+
ObjectSpace.each_object(Class) do |klass|
|
44
|
+
# don't try to load a class unless it is
|
45
|
+
# something we actually loaded ourselves
|
46
|
+
next unless loaded_classes.include?(klass.name)
|
47
|
+
if config.module
|
48
|
+
return klass if klass.name =~ /#{config.module}::#{classname}$/
|
49
|
+
else
|
50
|
+
return klass if klass.name =~ /(^|:)#{classname}$/
|
51
|
+
end
|
52
|
+
end
|
53
|
+
raise ArgumentError, "Class '#{config.module}::#{classname}' not found!"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Manage requests to run spreadsheets and send each to the FixtureLoader
|
58
|
+
class FixtureRunner
|
59
|
+
def initialize
|
60
|
+
@workbooks = []
|
61
|
+
prepare_results_directory
|
62
|
+
end
|
63
|
+
|
64
|
+
def add(spreadsheet)
|
65
|
+
require 'rasta/spreadsheet'
|
66
|
+
raise IOError, "File not found: #{spreadsheet}" if ! File.exists?(File.expand_path(spreadsheet))
|
67
|
+
workingfile = copy(spreadsheet)
|
68
|
+
config = Configuration.instance
|
69
|
+
@excel = Rasta::Spreadsheet::Excel.instance
|
70
|
+
@excel.pagecount = config.pagecount.to_i
|
71
|
+
@excel.recordcount = config.recordcount.to_i
|
72
|
+
@excel.continue = config.continue
|
73
|
+
@excel.visible = config.visible
|
74
|
+
@workbooks << workingfile
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Copies the spreadsheet with results in the [results_path] parameter
|
79
|
+
# provided when calling runxls.rb. If no parameter is provided, the results
|
80
|
+
# are saved into the results folder within the working dir.
|
81
|
+
def copy(spreadsheet)
|
82
|
+
config = Configuration.instance
|
83
|
+
testfilename = generate_testfile(spreadsheet)
|
84
|
+
while File.exists?(File.expand_path(testfilename))
|
85
|
+
testfilename = generate_testfile(spreadsheet)
|
86
|
+
end
|
87
|
+
FileUtils.cp(spreadsheet, testfilename)
|
88
|
+
return testfilename
|
89
|
+
end
|
90
|
+
def generate_testfile(spreadsheet)
|
91
|
+
config = Configuration.instance
|
92
|
+
config.result_index += 1
|
93
|
+
filename = config.results_path + '/' + File.basename(spreadsheet)
|
94
|
+
filename.sub!(/(\.\w{3})$/, ".#{config.result_index}" + '\1')
|
95
|
+
return filename
|
96
|
+
end
|
97
|
+
def prepare_results_directory
|
98
|
+
config = Configuration.instance
|
99
|
+
if File.expand_path(config.results_path) != config.results_path
|
100
|
+
config.results_path = Dir.getwd + '/' + config.results_path
|
101
|
+
end
|
102
|
+
# Remove the existing results
|
103
|
+
begin
|
104
|
+
FileUtils.rm(Dir.glob(File.join(config.results_path, "*"))) if File.exists?(config.results_path)
|
105
|
+
rescue Errno::EACCES
|
106
|
+
# The file is probably open so ignore and we'll create a new file
|
107
|
+
end
|
108
|
+
# Create a new results directory
|
109
|
+
begin
|
110
|
+
FileUtils.mkdir_p(config.results_path) if !File.exists?(config.results_path)
|
111
|
+
rescue => e
|
112
|
+
puts "Creating directory #{config.results_path}"
|
113
|
+
raise IOError, e.message
|
114
|
+
end
|
115
|
+
end
|
116
|
+
# Load the files in the fixture path and
|
117
|
+
# track which classes got loaded so we can hopefully
|
118
|
+
# reduce the chance of namespace issues. There may
|
119
|
+
# be a better way to handle this
|
120
|
+
def load_test_fixtures
|
121
|
+
before_classes = []
|
122
|
+
after_classes = []
|
123
|
+
ObjectSpace.each_object(Class) { |x| before_classes << x.name }
|
124
|
+
config = Configuration.instance
|
125
|
+
if config.require.size > 0
|
126
|
+
config.require.each { |file| do_require file }
|
127
|
+
else
|
128
|
+
# Look through all of the .rb files in the fixture path to see if
|
129
|
+
# we can find the file that has the class specified
|
130
|
+
if File.directory?(config.fixture_path)
|
131
|
+
fixture_files = File.join(config.fixture_path.gsub('\\','/'), "**", "*.rb")
|
132
|
+
Dir.glob(fixture_files).each {|f| do_require f }
|
133
|
+
else
|
134
|
+
do_require config.fixture_path
|
135
|
+
end
|
136
|
+
end
|
137
|
+
ObjectSpace.each_object(Class) { |x| after_classes << x.name }
|
138
|
+
return (after_classes - before_classes)
|
139
|
+
end
|
140
|
+
|
141
|
+
def do_require(filename)
|
142
|
+
raise LoadError, "Unable to require file '#{filename}'" unless require filename
|
143
|
+
end
|
144
|
+
|
145
|
+
def execute
|
146
|
+
loaded_classes = load_test_fixtures
|
147
|
+
initialize_rspec
|
148
|
+
begin
|
149
|
+
start_rspec
|
150
|
+
@workbooks.each do |workbook|
|
151
|
+
begin
|
152
|
+
book = Rasta::Spreadsheet::Book.new(workbook)
|
153
|
+
book.each do |sheet|
|
154
|
+
FixtureLoader.new(sheet, loaded_classes)
|
155
|
+
end
|
156
|
+
ensure
|
157
|
+
book.save
|
158
|
+
end
|
159
|
+
end
|
160
|
+
# move this in the loop once I work out the
|
161
|
+
# way to do this in rspec properly
|
162
|
+
stop_rspec
|
163
|
+
ensure
|
164
|
+
@excel.cleanup
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def initialize_rspec
|
169
|
+
require 'rasta/extensions/rspec_extensions'
|
170
|
+
require 'rasta/formatter/spreadsheet_formatter'
|
171
|
+
require 'spec/runner/formatter/progress_bar_formatter'
|
172
|
+
require 'spec/runner/formatter/html_formatter'
|
173
|
+
end
|
174
|
+
private :initialize_rspec
|
175
|
+
|
176
|
+
def start_rspec
|
177
|
+
config = Configuration.instance
|
178
|
+
Spec::Runner.options.backtrace_tweaker = Spec::Runner::NoisyBacktraceTweaker.new
|
179
|
+
Spec::Runner.options.parse_format("Formatter::ProgressBarFormatter")
|
180
|
+
Spec::Runner.options.parse_format("Formatter::BaseTextFormatter:#{config.results_path}/results.txt")
|
181
|
+
Spec::Runner.options.parse_format("Formatter::HtmlFormatter:#{config.results_path}/results.html")
|
182
|
+
Spec::Runner.options.parse_format("Formatter::SpreadsheetFormatter:#{config.results_path}/spreadsheet.out")
|
183
|
+
Spec::Runner.options.reporter.initialize_spreadsheet
|
184
|
+
end
|
185
|
+
private :start_rspec
|
186
|
+
|
187
|
+
def stop_rspec
|
188
|
+
Spec::Runner.options.reporter.original_dump if Spec::Runner.options
|
189
|
+
Spec::Runner.options.clear_format_options;
|
190
|
+
end
|
191
|
+
private :stop_rspec
|
192
|
+
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec/runner/formatter/base_formatter'
|
2
|
+
module Spec
|
3
|
+
module Runner
|
4
|
+
module Formatter
|
5
|
+
class SpreadsheetFormatter < Spec::Runner::Formatter::BaseFormatter
|
6
|
+
GREEN = 35
|
7
|
+
RED = 40
|
8
|
+
YELLOW = 19
|
9
|
+
NONE = -4142
|
10
|
+
|
11
|
+
def cell=(c)
|
12
|
+
@cell = c
|
13
|
+
end
|
14
|
+
|
15
|
+
def example_failed(example, counter, failure)
|
16
|
+
if @cell
|
17
|
+
failure.exception.backtrace ? @cell.color = YELLOW : @cell.color = RED
|
18
|
+
comment = "method: " + @cell.header + "()\n"
|
19
|
+
comment += failure.exception.message.gsub(/,\s+/,",\n")
|
20
|
+
comment += "\n" + failure.exception.backtrace.join("\n") if failure.exception.backtrace
|
21
|
+
@cell.comment = comment
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def example_passed(example)
|
26
|
+
@cell.color = GREEN if @cell && @cell.color == NONE
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|