rutema 1.0.9 → 1.1.0
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/History.txt +6 -0
- data/Manifest.txt +4 -0
- data/Rakefile +6 -5
- data/bin/rutema_upgrader +1 -1
- data/bin/rutemax +6 -2
- data/lib/rutema/configuration.rb +1 -1
- data/lib/rutema/gems.rb +2 -1
- data/lib/rutema/model.rb +199 -63
- data/lib/rutema/rake.rb +32 -0
- data/lib/rutema/reporter.rb +1 -1
- data/lib/rutema/reporters/activerecord.rb +10 -42
- data/lib/rutema/reporters/couchdb.rb +62 -0
- data/lib/rutema/reporters/email.rb +6 -2
- data/lib/rutema/reporters/standard_reporters.rb +3 -2
- data/lib/rutema/reporters/text.rb +26 -10
- data/lib/rutema/reporters/yaml.rb +35 -0
- data/lib/rutema/specification.rb +1 -1
- data/lib/rutema/system.rb +35 -25
- data/test/test_couchdb.rb +60 -0
- data/test/test_model.rb +29 -14
- data/test/test_reporter.rb +0 -0
- metadata +111 -57
data/History.txt
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
== 1.1.0 /2010-12
|
2
|
+
* Added Rutema::RakeTask class to allow integration of the test runner with rake
|
3
|
+
* Email reporting now suppresses _setup and _teardown entries unless it's configured as verbose. To do this add a :verbose=>true entry in the reporter configuration
|
4
|
+
* Fixed a bug, where on a setup spec failure the state of the actual spec was nil
|
5
|
+
* added YAML dump reporter
|
6
|
+
* Fixed a bug in the initialization of StepRunner that prevented use of --step
|
1
7
|
== 1.0.9 / 2010-03-22
|
2
8
|
* Fixed (hopefully) a nagging bug in activerecord reporter where it would crash if a step had status nil.
|
3
9
|
* Fixed the same behaviour in the text reporter
|
data/Manifest.txt
CHANGED
@@ -9,11 +9,14 @@ distro_test.sh
|
|
9
9
|
lib/rutema/configuration.rb
|
10
10
|
lib/rutema/gems.rb
|
11
11
|
lib/rutema/model.rb
|
12
|
+
lib/rutema/rake.rb
|
12
13
|
lib/rutema/reporter.rb
|
13
14
|
lib/rutema/reporters/activerecord.rb
|
14
15
|
lib/rutema/reporters/email.rb
|
15
16
|
lib/rutema/reporters/standard_reporters.rb
|
16
17
|
lib/rutema/reporters/text.rb
|
18
|
+
lib/rutema/reporters/yaml.rb
|
19
|
+
lib/rutema/reporters/couchdb.rb
|
17
20
|
lib/rutema/specification.rb
|
18
21
|
lib/rutema/system.rb
|
19
22
|
selftest.sh
|
@@ -38,4 +41,5 @@ test/test_model.rb
|
|
38
41
|
test/test_reporter.rb
|
39
42
|
test/test_specification.rb
|
40
43
|
test/test_system.rb
|
44
|
+
test/test_couchdb.rb
|
41
45
|
|
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007 Vassilis Rizopoulos. All rights reserved.
|
1
|
+
# Copyright (c) 2007-2010 Vassilis Rizopoulos. All rights reserved.
|
2
2
|
# -*- ruby -*-
|
3
3
|
$:.unshift File.join(File.dirname(__FILE__),"lib")
|
4
4
|
$:.unshift File.join(File.dirname(__FILE__),"ext")
|
@@ -17,11 +17,12 @@ Hoe.spec('rutema') do |p|
|
|
17
17
|
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
18
18
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
19
19
|
p.extra_deps<<['patir',">=0.6.4"]
|
20
|
-
p.extra_deps<<['highline']
|
21
|
-
p.extra_deps<<['mailfactory']
|
22
|
-
p.extra_deps<<['activerecord','2.3.
|
23
|
-
p.extra_deps<<['ruport','1.6.
|
20
|
+
p.extra_deps<<['highline','1.5.2']
|
21
|
+
p.extra_deps<<['mailfactory','1.4.0']
|
22
|
+
p.extra_deps<<['activerecord','2.3.8']
|
23
|
+
p.extra_deps<<['ruport','1.6.3']
|
24
24
|
p.extra_deps<<['acts_as_reportable','1.1.1']
|
25
|
+
p.extra_deps<<['couchrest','=0.37']
|
25
26
|
p.spec_extras={:executables=>["rutemax","rutema_upgrader"],
|
26
27
|
:default_executable=>"rutemax"}
|
27
28
|
end
|
data/bin/rutema_upgrader
CHANGED
data/bin/rutemax
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
# Copyright (c) 2007 Vassilis Rizopoulos. All rights reserved.
|
1
|
+
# Copyright (c) 2007-2010 Vassilis Rizopoulos. All rights reserved.
|
2
2
|
require 'rutema/gems'
|
3
3
|
require 'rutema/system'
|
4
|
-
|
4
|
+
begin
|
5
|
+
Rutema::RutemaX.new(ARGV)
|
6
|
+
rescue
|
7
|
+
exit 1
|
8
|
+
end
|
data/lib/rutema/configuration.rb
CHANGED
data/lib/rutema/gems.rb
CHANGED
data/lib/rutema/model.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
# Copyright (c) 2007 Vassilis Rizopoulos. All rights reserved.
|
1
|
+
# Copyright (c) 2007-2010 Vassilis Rizopoulos. All rights reserved.
|
2
2
|
$:.unshift File.join(File.dirname(__FILE__),"..")
|
3
3
|
require 'active_record'
|
4
4
|
require 'ruport/acts_as_reportable'
|
5
|
+
require 'patir/base'
|
6
|
+
require 'couchrest'
|
5
7
|
#this fixes the AR Logger hack that annoys me sooooo much
|
6
8
|
class Logger
|
7
9
|
private
|
@@ -10,84 +12,218 @@ class Logger
|
|
10
12
|
end
|
11
13
|
end
|
12
14
|
module Rutema
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
#This is the schema for the AR database used to store test results
|
15
|
+
module ActiveRecord
|
16
|
+
#Exception occuring when connecting to a database
|
17
|
+
class ConnectionError<RuntimeError
|
18
|
+
end
|
19
|
+
#This is the ActiveRecord model for Rutema:
|
19
20
|
#
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
#A Run has n instances of executed scenarios - which in turn have n instances of executed steps -
|
22
|
+
#and n instances of parse errors.
|
23
|
+
module Model
|
24
|
+
#This is the schema for the AR database used to store test results
|
25
|
+
#
|
26
|
+
#We store the RutemaConfiguration#context for every run so that reports for past runs can be recreated without running the actual tests again.
|
27
|
+
class Schema< ::ActiveRecord::Migration
|
28
|
+
def self.up
|
29
|
+
create_table :runs do |t|
|
30
|
+
t.column :context, :string
|
31
|
+
end
|
26
32
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
create_table :scenarios do |t|
|
34
|
+
t.column :name, :string, :null=>false
|
35
|
+
t.column :run_id,:integer, :null=>false
|
36
|
+
t.column :attended,:bool, :null=>false
|
37
|
+
t.column :status, :string,:null=>false
|
38
|
+
t.column :number,:integer
|
39
|
+
t.column :start_time, :datetime,:null=>false
|
40
|
+
t.column :stop_time, :datetime
|
41
|
+
t.column :version, :string
|
42
|
+
t.column :title, :string
|
43
|
+
t.column :description, :string
|
44
|
+
end
|
45
|
+
|
46
|
+
create_table :steps do |t|
|
47
|
+
t.column :scenario_id,:integer, :null=>false
|
48
|
+
t.column :name, :string
|
49
|
+
t.column :number, :integer,:null=>false
|
50
|
+
t.column :status, :string,:null=>false
|
51
|
+
t.column :output, :text
|
52
|
+
t.column :error, :text
|
53
|
+
t.column :duration, :decimal
|
54
|
+
end
|
39
55
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
t.column :output, :text
|
46
|
-
t.column :error, :text
|
47
|
-
t.column :duration, :decimal
|
56
|
+
create_table :parse_errors do |t|
|
57
|
+
t.column :filename, :string,:null=>false
|
58
|
+
t.column :error, :string
|
59
|
+
t.column :run_id,:integer, :null=>false
|
60
|
+
end
|
48
61
|
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class Run< ::ActiveRecord::Base
|
65
|
+
has_many :scenarios
|
66
|
+
has_many :parse_errors
|
67
|
+
serialize :context
|
68
|
+
acts_as_reportable
|
69
|
+
end
|
49
70
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
71
|
+
class Scenario< ::ActiveRecord::Base
|
72
|
+
belongs_to :run
|
73
|
+
has_many :steps
|
74
|
+
acts_as_reportable
|
75
|
+
end
|
76
|
+
|
77
|
+
class Step< ::ActiveRecord::Base
|
78
|
+
belongs_to :scenario
|
79
|
+
acts_as_reportable
|
80
|
+
end
|
81
|
+
|
82
|
+
class ParseError< ::ActiveRecord::Base
|
83
|
+
belongs_to :run
|
84
|
+
acts_as_reportable
|
85
|
+
end
|
86
|
+
|
87
|
+
class UpgradeV9toV10< ::ActiveRecord::Migration
|
88
|
+
def self.up
|
89
|
+
puts("Adding new columns")
|
90
|
+
add_column(:scenarios, :title, :string,{:default=>"title"})
|
91
|
+
add_column(:scenarios, :description, :string,{:default=>"description"})
|
92
|
+
puts("Updating existing scenario entries")
|
93
|
+
Rutema::Model::Scenario.find(:all).each do |sc|
|
94
|
+
puts "Updating scenario #{sc.id}"
|
95
|
+
sc.title="#{name}"
|
96
|
+
sc.description="#{name}"
|
97
|
+
end
|
54
98
|
end
|
55
99
|
end
|
56
100
|
end
|
57
101
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
102
|
+
#Exports the contents of the database/model as a yaml dump
|
103
|
+
class Export
|
104
|
+
def initialize params
|
105
|
+
@logger = params[:logger]
|
106
|
+
@logger ||= Patir.setup_logger
|
107
|
+
@result_set_size = params[:result_set_size]
|
108
|
+
@result_set_size ||= 1000
|
109
|
+
@currently_on_no=0
|
110
|
+
database_configuration = params[:db]
|
111
|
+
raise "No database configuration defined, missing :db configuration key." unless database_configuration
|
112
|
+
ActiveRecord.connect(database_configuration,@logger)
|
113
|
+
end
|
114
|
+
|
115
|
+
def next
|
116
|
+
@logger.info("Found #{Model::Run.count} runs") if @currently_on_no==0
|
117
|
+
@logger.info("Exporting from #{@currently_on_no} to #{@currently_on_no+@result_set_size}")
|
118
|
+
export(@result_set_size)
|
119
|
+
end
|
120
|
+
|
121
|
+
def all
|
122
|
+
@logger.info("Found #{Model::Run.count} runs")
|
123
|
+
export(nil)
|
124
|
+
end
|
125
|
+
private
|
126
|
+
def export offset=nil
|
127
|
+
if offset
|
128
|
+
runs=Model::Run.find(:all,:order=>"id ASC",:limit=>@result_set_size,:offset=>@currently_on_no)
|
129
|
+
@currently_on_no+=offset
|
130
|
+
else
|
131
|
+
runs=Model::Run.find(:all)
|
132
|
+
end
|
133
|
+
return nil if runs.empty?
|
134
|
+
export=[]
|
135
|
+
runs.each do |run|
|
136
|
+
e={:parse_errors=>[],:scenarios=>[],:context=>run.context}
|
137
|
+
run.parse_errors.each { |pe| e[:parse_errors]<<{:filename=>pe.filename, :error=>pe.error} }
|
138
|
+
run.scenarios.each { |sc| e[:scenarios]<<export_scenario(sc) }
|
139
|
+
export<<e
|
140
|
+
@logger.debug("Exported #{run.id}")
|
141
|
+
end
|
142
|
+
return export
|
143
|
+
end
|
144
|
+
|
145
|
+
def export_scenario sc
|
146
|
+
scenario={:name=>sc[:name],
|
147
|
+
:attended=>sc[:attended],
|
148
|
+
:status=>sc[:status],
|
149
|
+
:number=>sc[:number],
|
150
|
+
:start_time=>sc[:start_time],
|
151
|
+
:stop_time=>sc[:stop_time],
|
152
|
+
:version=>sc[:version],
|
153
|
+
:title=>sc[:title],
|
154
|
+
:description=>sc[:description],
|
155
|
+
:steps=>[]
|
156
|
+
}
|
157
|
+
sc.steps.each do |step|
|
158
|
+
st={:name=>step[:name],
|
159
|
+
:number=>step[:number],
|
160
|
+
:status=>step[:status],
|
161
|
+
:output=>step[:output],
|
162
|
+
:error=>step[:error],
|
163
|
+
:duration=>step[:duration]
|
164
|
+
}
|
165
|
+
scenario[:steps]<<st
|
166
|
+
end
|
167
|
+
return scenario
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
#Establishes an ActiveRecord connection
|
172
|
+
def self.connect cfg,logger
|
173
|
+
conn=cnct(cfg,logger)
|
174
|
+
Model::Schema.migrate(:up) if perform_migration?(cfg)
|
63
175
|
end
|
64
176
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
177
|
+
private
|
178
|
+
#Establishes an active record connection using the cfg hash
|
179
|
+
#There is only a rudimentary check to ensure the integrity of cfg
|
180
|
+
def self.cnct cfg,logger
|
181
|
+
if cfg[:adapter] && cfg[:database]
|
182
|
+
logger.debug("Connecting to #{cfg[:database]}")
|
183
|
+
return ::ActiveRecord::Base.establish_connection(cfg)
|
184
|
+
else
|
185
|
+
raise ConnectionError,"Erroneous database configuration. Missing :adapter and/or :database"
|
186
|
+
end
|
69
187
|
end
|
70
188
|
|
71
|
-
|
72
|
-
|
73
|
-
|
189
|
+
def self.perform_migration? cfg
|
190
|
+
return true if cfg[:migrate]
|
191
|
+
#special case for sqlite3
|
192
|
+
if cfg[:adapter]=="sqlite3" && !File.exists?(cfg[:database])
|
193
|
+
return true
|
194
|
+
end
|
195
|
+
return false
|
74
196
|
end
|
75
197
|
|
76
|
-
|
77
|
-
|
78
|
-
|
198
|
+
end
|
199
|
+
|
200
|
+
module CouchDB
|
201
|
+
def self.connect cfg,logger
|
202
|
+
if cfg[:url] && cfg[:database]
|
203
|
+
if cfg[:user] && cfg[:password]
|
204
|
+
end
|
205
|
+
return CouchRest.database!("#{cfg[:url]}/#{cfg[:database]}")
|
206
|
+
|
207
|
+
else
|
208
|
+
raise ConnectionError,"Erroneous database configuration. Missing :url and/or :database"
|
209
|
+
end
|
79
210
|
end
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
211
|
+
module Model
|
212
|
+
class Run <CouchRest::ExtendedDocument
|
213
|
+
unique_id :slug
|
214
|
+
|
215
|
+
timestamps!
|
216
|
+
|
217
|
+
view_by :slug, :descending=>true
|
218
|
+
|
219
|
+
property :slug, :read_only => true
|
220
|
+
property :context
|
221
|
+
property :scenarios
|
222
|
+
property :parse_errors
|
223
|
+
|
224
|
+
set_callback :save, :before, :generate_slug_from_payload
|
225
|
+
def generate_slug_from_payload
|
226
|
+
self['slug']=Digest::SHA1.hexdigest("#{self['context']},#{self['scenarios']}")
|
91
227
|
end
|
92
228
|
end
|
93
229
|
end
|
data/lib/rutema/rake.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rutema/system'
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
module Rutema
|
5
|
+
class RakeTask
|
6
|
+
attr_accessor :config_file, :log_file, :step, :name
|
7
|
+
def initialize params=nil
|
8
|
+
params||={}
|
9
|
+
@config_file=params[:config]
|
10
|
+
@log_file=params[:log]
|
11
|
+
@name=params[:name]
|
12
|
+
yield self if block_given?
|
13
|
+
|
14
|
+
raise "No rutema configuration given" unless @config_file
|
15
|
+
args=['-c',@config_file]
|
16
|
+
args+=['-l',@log_file] if @log_file
|
17
|
+
args<<"all"
|
18
|
+
OptionParser::Arguable.extend_object(args)
|
19
|
+
if @name
|
20
|
+
desc "Executes the tests in #{File.basename(@config_file)}"
|
21
|
+
task :"rutema:#{@name}" do
|
22
|
+
Rutema::RutemaX.new(args)
|
23
|
+
end
|
24
|
+
else
|
25
|
+
desc "Executes the tests in #{File.basename(@config_file)}"
|
26
|
+
task :rutema do
|
27
|
+
Rutema::RutemaX.new(args)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/rutema/reporter.rb
CHANGED
@@ -1,47 +1,15 @@
|
|
1
|
-
# Copyright (c) 2007 Vassilis Rizopoulos. All rights reserved.
|
1
|
+
# Copyright (c) 2007-2010 Vassilis Rizopoulos. All rights reserved.
|
2
2
|
$:.unshift File.join(File.dirname(__FILE__),"..","..")
|
3
3
|
require 'yaml'
|
4
4
|
require 'rutema/reporter'
|
5
5
|
require 'rutema/model'
|
6
6
|
|
7
7
|
module Rutema
|
8
|
-
#Exception occuring when connecting to a database
|
9
|
-
class ConnectionError<RuntimeError
|
10
|
-
end
|
11
|
-
|
12
|
-
module ActiveRecordConnections
|
13
|
-
#Establishes an ActiveRecord connection
|
14
|
-
def connect_to_active_record cfg,logger
|
15
|
-
conn=connect(cfg,logger)
|
16
|
-
Rutema::Model::Schema.migrate(:up) if perform_migration?(cfg)
|
17
|
-
end
|
18
|
-
private
|
19
|
-
#Establishes an active record connection using the cfg hash
|
20
|
-
#There is only a rudimentary check to ensure the integrity of cfg
|
21
|
-
def connect cfg,logger
|
22
|
-
if cfg[:adapter] && cfg[:database]
|
23
|
-
logger.debug("Connecting to #{cfg[:database]}")
|
24
|
-
return ActiveRecord::Base.establish_connection(cfg)
|
25
|
-
else
|
26
|
-
raise ConnectionError,"Erroneous database configuration. Missing :adapter and/or :database"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def perform_migration? cfg
|
31
|
-
return true if cfg[:migrate]
|
32
|
-
#special case for sqlite3
|
33
|
-
if cfg[:adapter]=="sqlite3" && !File.exists?(cfg[:database])
|
34
|
-
return true
|
35
|
-
end
|
36
|
-
return false
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
8
|
#The ActiveRecordReporter will store the results of a test run in a database using ActiveRecord.
|
41
9
|
#
|
42
10
|
#The DBMSs supported are dependent on the platform: either SQLite3 (MRI) or h2 (jruby)
|
43
11
|
class ActiveRecordReporter
|
44
|
-
include
|
12
|
+
include ActiveRecord
|
45
13
|
#The required keys in this reporter's configuration are:
|
46
14
|
# :db - the database configuration. A Hash with the DB adapter information
|
47
15
|
# :db=>{:database=>"sample.rb"}
|
@@ -50,27 +18,27 @@ module Rutema
|
|
50
18
|
@logger||=Patir.setup_logger
|
51
19
|
database_configuration = definition[:db]
|
52
20
|
raise "No database configuration defined, missing :db configuration key." unless database_configuration
|
53
|
-
|
21
|
+
ActiveRecord.connect(database_configuration,@logger)
|
54
22
|
@logger.info("Reporter #{self.to_s} registered")
|
55
23
|
end
|
56
24
|
|
57
|
-
#We get all the data for a Rutema::Model::Run entry in here.
|
25
|
+
#We get all the data for a Rutema::ActiveRecord::Model::Run entry in here.
|
58
26
|
#
|
59
|
-
#If the configuration is given and there is a context defined, this will be YAML-dumped into Rutema::Model::Run#context
|
27
|
+
#If the configuration is given and there is a context defined, this will be YAML-dumped into Rutema::ActiveRecord::Model::Run#context
|
60
28
|
def report specifications,runner_states,parse_errors,configuration
|
61
|
-
run_entry=Model::Run.new
|
29
|
+
run_entry=ActiveRecord::Model::Run.new
|
62
30
|
if configuration && configuration.context
|
63
31
|
run_entry.context=configuration.context
|
64
32
|
end
|
65
33
|
parse_errors.each do |pe|
|
66
|
-
er=Model::ParseError.new()
|
34
|
+
er=ActiveRecord::Model::ParseError.new()
|
67
35
|
er.filename=pe[:filename]
|
68
36
|
er.error=pe[:error]
|
69
37
|
run_entry.parse_errors<<er
|
70
38
|
end
|
71
39
|
runner_states.compact!
|
72
40
|
runner_states.each do |scenario|
|
73
|
-
sc=Model::Scenario.new
|
41
|
+
sc=ActiveRecord::Model::Scenario.new
|
74
42
|
sc.name=scenario.sequence_name
|
75
43
|
sc.number=scenario.sequence_id
|
76
44
|
sc.start_time=scenario.start_time
|
@@ -93,7 +61,7 @@ module Rutema
|
|
93
61
|
sc.attended=false
|
94
62
|
end
|
95
63
|
scenario.step_states.each do |number,step|
|
96
|
-
st=Model::Step.new
|
64
|
+
st=ActiveRecord::Model::Step.new
|
97
65
|
st.name=step[:name]
|
98
66
|
st.number=number
|
99
67
|
st.status="#{step[:status]}"
|
@@ -109,7 +77,7 @@ module Rutema
|
|
109
77
|
end
|
110
78
|
|
111
79
|
def to_s
|
112
|
-
"ActiveRecordReporter
|
80
|
+
"ActiveRecordReporter"
|
113
81
|
end
|
114
82
|
|
115
83
|
private
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rutema/model'
|
2
|
+
|
3
|
+
module Rutema
|
4
|
+
class CouchDBReporter
|
5
|
+
def initialize definition
|
6
|
+
@logger=definition[:logger]
|
7
|
+
@logger||=Patir.setup_logger
|
8
|
+
database_configuration = definition[:db]
|
9
|
+
raise "No database configuration defined, missing :db configuration key." unless database_configuration
|
10
|
+
@database=Rutema::CouchDB.connect(database_configuration,@logger)
|
11
|
+
@logger.info("Reporter #{self.to_s} registered")
|
12
|
+
end
|
13
|
+
|
14
|
+
#We get all the data for a Rutema::CouchDB::Model::Run entry in here.
|
15
|
+
def report specifications,runner_states,parse_errors,configuration
|
16
|
+
run_entry=Rutema::CouchDB::Model::Run.new
|
17
|
+
run_entry.database=@database
|
18
|
+
if configuration && configuration.context
|
19
|
+
run_entry.context=configuration.context
|
20
|
+
end
|
21
|
+
run_entry.parse_errors=parse_errors
|
22
|
+
scenarios=[]
|
23
|
+
runner_states.compact!
|
24
|
+
runner_states.each { |scenario| scenarios<<format_scenario(scenario,specifications)}
|
25
|
+
run_entry.scenarios=scenarios
|
26
|
+
run_entry.save
|
27
|
+
"couchdb reporter done"
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
"CouchDBReporter"
|
32
|
+
end
|
33
|
+
private
|
34
|
+
def format_scenario scenario,specifications
|
35
|
+
sc={}
|
36
|
+
sc[:name]=scenario.sequence_name
|
37
|
+
sc[:number]=scenario.sequence_id
|
38
|
+
sc[:start_time]=scenario.start_time
|
39
|
+
sc[:stop_time]=scenario.stop_time
|
40
|
+
sc[:status]=scenario.status.to_s
|
41
|
+
#get the specification for this scenario
|
42
|
+
spec=specifications[sc[:name]]
|
43
|
+
if spec
|
44
|
+
sc[:version]=spec.version if spec.has_version?
|
45
|
+
sc[:title]=spec.title
|
46
|
+
sc[:description]=spec.description
|
47
|
+
else
|
48
|
+
@logger.debug("Could not find specification for #{sc[:name]}")
|
49
|
+
|
50
|
+
sc[:title]=sc[:name]
|
51
|
+
sc[:description]=""
|
52
|
+
end
|
53
|
+
if scenario.strategy==:attended
|
54
|
+
sc[:attended]=true
|
55
|
+
else
|
56
|
+
sc[:attended]=false
|
57
|
+
end
|
58
|
+
sc[:steps]=scenario.step_states
|
59
|
+
return sc
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007 Vassilis Rizopoulos. All rights reserved.
|
1
|
+
# Copyright (c) 2007-2010 Vassilis Rizopoulos. All rights reserved.
|
2
2
|
$:.unshift File.join(File.dirname(__FILE__),"..","..")
|
3
3
|
require 'net/smtp'
|
4
4
|
require 'rutema/reporter'
|
@@ -24,6 +24,8 @@ module Rutema
|
|
24
24
|
#Customization keys:
|
25
25
|
#
|
26
26
|
#:subject - the string of this key will be prefixed as a subject for the email
|
27
|
+
#
|
28
|
+
#:verbose - when true, the report contains info on setup and teardown specs. Optional. Default is false
|
27
29
|
class EmailReporter
|
28
30
|
attr_reader :last_message
|
29
31
|
def initialize definition
|
@@ -47,6 +49,8 @@ module Rutema
|
|
47
49
|
@subject||=""
|
48
50
|
@footer=definition[:footer]
|
49
51
|
@footer||=""
|
52
|
+
@verbose=definition[:verbose]
|
53
|
+
@verbose||=false
|
50
54
|
@logger.info("Reporter '#{self.to_s}' registered")
|
51
55
|
end
|
52
56
|
|
@@ -57,7 +61,7 @@ module Rutema
|
|
57
61
|
|
58
62
|
def report specifications,runner_states,parse_errors,configuration
|
59
63
|
@mail.subject = "#{@subject}"
|
60
|
-
txt=TextReporter.new.report(specifications,runner_states,parse_errors,configuration)
|
64
|
+
txt=TextReporter.new(:verbose=>@verbose).report(specifications,runner_states,parse_errors,configuration)
|
61
65
|
txt<<"\n\n#{@footer}"
|
62
66
|
@mail.text = txt
|
63
67
|
begin
|
@@ -1,6 +1,7 @@
|
|
1
|
-
# Copyright (c) 2007 Vassilis Rizopoulos. All rights reserved.
|
1
|
+
# Copyright (c) 2007-2010 Vassilis Rizopoulos. All rights reserved.
|
2
2
|
$:.unshift File.join(File.dirname(__FILE__),"..","..")
|
3
3
|
|
4
4
|
require 'rutema/reporters/text'
|
5
5
|
require 'rutema/reporters/email'
|
6
|
-
require 'rutema/reporters/activerecord'
|
6
|
+
require 'rutema/reporters/activerecord'
|
7
|
+
require 'rutema/reporters/yaml'
|
@@ -1,7 +1,13 @@
|
|
1
1
|
module Rutema
|
2
|
-
#This reporter
|
2
|
+
#This reporter creates a simple text summary of a test run
|
3
|
+
#
|
4
|
+
#The following configuration keys are used by TextReporter:
|
5
|
+
#
|
6
|
+
#:verbose - when true, the report contains info on setup and teardown specs. Optional. Default is false
|
3
7
|
class TextReporter
|
4
|
-
def initialize params=nil
|
8
|
+
def initialize params=nil
|
9
|
+
@verbose=params[:verbose] if params
|
10
|
+
@verbose||=false
|
5
11
|
end
|
6
12
|
|
7
13
|
#Returns the text summary
|
@@ -26,20 +32,30 @@ module Rutema
|
|
26
32
|
#Report on scenarios
|
27
33
|
runner_states.compact!#make sure no nil elements make it through
|
28
34
|
msg<<"\nNo scenarios in this run" if runner_states.empty?
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
msg<<"\n#{
|
35
|
+
if @verbose
|
36
|
+
states=runner_states
|
37
|
+
else
|
38
|
+
states=runner_states.select{|state| state.sequence_name !~ /[_setup|_teardown]$/}
|
39
|
+
end
|
40
|
+
msg<<"\nOne scenario in the current run" if states.size==1
|
41
|
+
msg<<"\n#{states.size} scenarios in the current run" if states.size>1
|
42
|
+
|
43
|
+
not_run = states.select{|state| state.status == :not_executed }.sort_by {|state| state.sequence_id.to_i}
|
44
|
+
errors = states.select{|state| state.status == :error }.sort_by {|state| state.sequence_id.to_i}
|
45
|
+
warnings = states.select{|state| state.status == :warning }.sort_by {|state| state.sequence_id.to_i}
|
46
|
+
successes = states.select{|state| state.status == :success }.sort_by {|state| state.sequence_id.to_i}
|
47
|
+
msg<<"\n#{errors.size} errors, #{warnings.size} warnings, #{successes.size} successes, #{not_run.size} not executed (setup failure)"
|
36
48
|
msg<<"\nErrors:" unless errors.empty?
|
37
49
|
msg<<scenario_summaries(errors,specifications)
|
38
50
|
msg<<"\nWarnings:" unless warnings.empty?
|
39
51
|
msg<<scenario_summaries(warnings,specifications)
|
40
52
|
msg<<"\nNot executed:" unless not_run.empty?
|
41
53
|
not_run.each do |state|
|
42
|
-
|
54
|
+
if specifications[state.sequence_name]
|
55
|
+
msg<<"\n#{specifications[state.sequence_name].title}"
|
56
|
+
else
|
57
|
+
msg<<"\n#{state.sequence_name}"
|
58
|
+
end
|
43
59
|
end
|
44
60
|
msg<<"\nSuccesses:" unless successes.empty?
|
45
61
|
msg<<scenario_summaries(successes,specifications)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Rutema
|
4
|
+
|
5
|
+
module YAML
|
6
|
+
#Experimental reporter used to dump the data of a run on disk
|
7
|
+
#
|
8
|
+
#The following configuration keys are used by YAML::Reporter:
|
9
|
+
#
|
10
|
+
#:filename - the filename to use to save the YAML dump. Default is 'rutema.yaml'
|
11
|
+
class Reporter
|
12
|
+
DEFAULT_FILENAME="rutema.yaml"
|
13
|
+
|
14
|
+
def initialize definition
|
15
|
+
@logger=definition[:logger]
|
16
|
+
@logger||=Patir.setup_logger
|
17
|
+
@filename=definition[:filename]
|
18
|
+
@filename||="rutema.yaml"
|
19
|
+
@logger.info("Reporter #{self.to_s} registered")
|
20
|
+
end
|
21
|
+
|
22
|
+
#We get all the data from a test run in here.
|
23
|
+
def report specifications,runner_states,parse_errors,configuration
|
24
|
+
run_entry={}
|
25
|
+
if configuration && configuration.context
|
26
|
+
run_entry[:context]=configuration.context
|
27
|
+
end
|
28
|
+
run_entry[:parse_errors]=parse_errors
|
29
|
+
runner_states.compact!
|
30
|
+
run_entry[:runner_states]=runner_states
|
31
|
+
File.open(@filename,"wb") {|f| f.write( ::YAML.dump(run_entry))}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/rutema/specification.rb
CHANGED
data/lib/rutema/system.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2007 Vassilis Rizopoulos. All rights reserved.
|
1
|
+
# Copyright (c) 2007-2010 Vassilis Rizopoulos. All rights reserved.
|
2
2
|
$:.unshift File.join(File.dirname(__FILE__),"..")
|
3
3
|
require 'rexml/document'
|
4
4
|
require 'patir/configuration'
|
@@ -12,8 +12,8 @@ module Rutema
|
|
12
12
|
#This module defines the version numbers for the library
|
13
13
|
module Version
|
14
14
|
MAJOR=1
|
15
|
-
MINOR=
|
16
|
-
TINY=
|
15
|
+
MINOR=1
|
16
|
+
TINY=0
|
17
17
|
STRING=[ MAJOR, MINOR, TINY ].join( "." )
|
18
18
|
end
|
19
19
|
#The Elements module provides the namespace for the various modules adding parser functionality
|
@@ -304,12 +304,12 @@ module Rutema
|
|
304
304
|
run_test(spec) if spec
|
305
305
|
else
|
306
306
|
@logger.fatal("Don't know how to run '#{mode}'")
|
307
|
-
|
307
|
+
raise "Don't know how to run '#{mode}'"
|
308
308
|
end
|
309
309
|
rescue
|
310
310
|
@logger.debug($!)
|
311
311
|
@logger.fatal("Runner error: #{$!.message}")
|
312
|
-
|
312
|
+
raise
|
313
313
|
end
|
314
314
|
@configuration.context[:end_time]=Time.now
|
315
315
|
@logger.info("Run completed in #{@configuration.context[:end_time]-@configuration.context[:start_time]}s")
|
@@ -500,6 +500,9 @@ module Rutema
|
|
500
500
|
@logger.info("Scenario for #{name}")
|
501
501
|
@states[name]=run_scenario(name,scenario)
|
502
502
|
@states[name].sequence_id="#{@number_of_runs}"
|
503
|
+
else
|
504
|
+
@states[name]=initialize_state(name,scenario)
|
505
|
+
@states[name].sequence_id="#{@number_of_runs}"
|
503
506
|
end
|
504
507
|
end
|
505
508
|
else
|
@@ -542,18 +545,9 @@ module Rutema
|
|
542
545
|
end
|
543
546
|
private
|
544
547
|
def run_scenario name,scenario
|
545
|
-
state=
|
546
|
-
begin
|
547
|
-
|
548
|
-
if attention_needed && !self.attended?
|
549
|
-
@logger.warn("Attended scenario cannot be run in unattended mode")
|
550
|
-
state.status=:warning
|
551
|
-
else
|
552
|
-
if attention_needed
|
553
|
-
state.strategy=:attended
|
554
|
-
else
|
555
|
-
state.strategy=:unattended
|
556
|
-
end
|
548
|
+
state=initialize_state(name,scenario)
|
549
|
+
begin
|
550
|
+
if evaluate_attention(scenario,state)
|
557
551
|
stps=scenario.steps
|
558
552
|
if stps.empty?
|
559
553
|
@logger.warn("Scenario #{name} contains no steps")
|
@@ -574,6 +568,22 @@ module Rutema
|
|
574
568
|
state.sequence_id=@number_of_runs
|
575
569
|
return state
|
576
570
|
end
|
571
|
+
def initialize_state name,scenario
|
572
|
+
state=Patir::CommandSequenceStatus.new(name,scenario.steps)
|
573
|
+
end
|
574
|
+
def evaluate_attention scenario,state
|
575
|
+
if scenario.attended?
|
576
|
+
if !self.attended?
|
577
|
+
@logger.warn("Attended scenario cannot be run in unattended mode")
|
578
|
+
state.status=:warning
|
579
|
+
return false
|
580
|
+
end
|
581
|
+
state.strategy=:attended
|
582
|
+
else
|
583
|
+
state.strategy=:unattended
|
584
|
+
end
|
585
|
+
return true
|
586
|
+
end
|
577
587
|
def run_step step
|
578
588
|
@logger.info("Running step #{step.number} - #{step.name}")
|
579
589
|
if step.has_cmd? && step.cmd.respond_to?(:run)
|
@@ -601,13 +611,14 @@ module Rutema
|
|
601
611
|
@logger.info(msg) if msg && !msg.empty?
|
602
612
|
end
|
603
613
|
end
|
614
|
+
|
604
615
|
end
|
605
616
|
|
606
617
|
#StepRunner halts before every step and asks if it should be executed or not.
|
607
618
|
class StepRunner<Runner
|
608
|
-
def initialize setup=nil, teardown=nil,logger=nil
|
619
|
+
def initialize context=nil,setup=nil, teardown=nil,logger=nil
|
609
620
|
@questioner=HighLine.new
|
610
|
-
super(setup,teardown,logger)
|
621
|
+
super(context,setup,teardown,logger)
|
611
622
|
end
|
612
623
|
def run_step step
|
613
624
|
if @questioner.agree("Execute #{step.to_s}?")
|
@@ -641,11 +652,11 @@ module Rutema
|
|
641
652
|
rescue Patir::ConfigurationException
|
642
653
|
@logger.debug($!)
|
643
654
|
@logger.fatal("Configuration error '#{$!.message}'")
|
644
|
-
|
655
|
+
raise "Configuration error '#{$!.message}'"
|
645
656
|
rescue
|
646
657
|
@logger.debug($!)
|
647
658
|
@logger.fatal("#{$!.message}")
|
648
|
-
|
659
|
+
raise
|
649
660
|
end
|
650
661
|
end
|
651
662
|
private
|
@@ -682,7 +693,7 @@ module Rutema
|
|
682
693
|
@mode=File.expand_path(command)
|
683
694
|
else
|
684
695
|
$stderr.puts "Can't find '#{command}' and it does not match any known commands. Don't know what to do with it."
|
685
|
-
|
696
|
+
raise "Can't find '#{command}' and it does not match any known commands. Don't know what to do with it."
|
686
697
|
end
|
687
698
|
end
|
688
699
|
end
|
@@ -696,7 +707,7 @@ module Rutema
|
|
696
707
|
@coordinator.run(@configuration.check)
|
697
708
|
else
|
698
709
|
@logger.fatal("There is no check test defined in the configuration.")
|
699
|
-
|
710
|
+
raise "There is no check test defined in the configuration."
|
700
711
|
end
|
701
712
|
else
|
702
713
|
#run everything
|
@@ -706,10 +717,9 @@ module Rutema
|
|
706
717
|
@coordinator.report
|
707
718
|
if @coordinator.parse_errors.empty? && @coordinator.last_run_a_success?
|
708
719
|
@logger.info("All tests successful")
|
709
|
-
exit 0
|
710
720
|
else
|
711
721
|
@logger.warn("Not all tests were successful")
|
712
|
-
|
722
|
+
raise "Not all tests were successful"
|
713
723
|
end
|
714
724
|
end
|
715
725
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rutema/gems'
|
4
|
+
require 'test/unit'
|
5
|
+
require 'ostruct'
|
6
|
+
require 'rutema/reporters/couchdb'
|
7
|
+
require 'patir/command'
|
8
|
+
require 'mocha'
|
9
|
+
#$DEBUG=true
|
10
|
+
module TestRutema
|
11
|
+
class MockCommand
|
12
|
+
include Patir::Command
|
13
|
+
def initialize number
|
14
|
+
@number=number
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class TestCouchDBModel<Test::Unit::TestCase
|
19
|
+
end
|
20
|
+
|
21
|
+
class TestCouchDBReporter<Test::Unit::TestCase
|
22
|
+
CFG={:db=>{:url=>"http://localhost:5984", :database=>"rutema_test_sandbox"}}
|
23
|
+
def setup
|
24
|
+
@parse_errors=[{:filename=>"f.spec",:error=>"error"}]
|
25
|
+
st=Patir::CommandSequenceStatus.new("test_seq")
|
26
|
+
st.step=MockCommand.new(1)
|
27
|
+
st.step=MockCommand.new(2)
|
28
|
+
st.step=MockCommand.new(3)
|
29
|
+
@status=[st]
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_no_errors
|
33
|
+
spec=mock
|
34
|
+
r=Rutema::CouchDBReporter.new(CFG)
|
35
|
+
assert_nothing_raised() { r.report({"test"=>spec},[runner_state_mock()],[],nil) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_a_bit_of_everything
|
39
|
+
spec=mock
|
40
|
+
spec.expects(:has_version?).returns(false)
|
41
|
+
spec.expects(:title).returns("T")
|
42
|
+
spec.expects(:description).returns("cool test")
|
43
|
+
|
44
|
+
r=Rutema::CouchDBReporter.new(CFG)
|
45
|
+
assert_nothing_raised() { r.report({"1"=>spec},[runner_state_mock,runner_state_mock(1,:error)],[],nil) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def runner_state_mock n=0,status=:success,step_states=[]
|
49
|
+
rs=mock()
|
50
|
+
rs.expects(:sequence_name).returns("#{n}")
|
51
|
+
rs.expects(:sequence_id).returns("seq_id#{n}")
|
52
|
+
rs.expects(:start_time).returns(Time.now-3600)
|
53
|
+
rs.expects(:stop_time).returns(Time.now)
|
54
|
+
rs.expects(:status).returns(status)
|
55
|
+
rs.expects(:strategy).returns(:attended)
|
56
|
+
rs.expects(:step_states).returns(step_states)
|
57
|
+
return rs
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/test/test_model.rb
CHANGED
@@ -1,21 +1,16 @@
|
|
1
1
|
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
2
|
-
|
2
|
+
require 'rubygems'
|
3
3
|
require 'test/unit'
|
4
4
|
require 'rutema/model'
|
5
5
|
require 'fileutils'
|
6
6
|
require 'rubygems'
|
7
7
|
require 'rutema/gems'
|
8
|
-
require 'active_record/fixtures'
|
9
8
|
|
10
9
|
module TestRutema
|
11
|
-
class
|
10
|
+
class TestActiveRecordModel<Test::Unit::TestCase
|
12
11
|
def setup
|
13
|
-
|
14
|
-
|
15
|
-
else
|
16
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3",:database =>":memory:")
|
17
|
-
end
|
18
|
-
Rutema::Model::Schema.up
|
12
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3",:database =>":memory:")
|
13
|
+
Rutema::ActiveRecord::Model::Schema.up
|
19
14
|
end
|
20
15
|
def teardown
|
21
16
|
ActiveRecord::Base.remove_connection
|
@@ -24,15 +19,15 @@ module TestRutema
|
|
24
19
|
#test the CRUD operations
|
25
20
|
def test_create_read_update_delete
|
26
21
|
#create
|
27
|
-
r=Rutema::Model::Run.new
|
22
|
+
r=Rutema::ActiveRecord::Model::Run.new
|
28
23
|
context={:tester=>"automatopoulos",:version=>"latest"}
|
29
24
|
r.context=context
|
30
|
-
sc=Rutema::Model::Scenario.new(:name=>"TC000",:attended=>false,:status=>"success",:start_time=>Time.now)
|
31
|
-
sc.steps<<Rutema::Model::Step.new(:name=>"echo",:number=>1,:status=>"success",:output=>"testing is nice",:error=>"",:duration=>1)
|
25
|
+
sc=Rutema::ActiveRecord::Model::Scenario.new(:name=>"TC000",:attended=>false,:status=>"success",:start_time=>Time.now)
|
26
|
+
sc.steps<<Rutema::ActiveRecord::Model::Step.new(:name=>"echo",:number=>1,:status=>"success",:output=>"testing is nice",:error=>"",:duration=>1)
|
32
27
|
r.scenarios<<sc
|
33
28
|
assert(r.save, "Failed to save.")
|
34
29
|
#read
|
35
|
-
run=Rutema::Model::Run.find(r.id)
|
30
|
+
run=Rutema::ActiveRecord::Model::Run.find(r.id)
|
36
31
|
assert_equal(context,run.context)
|
37
32
|
assert_equal(sc.name, run.scenarios[0].name)
|
38
33
|
#update
|
@@ -41,7 +36,27 @@ module TestRutema
|
|
41
36
|
assert(run.save, "Failed to update.")
|
42
37
|
#delete
|
43
38
|
assert(run.destroy, "Failed to delete.")
|
44
|
-
assert_raise(ActiveRecord::RecordNotFound) {Rutema::Model::Run.find(r.id)}
|
39
|
+
assert_raise(ActiveRecord::RecordNotFound) {Rutema::ActiveRecord::Model::Run.find(r.id)}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class TestCouchDBModel<Test::Unit::TestCase
|
44
|
+
def setup
|
45
|
+
@db=CouchRest.database!("http://localhost:5984/rutema_test")
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_couchdb_model
|
49
|
+
run=Rutema::CouchDB::Model::Run.new
|
50
|
+
run.database=@db
|
51
|
+
run.context="context"
|
52
|
+
run.scenarios=["1","2","#{self.object_id}"]
|
53
|
+
assert_nothing_raised() { run.save }
|
54
|
+
|
55
|
+
r=Rutema::CouchDB::Model::Run.get(run.slug)
|
56
|
+
assert_equal(run.slug, r.slug)
|
57
|
+
|
45
58
|
end
|
59
|
+
|
60
|
+
|
46
61
|
end
|
47
62
|
end
|
data/test/test_reporter.rb
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rutema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 1.1.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Vassilis Rizopoulos
|
@@ -9,99 +15,136 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-12-20 00:00:00 +02:00
|
13
19
|
default_executable: rutemax
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
22
|
name: patir
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - ">="
|
22
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 15
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 6
|
33
|
+
- 4
|
23
34
|
version: 0.6.4
|
24
|
-
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
25
37
|
- !ruby/object:Gem::Dependency
|
26
38
|
name: highline
|
27
|
-
|
28
|
-
|
29
|
-
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
30
42
|
requirements:
|
31
|
-
- - "
|
43
|
+
- - "="
|
32
44
|
- !ruby/object:Gem::Version
|
33
|
-
|
34
|
-
|
45
|
+
hash: 7
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 5
|
49
|
+
- 2
|
50
|
+
version: 1.5.2
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
35
53
|
- !ruby/object:Gem::Dependency
|
36
54
|
name: mailfactory
|
37
|
-
|
38
|
-
|
39
|
-
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
40
58
|
requirements:
|
41
|
-
- - "
|
59
|
+
- - "="
|
42
60
|
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
|
61
|
+
hash: 7
|
62
|
+
segments:
|
63
|
+
- 1
|
64
|
+
- 4
|
65
|
+
- 0
|
66
|
+
version: 1.4.0
|
67
|
+
type: :runtime
|
68
|
+
version_requirements: *id003
|
45
69
|
- !ruby/object:Gem::Dependency
|
46
70
|
name: activerecord
|
47
|
-
|
48
|
-
|
49
|
-
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
50
74
|
requirements:
|
51
75
|
- - "="
|
52
76
|
- !ruby/object:Gem::Version
|
53
|
-
|
54
|
-
|
77
|
+
hash: 19
|
78
|
+
segments:
|
79
|
+
- 2
|
80
|
+
- 3
|
81
|
+
- 8
|
82
|
+
version: 2.3.8
|
83
|
+
type: :runtime
|
84
|
+
version_requirements: *id004
|
55
85
|
- !ruby/object:Gem::Dependency
|
56
86
|
name: ruport
|
57
|
-
|
58
|
-
|
59
|
-
|
87
|
+
prerelease: false
|
88
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
60
90
|
requirements:
|
61
91
|
- - "="
|
62
92
|
- !ruby/object:Gem::Version
|
63
|
-
|
64
|
-
|
93
|
+
hash: 9
|
94
|
+
segments:
|
95
|
+
- 1
|
96
|
+
- 6
|
97
|
+
- 3
|
98
|
+
version: 1.6.3
|
99
|
+
type: :runtime
|
100
|
+
version_requirements: *id005
|
65
101
|
- !ruby/object:Gem::Dependency
|
66
102
|
name: acts_as_reportable
|
67
|
-
|
68
|
-
|
69
|
-
|
103
|
+
prerelease: false
|
104
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
70
106
|
requirements:
|
71
107
|
- - "="
|
72
108
|
- !ruby/object:Gem::Version
|
109
|
+
hash: 17
|
110
|
+
segments:
|
111
|
+
- 1
|
112
|
+
- 1
|
113
|
+
- 1
|
73
114
|
version: 1.1.1
|
74
|
-
|
115
|
+
type: :runtime
|
116
|
+
version_requirements: *id006
|
75
117
|
- !ruby/object:Gem::Dependency
|
76
|
-
name:
|
77
|
-
|
78
|
-
|
79
|
-
|
118
|
+
name: couchrest
|
119
|
+
prerelease: false
|
120
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
80
122
|
requirements:
|
81
|
-
- - "
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
version: 2.0.3
|
84
|
-
version:
|
85
|
-
- !ruby/object:Gem::Dependency
|
86
|
-
name: gemcutter
|
87
|
-
type: :development
|
88
|
-
version_requirement:
|
89
|
-
version_requirements: !ruby/object:Gem::Requirement
|
90
|
-
requirements:
|
91
|
-
- - ">="
|
123
|
+
- - "="
|
92
124
|
- !ruby/object:Gem::Version
|
93
|
-
|
94
|
-
|
125
|
+
hash: 65
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
- 37
|
129
|
+
version: "0.37"
|
130
|
+
type: :runtime
|
131
|
+
version_requirements: *id007
|
95
132
|
- !ruby/object:Gem::Dependency
|
96
133
|
name: hoe
|
97
|
-
|
98
|
-
|
99
|
-
|
134
|
+
prerelease: false
|
135
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
100
137
|
requirements:
|
101
138
|
- - ">="
|
102
139
|
- !ruby/object:Gem::Version
|
103
|
-
|
104
|
-
|
140
|
+
hash: 47
|
141
|
+
segments:
|
142
|
+
- 2
|
143
|
+
- 8
|
144
|
+
- 0
|
145
|
+
version: 2.8.0
|
146
|
+
type: :development
|
147
|
+
version_requirements: *id008
|
105
148
|
description: |-
|
106
149
|
== DESCRIPTION:
|
107
150
|
rutema is a test execution tool with a twist.
|
@@ -151,11 +194,14 @@ files:
|
|
151
194
|
- lib/rutema/configuration.rb
|
152
195
|
- lib/rutema/gems.rb
|
153
196
|
- lib/rutema/model.rb
|
197
|
+
- lib/rutema/rake.rb
|
154
198
|
- lib/rutema/reporter.rb
|
155
199
|
- lib/rutema/reporters/activerecord.rb
|
156
200
|
- lib/rutema/reporters/email.rb
|
157
201
|
- lib/rutema/reporters/standard_reporters.rb
|
158
202
|
- lib/rutema/reporters/text.rb
|
203
|
+
- lib/rutema/reporters/yaml.rb
|
204
|
+
- lib/rutema/reporters/couchdb.rb
|
159
205
|
- lib/rutema/specification.rb
|
160
206
|
- lib/rutema/system.rb
|
161
207
|
- selftest.sh
|
@@ -180,6 +226,7 @@ files:
|
|
180
226
|
- test/test_reporter.rb
|
181
227
|
- test/test_specification.rb
|
182
228
|
- test/test_system.rb
|
229
|
+
- test/test_couchdb.rb
|
183
230
|
has_rdoc: true
|
184
231
|
homepage:
|
185
232
|
licenses: []
|
@@ -191,26 +238,33 @@ rdoc_options:
|
|
191
238
|
require_paths:
|
192
239
|
- lib
|
193
240
|
required_ruby_version: !ruby/object:Gem::Requirement
|
241
|
+
none: false
|
194
242
|
requirements:
|
195
243
|
- - ">="
|
196
244
|
- !ruby/object:Gem::Version
|
245
|
+
hash: 3
|
246
|
+
segments:
|
247
|
+
- 0
|
197
248
|
version: "0"
|
198
|
-
version:
|
199
249
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
250
|
+
none: false
|
200
251
|
requirements:
|
201
252
|
- - ">="
|
202
253
|
- !ruby/object:Gem::Version
|
254
|
+
hash: 3
|
255
|
+
segments:
|
256
|
+
- 0
|
203
257
|
version: "0"
|
204
|
-
version:
|
205
258
|
requirements: []
|
206
259
|
|
207
260
|
rubyforge_project: patir
|
208
|
-
rubygems_version: 1.3.
|
261
|
+
rubygems_version: 1.3.7
|
209
262
|
signing_key:
|
210
263
|
specification_version: 3
|
211
264
|
summary: rutema is a test execution and management framework for heterogeneous testing environments
|
212
265
|
test_files:
|
213
266
|
- test/test_configuration.rb
|
267
|
+
- test/test_couchdb.rb
|
214
268
|
- test/test_model.rb
|
215
269
|
- test/test_reporter.rb
|
216
270
|
- test/test_specification.rb
|