rutema 1.0.9 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|