are_we_there_yet 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +13 -0
- data/VERSION +1 -1
- data/are_we_there_yet.gemspec +1 -1
- data/lib/are_we_there_yet.rb +40 -6
- data/spec/are_we_there_yet_spec.rb +72 -1
- metadata +3 -3
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.2.0
|
data/are_we_there_yet.gemspec
CHANGED
data/lib/are_we_there_yet.rb
CHANGED
@@ -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
|
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:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
10
|
segments_generated: true
|
11
|
-
version: 0.
|
11
|
+
version: 0.2.0
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- Rory McKinley
|