are_we_there_yet 0.2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe AreWeThereYet::Recorder do
4
+ before(:each) do
5
+ @db_name = "/tmp/arewethereyet.sqlite"
6
+ @db = "sqlite://#{@db_name}"
7
+
8
+ File.unlink(@db_name) if File.exists? @db_name
9
+
10
+ @connection = Sequel.connect(@db)
11
+ end
12
+
13
+ it "extends the RSpec formatter" do
14
+ AreWeThereYet::Recorder.should < Spec::Runner::Formatter::BaseFormatter
15
+ end
16
+
17
+ describe "#initialize" do
18
+ it "creates the necessary tables in the database" do
19
+ AreWeThereYet::Recorder.new({},@db)
20
+
21
+ @connection.tables.should_not be_empty
22
+ end
23
+
24
+ it "logs the start of a spec run" do
25
+ AreWeThereYet::Recorder.new({},@db)
26
+
27
+ @connection[:runs].first[:started_at].should_not be_nil
28
+ end
29
+ end
30
+
31
+ describe "logging a metric" do
32
+ before(:each) do
33
+ @awty = AreWeThereYet::Recorder.new({}, @db)
34
+ @mock_example = mock(Spec::Example::ExampleProxy, :location => "/path/to/spec:42", :description => "blaah")
35
+ end
36
+
37
+ # This test duplicates a test done for the Metric class - still undecided whether the cost of duplication
38
+ # outweighs the benefit of confirming integration
39
+ it "creates an entry for the metric in the database" do
40
+ start_time = Time.now - 10
41
+ end_time = Time.now
42
+
43
+ Time.stub!(:now).and_return(start_time)
44
+ @awty.example_started(@mock_example)
45
+
46
+ Time.stub!(:now).and_return(end_time)
47
+ @awty.example_passed(@mock_example)
48
+
49
+ run_id = @connection[:runs].first[:id]
50
+
51
+ @connection[:metrics].count.should ==1
52
+ metric = @connection[:metrics].first
53
+ metric[:execution_time].should == end_time - start_time
54
+ metric[:run_id].should == run_id
55
+ metric[:path].should == @mock_example.location.split(':').first
56
+ metric[:description].should == @mock_example.description
57
+ end
58
+ end
59
+
60
+ describe "closing" do
61
+ before(:each) do
62
+ @awty = AreWeThereYet::Recorder.new({}, @db)
63
+ @mock_example = mock(Spec::Example::ExampleProxy, :location => "/path/to/spec", :description => "blaah")
64
+ @awty.example_started(@mock_example)
65
+ end
66
+
67
+ it "closes the connection to the database" do
68
+ Sequel::SQLite::Database.any_instance.should_receive(:disconnect)
69
+ @awty.close
70
+ end
71
+
72
+ it "updates the end time value for the relevant run" do
73
+ @awty.close
74
+
75
+ run = @connection[:runs].first[:ended_at].should_not be_nil
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe AreWeThereYet::Run do
4
+ before(:each) do
5
+ @db_name = "/tmp/are_we_there_yet_#{Time.now.to_i}_#{rand(100000000)}_spec.sqlite"
6
+ @db = "sqlite://#{@db_name}"
7
+
8
+ @connection = AreWeThereYet::Persistence::Connection.create(@db)
9
+ AreWeThereYet::Persistence::Schema.create(@connection)
10
+ end
11
+
12
+ describe "start" do
13
+ it "adds a record to the database" do
14
+ @connection[:runs].all.should be_empty
15
+
16
+ AreWeThereYet::Run.new.start(@connection)
17
+
18
+ @connection[:runs].all.should have(1).records
19
+ end
20
+
21
+ it "sets the start time as an UTC timestamp" do
22
+ fake_time = Time.at(0)
23
+ Time.stub_chain(:now, :utc).and_return(fake_time)
24
+
25
+ AreWeThereYet::Run.new.start(@connection)
26
+
27
+ @connection[:runs].first[:started_at].should == fake_time
28
+ end
29
+
30
+ it "records the id of the run created" do
31
+ run = AreWeThereYet::Run.new
32
+ run.start(@connection)
33
+ run.id.should == @connection[:runs].first[:id]
34
+ end
35
+ end
36
+
37
+ describe "finish" do
38
+ it "sets the end time as an UTC timestamp" do
39
+ fake_time = Time.at(0)
40
+ Time.stub_chain(:now, :utc).and_return(fake_time)
41
+
42
+ run = AreWeThereYet::Run.new
43
+ run.start(@connection)
44
+ run.finish(@connection)
45
+
46
+ @connection[:runs].first[:ended_at].should == fake_time
47
+ end
48
+ end
49
+ end
@@ -2,43 +2,14 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
  require 'rspec'
