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 +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
|