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 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.4']
23
- p.extra_deps<<['ruport','1.6.1']
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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2008 Vassilis Rizopoulos. All rights reserved.
1
+ # Copyright (c) 2008-2010 Vassilis Rizopoulos. All rights reserved.
2
2
  require 'rutema/system'
3
3
  require 'patir/base'
4
4
 
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
- Rutema::RutemaX.new(ARGV)
4
+ begin
5
+ Rutema::RutemaX.new(ARGV)
6
+ rescue
7
+ exit 1
8
+ 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
 
4
4
  module Rutema
data/lib/rutema/gems.rb CHANGED
@@ -1,3 +1,4 @@
1
- gem 'activerecord','2.3.4'
1
+ gem 'activerecord','2.3.8'
2
2
  gem 'patir',">=0.6.4"
3
3
  gem 'acts_as_reportable','=1.1.1'
4
+ gem 'couchrest','=0.37'
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
- #This is the ActiveRecord model for Rutema:
14
- #
15
- #A Run has n instances of executed scenarios - which in turn have n instances of executed steps -
16
- #and n instances of parse errors.
17
- module Model
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
- #We store the RutemaConfiguration#context for every run so that reports for past runs can be recreated without running the actual tests again.
21
- class Schema<ActiveRecord::Migration
22
- def self.up
23
- create_table :runs do |t|
24
- t.column :context, :string
25
- end
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
- create_table :scenarios do |t|
28
- t.column :name, :string, :null=>false
29
- t.column :run_id,:integer, :null=>false
30
- t.column :attended,:bool, :null=>false
31
- t.column :status, :string,:null=>false
32
- t.column :number,:integer
33
- t.column :start_time, :datetime,:null=>false
34
- t.column :stop_time, :datetime
35
- t.column :version, :string
36
- t.column :title, :string
37
- t.column :description, :string
38
- end
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
- create_table :steps do |t|
41
- t.column :scenario_id,:integer, :null=>false
42
- t.column :name, :string
43
- t.column :number, :integer,:null=>false
44
- t.column :status, :string,:null=>false
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
- create_table :parse_errors do |t|
51
- t.column :filename, :string,:null=>false
52
- t.column :error, :string
53
- t.column :run_id,:integer, :null=>false
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
- class Run<ActiveRecord::Base
59
- has_many :scenarios
60
- has_many :parse_errors
61
- serialize :context
62
- acts_as_reportable
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
- class Scenario<ActiveRecord::Base
66
- belongs_to :run
67
- has_many :steps
68
- acts_as_reportable
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
- class Step<ActiveRecord::Base
72
- belongs_to :scenario
73
- acts_as_reportable
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
- class ParseError<ActiveRecord::Base
77
- belongs_to :run
78
- acts_as_reportable
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
- class UpgradeV9toV10<ActiveRecord::Migration
82
- def self.up
83
- puts("Adding new columns")
84
- add_column(:scenarios, :title, :string,{:default=>"title"})
85
- add_column(:scenarios, :description, :string,{:default=>"description"})
86
- puts("Updating existing scenario entries")
87
- Rutema::Model::Scenario.find(:all).each do |sc|
88
- puts "Updating scenario #{sc.id}"
89
- sc.title="#{name}"
90
- sc.description="#{name}"
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
@@ -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
@@ -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 'rutema/specification'
4
4
 
@@ -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 ActiveRecordConnections
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
- connect_to_active_record(database_configuration,@logger)
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 using '#{@dbfile}'"
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 cerates a simple text summary of a test run
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
- msg<<"\nOne scenario in the current run" if runner_states.size==1
30
- msg<<"\n#{runner_states.size} scenarios in the current run" if runner_states.size>1
31
- not_run = runner_states.select{|state| state.status == :not_executed }.sort_by {|state| state.sequence_id.to_i}
32
- errors = runner_states.select{|state| state.status == :error }.sort_by {|state| state.sequence_id.to_i}
33
- warnings = runner_states.select{|state| state.status == :warning }.sort_by {|state| state.sequence_id.to_i}
34
- successes = runner_states.select{|state| state.status == :success }.sort_by {|state| state.sequence_id.to_i}
35
- msg<<"\n#{errors.size} errors, #{warnings.size} warnings, #{successes.size} successes"
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
- msg<<"\n#{specifications[state.sequence_name].title}" if specifications[state.sequence_name]
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
@@ -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 'rutema/reporters/standard_reporters'
4
4
  require 'patir/command'
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=0
16
- TINY=9
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
- exit 1
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
- exit 1
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=Patir::CommandSequenceStatus.new(name,scenario.steps)
546
- begin
547
- attention_needed=scenario.attended?
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
- exit 1
655
+ raise "Configuration error '#{$!.message}'"
645
656
  rescue
646
657
  @logger.debug($!)
647
658
  @logger.fatal("#{$!.message}")
648
- exit 1
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
- exit 1
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
- exit 1
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
- exit 1
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 TestModel<Test::Unit::TestCase
10
+ class TestActiveRecordModel<Test::Unit::TestCase
12
11
  def setup
13
- if RUBY_PLATFORM =~ /java/
14
- ActiveRecord::Base.establish_connection(:adapter => "jdbch2",:database =>"db/h2")
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
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
- version: 1.0.9
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-04-07 00:00:00 +03:00
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
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
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
- version:
35
+ type: :runtime
36
+ version_requirements: *id001
25
37
  - !ruby/object:Gem::Dependency
26
38
  name: highline
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
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
- version: "0"
34
- version:
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
- type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
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
- version: "0"
44
- version:
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
- type: :runtime
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
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
- version: 2.3.4
54
- version:
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
- type: :runtime
58
- version_requirement:
59
- version_requirements: !ruby/object:Gem::Requirement
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
- version: 1.6.1
64
- version:
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
- type: :runtime
68
- version_requirement:
69
- version_requirements: !ruby/object:Gem::Requirement
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
- version:
115
+ type: :runtime
116
+ version_requirements: *id006
75
117
  - !ruby/object:Gem::Dependency
76
- name: rubyforge
77
- type: :development
78
- version_requirement:
79
- version_requirements: !ruby/object:Gem::Requirement
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
- version: 0.3.0
94
- version:
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
- type: :development
98
- version_requirement:
99
- version_requirements: !ruby/object:Gem::Requirement
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
- version: 2.5.0
104
- version:
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.5
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