4
4
 
5
- #Create an empty class that we will need to inherit from
6
-
7
- module Spec
8
- module Runner
9
- module Formatter
10
- class BaseFormatter
11
- end
12
- end
13
- end
14
- end
15
-
16
5
  AWTY_SPEC_RUN = true
17
- require 'are_we_there_yet'
18
6
 
19
7
  # Requires supporting files with custom matchers and macros, etc,
20
8
  # in ./support/ and its subdirectories.
21
9
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
22
10
 
11
+ require 'are_we_there_yet'
12
+
23
13
  RSpec.configure do |config|
24
14
 
25
15
  end
26
-
27
- def table_exists?(database_location,table_name)
28
- SQLite3::Database.new(database_location).execute(
29
- "SELECT name FROM sqlite_master WHERE type = 'table' AND name = '#{table_name}'"
30
- ).any?
31
- end
32
-
33
- def index_exists?(database_location,table_name,index_name)
34
- SQLite3::Database.new(database_location).execute(
35
- "SELECT name FROM sqlite_master WHERE type = 'index' AND name = '#{index_name}' AND tbl_name = '#{table_name}'"
36
- ).any?
37
- end
38
-
39
- module Spec
40
- module Example
41
- class ExampleProxy
42
- end
43
- end
44
- end
@@ -0,0 +1,22 @@
1
+ # Fake classes so that we do not need RSpec1.x present for the tests to pass
2
+ module Spec
3
+ module Runner
4
+ module Formatter
5
+ class BaseFormatter
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ module Spec
12
+ module Example
13
+ class ExampleProxy
14
+ attr_reader :description, :location
15
+ def initialize(description, location)
16
+ @description = description
17
+ @location = location
18
+ end
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,6 @@
1
+ class Symbol
2
+ def <=>(other_symbol)
3
+ self.to_s <=> other_symbol.to_s
4
+ end
5
+ end
6
+
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: are_we_there_yet
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
5
- prerelease: false
4
+ hash: 23
5
+ prerelease:
6
6
  segments:
7
- - 0
8
- - 2
9
7
  - 1
10
- segments_generated: true
11
- version: 0.2.1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
12
11
  platform: ruby
13
12
  authors:
14
13
  - Rory McKinley
@@ -16,28 +15,61 @@ autorequire:
16
15
  bindir: bin
17
16
  cert_chain: []
18
17
 
19
- date: 2012-01-10 00:00:00 +02:00
20
- default_executable:
18
+ date: 2012-05-09 00:00:00 Z
21
19
  dependencies:
22
20
  - !ruby/object:Gem::Dependency
23
- version_requirements: &id001 !ruby/object:Gem::Requirement
21
+ name: trollop
22
+ prerelease: false
23
+ type: :runtime
24
+ requirement: &id001 !ruby/object:Gem::Requirement
24
25
  none: false
25
26
  requirements:
26
27
  - - ~>
27
28
  - !ruby/object:Gem::Version
28
- hash: 27
29
+ hash: 83
29
30
  segments:
30
31
  - 1
32
+ - 16
33
+ - 2
34
+ version: 1.16.2
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: sequel
38
+ prerelease: false
39
+ type: :runtime
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 123
46
+ segments:
31
47
  - 3
