are_we_there_yet 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -17,6 +17,19 @@ Usage is fairly simple:
17
17
  2. When running the specs pass the name of the class together with the location of your SQLite3 database, e.g:
18
18
  `spec -fAreWeThereYet:/path/to/db.sqlite3 spec`
19
19
 
20
+ Only passing tests are profiled.
21
+
22
+ ## Data Structure
23
+
24
+ The following data is stored in the database:
25
+
26
+ - runs (from v0.2.0 onwards) - this is to allow conclusive tracking of metrics against a specific run. Multiple runs close to one
27
+ may result in guesswork when determining which metrics belong to which run. v0.1.0 does not track this data, but v0.2.0 is backwards
28
+ compatible and can handle the reduced fidelity when dealing with a database created by v0.1.0.
29
+ - files - this represents the individual files containing the examples that are being run.
30
+ - examples - the individual examples themselves (one file has many examples)
31
+ - metrics - the run time per example (per run from v0.2.0 onwards) - one example has many metrics, one run has many metrics
32
+
20
33
  ## License
21
34
 
22
35
  Copyright (c) 2012 Rory McKinley
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{are_we_there_yet}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Rory McKinley"]
@@ -6,6 +6,8 @@ class AreWeThereYet < Spec::Runner::Formatter::BaseFormatter
6
6
  @db = SQLite3::Database.new(where)
7
7
 
8
8
  create_tables
9
+
10
+ log_run
9
11
  end
10
12
 
11
13
  def example_started(example)
@@ -18,16 +20,26 @@ class AreWeThereYet < Spec::Runner::Formatter::BaseFormatter
18
20
 
19
21
  example_id = persist_example(db, example, location_id)
20
22
 
21
- db.execute(
22
- "INSERT INTO metrics(example_id, execution_time) VALUES(:example_id, :execution_time)",
23
- :example_id => db.last_insert_row_id,
24
- :execution_time => Time.now - @start
25
- )
23
+ persist_metric(db, example_id)
26
24
  end
27
25
  end
28
26
 
27
+ def close
28
+ @db.execute(
29
+ "UPDATE runs SET ended_at = :end_time WHERE id = :run_id",
30
+ :end_time => Time.now.strftime("%Y-%m-%d %H:%M:%S"),
31
+ :run_id => @run_id
32
+ ) if tracking_runs?
33
+ @db.close
34
+ end
35
+
29
36
  private
30
37
 
38
+ def log_run
39
+ @db.execute("INSERT INTO runs(id) VALUES(NULL)") if tracking_runs?
40
+ @run_id = @db.last_insert_row_id
41
+ end
42
+
31
43
  def persist_file(db, example)
32
44
  path = example.location.split(':').first
33
45
 
@@ -58,17 +70,39 @@ class AreWeThereYet < Spec::Runner::Formatter::BaseFormatter
58
70
  end
59
71
  end
60
72
 
73
+ def persist_metric(db, example_id)
74
+ if tracking_runs?
75
+ db.execute(
76
+ "INSERT INTO metrics(example_id, execution_time, run_id) VALUES(:example_id, :execution_time, :run_id)",
77
+ :example_id => db.last_insert_row_id,
78
+ :execution_time => Time.now - @start,
79
+ :run_id => @run_id
80
+ )
81
+ else
82
+ db.execute(
83
+ "INSERT INTO metrics(example_id, execution_time) VALUES(:example_id, :execution_time)",
84
+ :example_id => db.last_insert_row_id,
85
+ :execution_time => Time.now - @start
86
+ )
87
+ end
88
+ end
89
+
61
90
  def create_tables
62
91
  existing_tables = @db.execute("SELECT name FROM sqlite_master")
63
92
 
64
93
  if existing_tables.empty?
65
94
  @db.transaction do |db|
95
+ db.execute("CREATE TABLE runs(id INTEGER PRIMARY KEY, started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ended_at TIMESTAMP)")
66
96
  db.execute("CREATE TABLE files(id INTEGER PRIMARY KEY, path VARCHAR(255))")
67
97
  db.execute("CREATE INDEX path ON files (path)")
68
98
  db.execute("CREATE TABLE examples(id INTEGER PRIMARY KEY, file_id INTEGER, description TEXT)")
69
99
  db.execute("CREATE INDEX file_description ON examples (file_id, description)")
70
- db.execute("CREATE TABLE metrics(id INTEGER PRIMARY KEY, example_id INTEGER, execution_time FLOAT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)")
100
+ db.execute("CREATE TABLE metrics(id INTEGER PRIMARY KEY, example_id INTEGER, execution_time FLOAT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, run_id INTEGER )")
71
101
  end
72
102
  end
73
103
  end
104
+
105
+ def tracking_runs?
106
+ @tracking_runs ||= @db.execute("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'runs'").any?
107
+ end
74
108
  end
@@ -21,6 +21,7 @@ describe AreWeThereYet do
21
21
  table_exists?(@db_name, 'files').should be_true
22
22
  table_exists?(@db_name, 'examples').should be_true
23
23
  table_exists?(@db_name, 'metrics').should be_true
24
+ table_exists?(@db_name, 'runs').should be_true
24
25
  end
25
26
 
26
27
  it "creates the necessary indexes" do
@@ -52,6 +53,31 @@ describe AreWeThereYet do
52
53
 
53
54
  connection.execute2("SELECT name FROM sqlite_master").size.should == 1 # Execute2 lists fields - size 1 means empty response
54
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
55
81
  end
56
82
 
57
83
  describe "logging a metric for a new file" do
@@ -94,15 +120,31 @@ describe AreWeThereYet do
94
120
  @awty.example_passed(@mock_example)
95
121
 
96
122
  connection = SQLite3::Database.new(@db_name)
123
+ run = connection.get_first_row("SELECT id FROM runs")
124
+ run_id = run.first
125
+
97
126
  example = connection.get_first_row("SELECT id FROM examples")
98
127
  example_id = example.first
99
128
 
100
129
  Time.stub!(:now)
101
- metrics = connection.execute("SELECT id, example_id, execution_time, created_at FROM metrics")
130
+ metrics = connection.execute("SELECT id, example_id, execution_time, created_at, run_id FROM metrics")
102
131
  metrics.size.should == 1
103
132
  metrics.first[1].should == example_id
104
133
  metrics.first[2].should == end_time - start_time
105
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
106
148
  end
107
149
  end
108
150
 
@@ -170,4 +212,33 @@ describe AreWeThereYet do
170
212
  connection.execute("SELECT * FROM examples").should be_empty
171
213
  end
172
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 "does not update the run if runs are not being tracked" do
237
+ connection = SQLite3::Database.new(@db_name)
238
+ connection.execute("DROP TABLE runs")
239
+ AreWeThereYet.any_instance.should_receive(:tracking_runs?).and_return(false)
240
+
241
+ expect { @awty.close }.should_not raise_error
242
+ end
243
+ end
173
244
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: are_we_there_yet
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
10
  segments_generated: true
11
- version: 0.1.0
11
+ version: 0.2.0
12
12
  platform: ruby
13
13
  authors:
14
14
  - Rory McKinley