piggly 2.0.0 → 2.1.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.
- checksums.yaml +4 -4
- data/lib/piggly/command/base.rb +20 -13
- data/lib/piggly/command.rb +0 -1
- data/lib/piggly/compiler/trace_compiler.rb +19 -7
- data/lib/piggly/dumper/qualified_type.rb +35 -8
- data/lib/piggly/dumper/reified_procedure.rb +15 -6
- data/lib/piggly/parser/grammar.tt +7 -4
- data/lib/piggly/profile.rb +1 -1
- data/lib/piggly/version.rb +2 -2
- data/spec/028_spec.rb +48 -0
- data/spec/examples/profile_spec.rb +1 -1
- metadata +5 -4
- data/lib/piggly/command/test.rb +0 -157
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f16c8c0dbea51654e23f87e09524076da758fb8e
|
4
|
+
data.tar.gz: 99c21d733eb0fc50e1334e760f7601141eac4c3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75479a4b5b69f804d2d7dd54272f65784301821a1088a3e969398610e8f4a56f114b48dca7606d34605305d4f440af669a9a7cfecf796a2c4aa59ad3fafff981
|
7
|
+
data.tar.gz: fbff8e9856834ad14593596fd5ea76ddfaf49ee9c8625afbb4257450b0e04e1ca4699c9b24e76de20c78283d91204cc25d5666244e6900d498b228eb1f389956
|
data/lib/piggly/command/base.rb
CHANGED
@@ -10,7 +10,7 @@ module Piggly
|
|
10
10
|
cmd, argv = command(argv)
|
11
11
|
|
12
12
|
if cmd.nil?
|
13
|
-
abort "usage: #{$0} {
|
13
|
+
abort "usage: #{$0} {report|trace|untrace} --help"
|
14
14
|
else
|
15
15
|
cmd.main(argv)
|
16
16
|
end
|
@@ -25,7 +25,6 @@ module Piggly
|
|
25
25
|
|
26
26
|
case head.downcase
|
27
27
|
when "report"; [Report, tail]
|
28
|
-
when "test"; [Test, tail]
|
29
28
|
when "trace"; [Trace, tail]
|
30
29
|
when "untrace"; [Untrace, tail]
|
31
30
|
end
|
@@ -68,18 +67,26 @@ module Piggly
|
|
68
67
|
else
|
69
68
|
head, _ = config.filters
|
70
69
|
|
71
|
-
start =
|
72
|
-
case head.first
|
73
|
-
when :+; []
|
74
|
-
when :-; index.procedures
|
75
|
-
end
|
70
|
+
start = index.procedures
|
76
71
|
|
77
72
|
config.filters.inject(start) do |s, pair|
|
78
73
|
case pair.first
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
74
|
+
when :+
|
75
|
+
puts "Selecting procedures"
|
76
|
+
o = s.select(&pair.last)
|
77
|
+
puts "Selected #{ o.count} procedures"
|
78
|
+
puts "Selected:"
|
79
|
+
o.each do |x| puts x.name end
|
80
|
+
puts "---"
|
81
|
+
o
|
82
|
+
when :-
|
83
|
+
puts "Rejecting procedures"
|
84
|
+
o = s.reject(&pair.last)
|
85
|
+
puts "Rejected #{s.count - o.count} procedures"
|
86
|
+
puts "Rejected:"
|
87
|
+
((o-s)|(s-o)).each do |x| puts x.name end
|
88
|
+
puts "---"
|
89
|
+
o
|
83
90
|
end
|
84
91
|
end
|
85
92
|
end
|
@@ -110,11 +117,11 @@ module Piggly
|
|
110
117
|
end
|
111
118
|
|
112
119
|
def o_version(config)
|
113
|
-
lambda { puts "piggly #{VERSION} #{VERSION::RELEASE_DATE}"; exit! }
|
120
|
+
lambda {|x| puts "piggly #{VERSION} #{VERSION::RELEASE_DATE}"; exit! }
|
114
121
|
end
|
115
122
|
|
116
123
|
def o_dry_run(config)
|
117
|
-
lambda { config.dry_run = true }
|
124
|
+
lambda {|x| config.dry_run = true }
|
118
125
|
end
|
119
126
|
|
120
127
|
def o_select(config)
|
data/lib/piggly/command.rb
CHANGED
@@ -22,6 +22,7 @@ module Piggly
|
|
22
22
|
cache = CacheDir.new(cache_path(procedure.source_path(@config)))
|
23
23
|
|
24
24
|
if stale?(procedure)
|
25
|
+
begin
|
25
26
|
$stdout.puts "Compiling #{procedure.name}"
|
26
27
|
tree = Parser.parse(IO.read(procedure.source_path(@config)))
|
27
28
|
tree = tree.force! if tree.respond_to?(:thunk?)
|
@@ -30,6 +31,17 @@ module Piggly
|
|
30
31
|
code = traverse(tree, procedure.oid, tags)
|
31
32
|
|
32
33
|
cache.replace(:tree => tree, :code => code, :tags => tags)
|
34
|
+
rescue RuntimeError => e
|
35
|
+
$stdout.puts <<-EXMSG
|
36
|
+
****
|
37
|
+
Error compiling procedure #{procedure.name}
|
38
|
+
Source: #{procedure.source_path(@config)}
|
39
|
+
Exception Message:
|
40
|
+
#{e.message}
|
41
|
+
****
|
42
|
+
EXMSG
|
43
|
+
end
|
44
|
+
|
33
45
|
end
|
34
46
|
|
35
47
|
cache
|
@@ -49,10 +61,10 @@ module Piggly
|
|
49
61
|
# IF(test) becomes IF(piggly_cond(TAG, test)) instead of IFpiggly_cond(TAG, (test))
|
50
62
|
pre, cond = node.cond.expr.text_value.match(/\A(\(?[\t\n\r ]*)(.+)\z/m).captures
|
51
63
|
node.cond.source_text = ""
|
52
|
-
|
64
|
+
|
53
65
|
tags << node.cond.tag(oid)
|
54
66
|
|
55
|
-
node.condStub.source_text = "#{pre}piggly_cond($PIGGLY$#{node.cond.tag_id}$PIGGLY$, (#{cond}))"
|
67
|
+
node.condStub.source_text = "#{pre}public.piggly_cond($PIGGLY$#{node.cond.tag_id}$PIGGLY$, (#{cond}))"
|
56
68
|
node.condStub.source_text << traverse(node.cond.tail, oid, tags) # preserve trailing whitespace
|
57
69
|
end
|
58
70
|
|
@@ -63,17 +75,17 @@ module Piggly
|
|
63
75
|
|
64
76
|
# Hack to simulate a loop conditional statement in stmtForLoop and stmtLoop.
|
65
77
|
# signal condition is true when body is executed, and false when exit stub is reached
|
66
|
-
node.bodyStub.source_text = "perform piggly_cond($PIGGLY$#{node.cond.tag_id}$PIGGLY$, true);#{node.indent(:bodySpace)}"
|
67
|
-
node.bodyStub.source_text << "perform piggly_branch($PIGGLY$#{node.body.tag_id}$PIGGLY$);#{node.indent(:bodySpace)}"
|
78
|
+
node.bodyStub.source_text = "perform public.piggly_cond($PIGGLY$#{node.cond.tag_id}$PIGGLY$, true);#{node.indent(:bodySpace)}"
|
79
|
+
node.bodyStub.source_text << "perform public.piggly_branch($PIGGLY$#{node.body.tag_id}$PIGGLY$);#{node.indent(:bodySpace)}"
|
68
80
|
|
69
81
|
if node.respond_to?(:doneStub)
|
70
82
|
# Signal the end of an iteration was reached
|
71
|
-
node.doneStub.source_text = "#{node.indent(:bodySpace)}perform piggly_signal($PIGGLY$#{node.cond.tag_id}$PIGGLY$, $PIGGLY$@$PIGGLY$);"
|
83
|
+
node.doneStub.source_text = "#{node.indent(:bodySpace)}perform public.piggly_signal($PIGGLY$#{node.cond.tag_id}$PIGGLY$, $PIGGLY$@$PIGGLY$);"
|
72
84
|
node.doneStub.source_text << node.body.indent
|
73
85
|
end
|
74
86
|
|
75
87
|
# Signal the loop terminated
|
76
|
-
node.exitStub.source_text = "\n#{node.indent}perform piggly_cond($PIGGLY$#{node.cond.tag_id}$PIGGLY$, false);"
|
88
|
+
node.exitStub.source_text = "\n#{node.indent}perform public.piggly_cond($PIGGLY$#{node.cond.tag_id}$PIGGLY$, false);"
|
77
89
|
elsif node.respond_to?(:body)
|
78
90
|
# Unconditional branches (or blocks)
|
79
91
|
# BEGIN ... END;
|
@@ -81,7 +93,7 @@ module Piggly
|
|
81
93
|
# CONTINUE label;
|
82
94
|
# EXIT label;
|
83
95
|
tags << node.body.tag(oid)
|
84
|
-
node.bodyStub.source_text = "perform piggly_branch($PIGGLY$#{node.body.tag_id}$PIGGLY$);#{node.indent(:bodySpace)}"
|
96
|
+
node.bodyStub.source_text = "perform public.piggly_branch($PIGGLY$#{node.body.tag_id}$PIGGLY$);#{node.indent(:bodySpace)}"
|
85
97
|
end
|
86
98
|
end
|
87
99
|
|
@@ -4,27 +4,55 @@ module Piggly
|
|
4
4
|
class QualifiedType
|
5
5
|
attr_reader :schema, :name
|
6
6
|
|
7
|
-
def
|
8
|
-
|
7
|
+
def self.parse(name, rest = nil)
|
8
|
+
if rest.to_s == ""
|
9
|
+
schema = nil
|
10
|
+
else
|
11
|
+
schema = name
|
12
|
+
name = rest
|
13
|
+
end
|
14
|
+
|
15
|
+
case name
|
16
|
+
when /(.*)\[\]$/
|
17
|
+
name = $1
|
18
|
+
array = "[]"
|
19
|
+
else
|
20
|
+
array = ""
|
21
|
+
end
|
22
|
+
|
23
|
+
if schema.to_s == ""
|
24
|
+
fst, snd = name.split(".", 2)
|
25
|
+
if snd.nil?
|
26
|
+
new(nil, fst, array)
|
27
|
+
else
|
28
|
+
new(fst, snd, array)
|
29
|
+
end
|
30
|
+
else
|
31
|
+
new(schema, name, array)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(schema, name, array)
|
36
|
+
@schema, @name, @array = schema, name, array
|
9
37
|
end
|
10
38
|
|
11
39
|
def shorten
|
12
|
-
self.class.new(nil, @name)
|
40
|
+
self.class.new(nil, @name, @array)
|
13
41
|
end
|
14
42
|
|
15
43
|
def quote
|
16
44
|
if @schema
|
17
|
-
'"' + @schema + '"."' + @name + '"'
|
45
|
+
'"' + @schema + '"."' + @name + '"' + @array
|
18
46
|
else
|
19
|
-
'"' + @name + '"'
|
47
|
+
'"' + @name + '"' + @array
|
20
48
|
end
|
21
49
|
end
|
22
50
|
|
23
51
|
def to_s
|
24
52
|
if @schema and !%w[public pg_catalog].include?(@schema)
|
25
|
-
@schema + "." + readable(@name)
|
53
|
+
@schema + "." + readable(@name) + @array
|
26
54
|
else
|
27
|
-
readable(@name)
|
55
|
+
readable(@name) + @array
|
28
56
|
end
|
29
57
|
end
|
30
58
|
|
@@ -42,7 +70,6 @@ module Piggly
|
|
42
70
|
# group by ret.typname, format_type(ret.oid, null)
|
43
71
|
# order by format_type(ret.oid, null);
|
44
72
|
case name
|
45
|
-
when /(.*)\[\]/ then "_#{normalize($1)}"
|
46
73
|
when '"any"' then "any"
|
47
74
|
when "bigint" then "int8"
|
48
75
|
when "bit varying" then "varbit"
|
@@ -63,10 +63,11 @@ module Piggly
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def defaults(exprs, count, total)
|
66
|
-
exprs = exprs.split(", ")
|
66
|
+
exprs = if exprs.nil? then [] else exprs.split(", ") end
|
67
|
+
|
67
68
|
nreqd = total - count
|
68
69
|
|
69
|
-
if nreqd
|
70
|
+
if nreqd >= 0 and exprs.length == count
|
70
71
|
Array.new(nreqd) + exprs
|
71
72
|
else
|
72
73
|
raise "Couldn't parse default arguments"
|
@@ -125,17 +126,25 @@ module Piggly
|
|
125
126
|
def from_hash(hash)
|
126
127
|
new(hash["source"],
|
127
128
|
hash["oid"],
|
128
|
-
QualifiedName.new(hash["nschema"], hash["name"]),
|
129
|
+
QualifiedName.new(hash["nschema"].to_s, hash["name"].to_s),
|
129
130
|
hash["strict"] == "t",
|
130
131
|
hash["secdef"] == "t",
|
131
132
|
hash["setof"] == "t",
|
132
|
-
QualifiedType.
|
133
|
+
QualifiedType.parse(hash["tschema"].to_s, hash["type"].to_s),
|
133
134
|
volatility(hash["volatility"]),
|
134
|
-
hash["arg_modes"].to_s.split(",").map{|x| mode(x.strip) },
|
135
|
+
coalesce(hash["arg_modes"].to_s.split(",").map{|x| mode(x.strip) }, ["in"]*hash["arg_count"].to_i),
|
135
136
|
hash["arg_names"].to_s.split(",").map{|x| QualifiedName.new(nil, x.strip) },
|
136
|
-
hash["arg_types"].to_s.split(",").map{|x| QualifiedType.
|
137
|
+
hash["arg_types"].to_s.split(",").map{|x| QualifiedType.parse(x.strip) },
|
137
138
|
defaults(hash["arg_defaults"], hash["arg_defaults_count"].to_i, hash["arg_count"].to_i))
|
138
139
|
end
|
140
|
+
|
141
|
+
def coalesce(value, default)
|
142
|
+
if [nil, "", []].include?(value)
|
143
|
+
default
|
144
|
+
else
|
145
|
+
value
|
146
|
+
end
|
147
|
+
end
|
139
148
|
end
|
140
149
|
|
141
150
|
end
|
@@ -256,9 +256,7 @@ grammar Piggly
|
|
256
256
|
end
|
257
257
|
|
258
258
|
rule stmtGetDiag
|
259
|
-
kwGET tSpace
|
260
|
-
kwPERFORM tSpace
|
261
|
-
notImplemented
|
259
|
+
kwGET tSpace kwSTACKED tSpace kwDIAGNOSTICS tSpace expressionUntilSemiColon ';' <Piggly::Parser::Nodes::Expression>
|
262
260
|
end
|
263
261
|
|
264
262
|
rule stmtNull
|
@@ -482,7 +480,8 @@ grammar Piggly
|
|
482
480
|
/ 'create'
|
483
481
|
/ 'set'
|
484
482
|
/ 'start'
|
485
|
-
/ 'notify'
|
483
|
+
/ 'notify'
|
484
|
+
/ 'with' ) ![a-z0-9] <Piggly::Parser::Nodes::TKeyword>
|
486
485
|
end
|
487
486
|
|
488
487
|
rule keyword
|
@@ -692,6 +691,10 @@ grammar Piggly
|
|
692
691
|
'scroll' ![a-z0-9_] <Piggly::Parser::Nodes::TKeyword>
|
693
692
|
end
|
694
693
|
|
694
|
+
rule kwSTACKED
|
695
|
+
'stacked' ![a-z0-9_] <Piggly::Parser::Nodes::TKeyword>
|
696
|
+
end
|
697
|
+
|
695
698
|
rule kwSTRICT
|
696
699
|
'strict' ![a-z0-9_] <Piggly::Parser::Nodes::TKeyword>
|
697
700
|
end
|
data/lib/piggly/profile.rb
CHANGED
data/lib/piggly/version.rb
CHANGED
data/spec/028_spec.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Piggly
|
4
|
+
describe "github issue #28" do
|
5
|
+
include GrammarHelper
|
6
|
+
|
7
|
+
it "can parse the a GET DIAGNOSTICS expression" do
|
8
|
+
body = 'GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT, text_var2 = PG_EXCEPTION_DETAIL, text_var3 = PG_EXCEPTION_HINT;'
|
9
|
+
|
10
|
+
node = parse(:statement, body)
|
11
|
+
node.should be_statement
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can parse a procedure with GET DIAGNOSTICS" do
|
15
|
+
body = <<-SQL
|
16
|
+
DECLARE
|
17
|
+
text_var1 text;
|
18
|
+
text_var2 text;
|
19
|
+
text_var3 text;
|
20
|
+
BEGIN
|
21
|
+
RETURN 1/0;
|
22
|
+
EXCEPTION WHEN SQLSTATE '22012' THEN
|
23
|
+
GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,
|
24
|
+
text_var2 = PG_EXCEPTION_DETAIL,
|
25
|
+
text_var3 = PG_EXCEPTION_HINT;
|
26
|
+
END
|
27
|
+
SQL
|
28
|
+
|
29
|
+
node = parse(:start, body.strip)
|
30
|
+
node.count{|e| e.branch? }.should == 1 # catch
|
31
|
+
node.find{|e| e.branch? }.body.source_text.strip.should =~ /^GET.+HINT;/m
|
32
|
+
end
|
33
|
+
|
34
|
+
it "can parse WITH <> AS <> SELECT <> SQL query" do
|
35
|
+
body = <<-SQL
|
36
|
+
DECLARE
|
37
|
+
BEGIN
|
38
|
+
WITH n AS (SELECT first_name FROM users where id > 1000)
|
39
|
+
SELECT * FROM people WHERE people.first_name = n.first_name;
|
40
|
+
RETURN 1;
|
41
|
+
END
|
42
|
+
SQL
|
43
|
+
|
44
|
+
node = parse(:start, body.strip.downcase)
|
45
|
+
node.count{|e| e.sql? }.should == 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -44,7 +44,7 @@ describe Profile do
|
|
44
44
|
context "when message doesn't match PATTERN" do
|
45
45
|
it "prints the message to stderr" do
|
46
46
|
message = "WARNING: Parameter was NULL and I don't like it!"
|
47
|
-
@stderr.should_receive(:puts).with(message)
|
47
|
+
@stderr.should_receive(:puts).with("unknown trace: #{message}")
|
48
48
|
@callback.call(message)
|
49
49
|
end
|
50
50
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: piggly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kvle Putnam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: treetop
|
@@ -52,7 +52,6 @@ files:
|
|
52
52
|
- lib/piggly/command.rb
|
53
53
|
- lib/piggly/command/base.rb
|
54
54
|
- lib/piggly/command/report.rb
|
55
|
-
- lib/piggly/command/test.rb
|
56
55
|
- lib/piggly/command/trace.rb
|
57
56
|
- lib/piggly/command/untrace.rb
|
58
57
|
- lib/piggly/compiler.rb
|
@@ -91,6 +90,7 @@ files:
|
|
91
90
|
- lib/piggly/util/process_queue.rb
|
92
91
|
- lib/piggly/util/thunk.rb
|
93
92
|
- lib/piggly/version.rb
|
93
|
+
- spec/028_spec.rb
|
94
94
|
- spec/examples/compiler/cacheable_spec.rb
|
95
95
|
- spec/examples/compiler/report_spec.rb
|
96
96
|
- spec/examples/compiler/trace_spec.rb
|
@@ -157,8 +157,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
157
|
version: '0'
|
158
158
|
requirements: []
|
159
159
|
rubyforge_project:
|
160
|
-
rubygems_version: 2.
|
160
|
+
rubygems_version: 2.2.2
|
161
161
|
signing_key:
|
162
162
|
specification_version: 4
|
163
163
|
summary: PL/pgSQL code coverage tool
|
164
164
|
test_files: []
|
165
|
+
has_rdoc: false
|
data/lib/piggly/command/test.rb
DELETED
@@ -1,157 +0,0 @@
|
|
1
|
-
module Piggly
|
2
|
-
module Command
|
3
|
-
|
4
|
-
#
|
5
|
-
# This command handles all the setup and teardown for running Ruby tests, that can
|
6
|
-
# otherwise be accomplished in a more manual fashion, using the other commands. It
|
7
|
-
# assumes that the test files will automatically establish a connection to the correct
|
8
|
-
# database when they are loaded (this is the case for Rails).
|
9
|
-
#
|
10
|
-
module Test
|
11
|
-
class << self
|
12
|
-
|
13
|
-
def main(argv)
|
14
|
-
benchmark do
|
15
|
-
tests, filters = parse_options(argv)
|
16
|
-
profile = Profile.new
|
17
|
-
|
18
|
-
# don't let rspec get these when loading spec files
|
19
|
-
ARGV.clear
|
20
|
-
|
21
|
-
load_tests(tests)
|
22
|
-
Command.connect_to_database
|
23
|
-
|
24
|
-
procedures = dump_procedures(filters)
|
25
|
-
|
26
|
-
if procedures.empty?
|
27
|
-
abort "No stored procedures in the database#{' matched your criteria' if filters.any?}"
|
28
|
-
end
|
29
|
-
|
30
|
-
result =
|
31
|
-
begin
|
32
|
-
trace(procedures)
|
33
|
-
clear_coverage
|
34
|
-
execute_tests
|
35
|
-
ensure
|
36
|
-
untrace(procedures)
|
37
|
-
end
|
38
|
-
|
39
|
-
create_index(procedures)
|
40
|
-
create_reports(procedures)
|
41
|
-
store_coverage
|
42
|
-
|
43
|
-
exit! result # avoid running tests again
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def benchmark
|
50
|
-
start = Time.now
|
51
|
-
value = yield
|
52
|
-
puts " > Completed in #{'%0.2f' % (Time.now - start)} seconds"
|
53
|
-
return value
|
54
|
-
end
|
55
|
-
|
56
|
-
#
|
57
|
-
# Parses command-line options
|
58
|
-
#
|
59
|
-
def parse_options(argv)
|
60
|
-
filters = []
|
61
|
-
|
62
|
-
opts = OptionParser.new do |opts|
|
63
|
-
opts.on("-I", "--include PATHS", "Prepend paths to $LOAD_PATH (colon separated list)", &Command.method(:opt_include_path))
|
64
|
-
opts.on("-o", "--report-root PATH", "Report output directory", &Command.method(:opt_report_root))
|
65
|
-
opts.on("-c", "--cache-root PATH", "Local cache directory", &Command.method(:opt_cache_root))
|
66
|
-
|
67
|
-
opts.on("-n", "--name PATTERN", "Trace stored procedures matching PATTERN") do |opt|
|
68
|
-
if m = opt.match(%r{^/(.+)/$})
|
69
|
-
filters << lambda{|p| p.name.match(m.captures.first) }
|
70
|
-
else
|
71
|
-
filters << lambda{|p| p.name === opt }
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
opts.on("-a", "--aggregate", "Aggregate data from the previous run", &Command.method(:opt_aggregate))
|
76
|
-
opts.on("-V", "--version", "Show version", &Command.method(:opt_version))
|
77
|
-
opts.on("-h", "--help", "Show this message") do
|
78
|
-
puts opts
|
79
|
-
exit! 0
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
begin
|
84
|
-
opts.parse! argv
|
85
|
-
raise OptionParser::MissingArgument, "no tests specified" if argv.empty?
|
86
|
-
rescue OptionParser::InvalidOption,
|
87
|
-
OptionParser::InvalidArgument,
|
88
|
-
OptionParser::MissingArgument
|
89
|
-
puts opts
|
90
|
-
puts
|
91
|
-
puts $!
|
92
|
-
|
93
|
-
exit! 1
|
94
|
-
end
|
95
|
-
|
96
|
-
test_paths = argv.map{|p| Dir[p] }.flatten.sort
|
97
|
-
|
98
|
-
return test_paths, filters
|
99
|
-
end
|
100
|
-
|
101
|
-
def load_tests(tests)
|
102
|
-
puts "Loading #{tests.size} test files"
|
103
|
-
benchmark { tests.each{|file| load file }}
|
104
|
-
end
|
105
|
-
|
106
|
-
#
|
107
|
-
# Writes all stored procedures in the database to disk
|
108
|
-
#
|
109
|
-
def dump_procedures(filters)
|
110
|
-
Command::Trace.dump_procedures(filters)
|
111
|
-
end
|
112
|
-
|
113
|
-
#
|
114
|
-
# Compiles all the stored procedures on disk and installs them
|
115
|
-
#
|
116
|
-
def trace(procedures)
|
117
|
-
benchmark { Command::Trace.trace(procedures) }
|
118
|
-
end
|
119
|
-
|
120
|
-
def clear_coverage
|
121
|
-
Command::Report.clear_coverage
|
122
|
-
end
|
123
|
-
|
124
|
-
def execute_tests
|
125
|
-
if defined? ::Test::Unit::AutoRunner
|
126
|
-
::Test::Unit::AutoRunner.run
|
127
|
-
elsif defined? ::RSpec::Core
|
128
|
-
::Rspec::Core::Runner.run(ARGV, $stderr, $stdout)
|
129
|
-
elsif defined? ::Spec::Runner
|
130
|
-
::Spec::Runner.run
|
131
|
-
elsif defined? ::MiniTest::Unit
|
132
|
-
::MiniTest::Unit.new.run(ARGV)
|
133
|
-
else
|
134
|
-
raise "Neither Test::Unit, MiniTest, nor RSpec were detected"
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def store_coverage(profile)
|
139
|
-
benchmark { Command::Report.store_coverage(profile) }
|
140
|
-
end
|
141
|
-
|
142
|
-
def untrace(procedures)
|
143
|
-
benchmark { Command::Untrace.untrace(procedures) }
|
144
|
-
end
|
145
|
-
|
146
|
-
def create_index(procedures, profile)
|
147
|
-
benchmark { Command::Report.create_index(procedures, profile) }
|
148
|
-
end
|
149
|
-
|
150
|
-
def create_reports(procedures, profile)
|
151
|
-
benchmark { Command::Report.create_reports(procedures, profile) }
|
152
|
-
end
|
153
|
-
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|