48
+ - 31
32
49
  - 0
33
- segments_generated: true
34
- version: 1.3.0
35
- requirement: *id001
50
+ version: 3.31.0
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: sqlite3
36
54
  prerelease: false
37
55
  type: :runtime
38
- name: sqlite3
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ hash: 27
62
+ segments:
63
+ - 1
64
+ - 3
65
+ - 0
66
+ version: 1.3.0
67
+ version_requirements: *id003
39
68
  - !ruby/object:Gem::Dependency
40
- version_requirements: &id002 !ruby/object:Gem::Requirement
69
+ name: rspec
70
+ prerelease: false
71
+ type: :development
72
+ requirement: &id004 !ruby/object:Gem::Requirement
41
73
  none: false
42
74
  requirements:
43
75
  - - ~>
@@ -47,31 +79,29 @@ dependencies:
47
79
  - 2
48
80
  - 7
49
81
  - 0
50
- segments_generated: true
51
82
  version: 2.7.0
52
- requirement: *id002
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ name: bundler
53
86
  prerelease: false
54
87
  type: :development
55
- name: rspec
56
- - !ruby/object:Gem::Dependency
57
- version_requirements: &id003 !ruby/object:Gem::Requirement
88
+ requirement: &id005 !ruby/object:Gem::Requirement
58
89
  none: false
59
90
  requirements:
60
91
  - - ~>
61
92
  - !ruby/object:Gem::Version
62
- hash: 23
93
+ hash: 19
63
94
  segments:
64
95
  - 1
96
+ - 1
65
97
  - 0
66
- - 0
67
- segments_generated: true
68
- version: 1.0.0
69
- requirement: *id003
98
+ version: 1.1.0
99
+ version_requirements: *id005
100
+ - !ruby/object:Gem::Dependency
101
+ name: jeweler
70
102
  prerelease: false
71
103
  type: :development
72
- name: bundler
73
- - !ruby/object:Gem::Dependency
74
- version_requirements: &id004 !ruby/object:Gem::Requirement
104
+ requirement: &id006 !ruby/object:Gem::Requirement
75
105
  none: false
76
106
  requirements:
77
107
  - - ~>
@@ -81,14 +111,13 @@ dependencies:
81
111
  - 1
82
112
  - 6
83
113
  - 4
84
- segments_generated: true
85
114
  version: 1.6.4
86
- requirement: *id004
115
+ version_requirements: *id006
116
+ - !ruby/object:Gem::Dependency
117
+ name: rcov
87
118
  prerelease: false
88
119
  type: :development
89
- name: jeweler
90
- - !ruby/object:Gem::Dependency
91
- version_requirements: &id005 !ruby/object:Gem::Requirement
120
+ requirement: &id007 !ruby/object:Gem::Requirement
92
121
  none: false
93
122
  requirements:
94
123
  - - ">="
@@ -96,16 +125,12 @@ dependencies:
96
125
  hash: 3
97
126
  segments:
98
127
  - 0
99
- segments_generated: true
100
128
  version: "0"
101
- requirement: *id005
102
- prerelease: false
103
- type: :development
104
- name: rcov
129
+ version_requirements: *id007
105
130
  description: Provides detailed profiling data for RSpec runs in a SQLite3 DB
106
131
  email: rorymckinley@gmail.com
107
- executables: []
108
-
132
+ executables:
133
+ - are_we_there_yet
109
134
  extensions: []
110
135
 
111
136
  extra_rdoc_files:
@@ -121,10 +146,28 @@ files:
121
146
  - Rakefile
122
147
  - VERSION
123
148
  - are_we_there_yet.gemspec
149
+ - bin/are_we_there_yet
124
150
  - lib/are_we_there_yet.rb
125
- - spec/are_we_there_yet_spec.rb
151
+ - lib/are_we_there_yet/exceptions.rb
152
+ - lib/are_we_there_yet/formatter.rb
153
+ - lib/are_we_there_yet/metric.rb
154
+ - lib/are_we_there_yet/persistence/connection.rb
155
+ - lib/are_we_there_yet/persistence/schema.rb
156
+ - lib/are_we_there_yet/profiler.rb
157
+ - lib/are_we_there_yet/profiler_ui.rb
158
+ - lib/are_we_there_yet/recorder.rb
159
+ - lib/are_we_there_yet/run.rb
160
+ - spec/lib/formatter_spec.rb
161
+ - spec/lib/metric_spec.rb
162
+ - spec/lib/persistence/connection_spec.rb
163
+ - spec/lib/persistence/schema_spec.rb
164
+ - spec/lib/profiler_spec.rb
165
+ - spec/lib/profiler_ui_spec.rb
166
+ - spec/lib/recorder_spec.rb
167
+ - spec/lib/run_spec.rb
126
168
  - spec/spec_helper.rb
127
- has_rdoc: true
169
+ - spec/support/spec_classes.rb
170
+ - spec/support/symbol.rb
128
171
  homepage: http://github.com/rorymckinley/are_we_there_yet
129
172
  licenses:
130
173
  - MIT
@@ -141,7 +184,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
184
  hash: 3
142
185
  segments:
143
186
  - 0
144
- segments_generated: true
145
187
  version: "0"
146
188
  required_rubygems_version: !ruby/object:Gem::Requirement
147
189
  none: false
@@ -151,12 +193,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
193
  hash: 3
152
194
  segments:
153
195
  - 0
154
- segments_generated: true
155
196
  version: "0"
156
197
  requirements: []
157
198
 
158
199
  rubyforge_project:
159
- rubygems_version: 1.3.7
200
+ rubygems_version: 1.8.17
160
201
  signing_key:
161
202
  specification_version: 3
162
203
  summary: Profiler for RSpec 1.3.x
@@ -1,252 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe AreWeThereYet do
4
- before(:each) do
5
- @db_name = "/tmp/arewethereyet.sqlite"
6
- File.unlink(@db_name) if File.exists? @db_name
7
- end
8
-
9
- it "extends the RSpec formatter" do
10
- AreWeThereYet.should < Spec::Runner::Formatter::BaseFormatter
11
- end
12
-
13
- describe "#initialize" do
14
- it "opens a connection to the specified database" do
15
- SQLite3::Database.should_receive(:new).with('/path/to/db.sqlite').and_return(mock(SQLite3::Database).as_null_object)
16
- AreWeThereYet.new({},'/path/to/db.sqlite')
17
- end
18
-
19
- it "creates the necessary tables in the database" do
20
- AreWeThereYet.new({},@db_name)
21
- table_exists?(@db_name, 'files').should be_true
22
- table_exists?(@db_name, 'examples').should be_true
23
- table_exists?(@db_name, 'metrics').should be_true
24
- table_exists?(@db_name, 'runs').should be_true
25
- end
26
-
27
- it "creates the necessary indexes" do
28
- AreWeThereYet.new({},@db_name)
29
- index_exists?(@db_name, 'files', 'path').should be_true
30
- index_exists?(@db_name, 'examples', 'file_description').should be_true
31
- end
32
-
33
- it "does not create the tables if they already exist" do
34
- AreWeThereYet.new({},@db_name)
35
- SQLite3::Database.any_instance.should_not_receive(:execute)
36
-
37
- AreWeThereYet.new({}, @db_name)
38
- end
39
-
40
- it "rolls back table creation on error" do
41
- connection = SQLite3::Database.new(@db_name)
42
- connection.stub(:execute) do |arg|
43
- if arg =~ /metrics/
44
- raise RuntimeError
45
- else
46
- connection.execute2(arg)
47
- []
48
- end
49
- end
50
- SQLite3::Database.should_receive(:new).and_return(connection)
51
-
52
- expect { AreWeThereYet.new({},@db_name) }.should raise_error
53
-
54
- connection.execute2("SELECT name FROM sqlite_master").size.should == 1 # Execute2 lists fields - size 1 means empty response
55
- end
56
-
57
- it "logs the start of a spec run" do
58
- AreWeThereYet.new({},@db_name)
59
- connection = SQLite3::Database.new(@db_name)
60
-
61
- run = connection.get_first_row("SELECT id, started_at FROM runs")
62
- run.should_not be_nil
63
- run[1].should_not be_nil
64
- end
65
-
66
- it "does not log the start of a spec run if there is no table in the database" do
67
- # This to maintain backwards-compatibility with DBs created by v0.1.0
68
- connection = SQLite3::Database.new(@db_name)
69
- connection.stub(:execute) do |arg|
70
- if arg =~ /CREATE TABLE runs/
71
- # Do nothing
72
- else
73
- connection.execute2(arg)
74
- []
75
- end
76
- end
77
- SQLite3::Database.should_receive(:new).and_return(connection)
78
-
79
- expect { AreWeThereYet.new({},@db_name) }.should_not raise_error
80
- end
81
- end
82
-
83
- describe "logging a metric for a new file" do
84
- before(:each) do
85
- @awty = AreWeThereYet.new({}, @db_name)
86
- @mock_example = mock(Spec::Example::ExampleProxy, :location => "/path/to/spec:42", :description => "blaah")
87
- end
88
-
89
- it "creates an entry for the example's file" do
90
- @awty.example_started(@mock_example)
91
- @awty.example_passed(@mock_example)
92
-
93
- files = SQLite3::Database.new(@db_name).execute("SELECT id, path FROM files")
94
- files.size.should == 1
95
- files.first[1].should == @mock_example.location.split(':').first
96
- end
97
-
98
- it "creates an entry for the example itself" do
99
- @awty.example_started(@mock_example)
100
- @awty.example_passed(@mock_example)
101
-
102
- connection = SQLite3::Database.new(@db_name)
103
- file = connection.get_first_row("SELECT id FROM files")
104
- file_id = file.first
105
- examples = connection.execute("SELECT id, file_id, description FROM examples")
106
-
107
- examples.size.should == 1
108
- examples.first[1].should == file_id
109
- examples.first[2].should == @mock_example.description
110
- end
111
-
112
- it "creates an entry for the total execution time" do
113
- start_time = Time.now - 10
114
- end_time = Time.now
115
-
116
- Time.should_receive(:now).and_return(start_time)
117
- @awty.example_started(@mock_example)
118
-
119
- Time.should_receive(:now).and_return(end_time)
120
- @awty.example_passed(@mock_example)
121
-
122
- connection = SQLite3::Database.new(@db_name)
123
- run = connection.get_first_row("SELECT id FROM runs")
124
- run_id = run.first
125
-
126
- example = connection.get_first_row("SELECT id FROM examples")
127
- example_id = example.first
128
-
129
- Time.stub!(:now)
130
- metrics = connection.execute("SELECT id, example_id, execution_time, created_at, run_id FROM metrics")
131
- metrics.size.should == 1
132
- metrics.first[1].should == example_id
133
- metrics.first[2].should == end_time - start_time
134
- metrics.first[3].should_not be_nil
135
- metrics.first[4].should == run_id
136
- end
137
-
138
- it "does not link the metric to a run if the run table does not exist" do
139
- # To maintain compatibility with version 0.1.0
140
- AreWeThereYet.any_instance.should_receive(:tracking_runs?).and_return(false)
141
-
142
- connection = SQLite3::Database.new(@db_name)
143
- connection.execute("DROP TABLE metrics")
144
- connection.execute("CREATE TABLE metrics(id INTEGER PRIMARY KEY, example_id INTEGER, execution_time FLOAT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)")
145
-
146
- @awty.example_started(@mock_example)
147
- expect { @awty.example_passed(@mock_example) }.should_not raise_error
148
- end
149
- end
150
-
151
- describe "logging a metric for an existing file" do
152
- before(:each) do
153
- @awty = AreWeThereYet.new({}, @db_name)
154
- @mock_example = mock(Spec::Example::ExampleProxy, :location => "/path/to/spec", :description => "blaah")
155
- @another_example = mock(Spec::Example::ExampleProxy, :location => "/path/to/spec", :description => "yippee!")
156
- end
157
-
158
- it "creates an example linked to the existing location" do
159
- @awty.example_started(@mock_example)
160
- @awty.example_passed(@mock_example)
161
-
162
- @awty.example_started(@another_example)
163
- @awty.example_passed(@another_example)
164
-
165
- connection = SQLite3::Database.new(@db_name)
166
-
167
- examples = connection.execute("SELECT description FROM examples")
168
- examples.size.should == 2
169
-
170
- files = connection.execute("SELECT id FROM files")
171
- files.size.should == 1
172
- end
173
- end
174
-
175
- describe "logging a metric for an existing example" do
176
- before(:each) do
177
- @awty = AreWeThereYet.new({}, @db_name)
178
- @mock_example = mock(Spec::Example::ExampleProxy, :location => "/path/to/spec", :description => "blaah")
179
- end
180
-
181
- it "creates a metric linked to the example" do
182
- @awty.example_started(@mock_example)
183
- @awty.example_passed(@mock_example)
184
-
185
- @awty.example_started(@mock_example)
186
- @awty.example_passed(@mock_example)
187
-
188
- connection = SQLite3::Database.new(@db_name)
189
-
190
- metrics = connection.execute("SELECT id FROM metrics")
191
- metrics.size.should == 2
192
-
193
- examples = connection.execute("SELECT description FROM examples")
194
- examples.size.should == 1
195
- end
196
- end
197
-
198
- describe "handling errors when logging" do
199
- before(:each) do
200
- @awty = AreWeThereYet.new({}, @db_name)
201
- @mock_example = mock(Spec::Example::ExampleProxy, :location => "/path/to/spec", :description => "blaah")
202
- @awty.example_started(@mock_example)
203
- end
204
-
205
- it "allows the error through and any changes are undone" do
206
- connection = SQLite3::Database.new(@db_name)
207
- connection.execute("DROP TABLE metrics")
208
-
209
- expect { @awty.example_passed(@mock_example) }.should raise_error
210
-
211
- connection.execute("SELECT * FROM files").should be_empty
212
- connection.execute("SELECT * FROM examples").should be_empty
213
- end
214
- end
215
-
216
- describe "closing" do
217
- before(:each) do
218
- @awty = AreWeThereYet.new({}, @db_name)
219
- @mock_example = mock(Spec::Example::ExampleProxy, :location => "/path/to/spec", :description => "blaah")
220
- @awty.example_started(@mock_example)
221
- end
222
-
223
- it "closes the connection to the database" do
224
- SQLite3::Database.any_instance.should_receive(:close)
225
- @awty.close
226
- end
227
-
228
- it "updates the end time value for the relevant run" do
229
- @awty.close
230
-
231
- connection = SQLite3::Database.new(@db_name)
232
- run = connection.get_first_row('SELECT ended_at FROM runs')
233
- run.first.should_not be_nil
234
- end
235
-
236
- it "stores the UTC time value for the relevant run" do
237
- mock_time = mock(Time, :strftime => '1970-01-01 00:00:00')
238
- mock_time.should_receive(:utc).and_return(mock_time)
239
- Time.stub(:now).and_return(mock_time)
240
-
241
- @awty.close
242
- end
243
-
244
- it "does not update the run if runs are not being tracked" do
245
- connection = SQLite3::Database.new(@db_name)
246
- connection.execute("DROP TABLE runs")
247
- AreWeThereYet.any_instance.should_receive(:tracking_runs?).and_return(false)
248
-
249
- expect { @awty.close }.should_not raise_error
250
- end
251
- end
252
- end