piggly 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -1,29 +1,54 @@
1
- # Piggly - PostgreSQL PL/pgSQL stored procedure code coverage
1
+ # Piggly - PostgreSQL PL/pgSQL stored-procedure code coverage for Ruby
2
+
3
+ ## Purpose
4
+
5
+ PL/pgSQL doesn't have much in the way of developer tools, and writing automated tests for
6
+ stored procedures can go much better when you know what you haven't tested. Code coverage
7
+ allows you to see which parts of your code haven't been executed.
2
8
 
3
9
  ## What's Piggly?
4
- Piggly is like [RCov] [1] for PostgreSQL's PL/pgSQL stored procedures. It reports on code
5
- coverage to help you identify untested parts of your code.
10
+
11
+ Piggly is a tool written in Ruby to track code coverage of PostgreSQL's PL/pgSQL stored
12
+ procedures. It reports on code coverage to help you identify untested parts of your code. You
13
+ write tests in Ruby against your stored procedures and run them with piggly.
14
+
15
+ ## How Does It Work?
16
+
17
+ Piggly tracks the execution of PostgreSQL's PL/pgSQL stored procedures by recompiling
18
+ the stored procedure with instrumentation code that uses RAISE WARNING to notify the
19
+ client of an execution event (e.g., a branch condition evaluating to true or false). It records
20
+ these events and generates prettified source code that is annotated with coverage details.
6
21
 
7
22
  ## Features
23
+
8
24
  * Branch, block, and loop coverage analysis
9
25
  * Instrumenting source-to-source compiler
10
26
  * Low test execution overhead
11
27
  * Reduced compilation times by use of disk caching
12
- * Readable and easily navigable reports (see example/piggly/reports/index.html)
13
- * Able to aggregate coverage across multiple runs
28
+ * Readable and easily-navigable reports (see example/piggly/reports/index.html)
29
+ * Possible to aggregate coverage across multiple runs
14
30
  * Test::Unit and RSpec compatible
15
31
 
16
32
  ## Limitations
33
+
17
34
  * Cannot parse aggregate definitions (but helper functions are fine)
18
35
  * Cannot parse nested dollar-quoted strings, eg $A$ ... $B$ ... $B$ ... $A$
19
36
  * Report generation is resource intensive and slow
37
+ * SQL statements are not instrumented, so their branches (COALESCE, WHERE-clauses, etc) aren't tracked
38
+ * Not all PL/pgSQL grammar is currently supported, but this is easily addressed
20
39
 
21
40
  ## Requirements
41
+
22
42
  * [Treetop] [2]
23
- * Stored procedures stored on the filesystem, defined with "CREATE OR REPLACE FUNCTION ..."
43
+ * Stored procedures stored on the filesystem, defined as `CREATE OR REPLACE FUNCTION`
24
44
  * The [ruby-pg driver] [3], and for the time being, ActiveRecord (some workaround should be possible)
25
45
 
46
+ ## How to Install
47
+
48
+ $ gem install piggly
49
+
26
50
  ## Usage
51
+
27
52
  Assume your stored procedures are in proc/, and the tests that should be exercising your
28
53
  stored procedures are in spec/.
29
54
 
@@ -57,16 +82,17 @@ stored procedures are in spec/.
57
82
  -rw-r--r-- 1 kputnam kputnam 1.3K 2010-04-19 14:25 piggly/reports/index.html
58
83
 
59
84
  Note the compilation can be slow on the first run, but on subsequent runs it shouldn't need
60
- to be compiled again. If a file is added or changed (based on mtime), it will be recompiled.
85
+ to compile everything again. If a file is added or changed (based on mtime), it will be recompiled.
61
86
 
62
87
  Piggly can also be run from Rake, with a task like:
88
+ require 'piggly/task'
63
89
 
64
90
  namespace :spec do
65
91
  Piggly::Task.new(:piggly => 'db:test:prepare') do |t|
66
92
  t.libs.push 'spec'
67
93
 
68
94
  t.test_files = FileList['spec/**/*_spec.rb']
69
- t.proc_files = FileList['procs/*.sql']
95
+ t.proc_files = FileList['proc/*.sql']
70
96
 
71
97
  # this can be used if piggly is frozen in a Rails application
72
98
  t.libs.concat Dir['vendor/gems/*/lib/'].sort.reverse
@@ -76,9 +102,15 @@ Piggly can also be run from Rake, with a task like:
76
102
 
77
103
  $ rake spec:piggly
78
104
 
105
+ ## Bugs & Issues
106
+
107
+ Please report any issues on the [github tracker] [4]
108
+
79
109
  ## Author
110
+
80
111
  * Kyle Putnam <putnam.kyle@gmail.com>
81
112
 
82
113
  [1]: http://github.com/relevance/rcov/
83
114
  [2]: http://github.com/nathansobo/treetop
84
115
  [3]: http://bitbucket.org/ged/ruby-pg/
116
+ [4]: http://github.com/kputnam/piggly/issues
data/bin/piggly CHANGED
@@ -26,6 +26,7 @@ module Piggly
26
26
  uninstall_procs(sources)
27
27
  create_index(sources)
28
28
  create_reports(sources)
29
+ exit! 0 # avoid running tests again
29
30
  end
30
31
  end
31
32
 
@@ -172,10 +173,12 @@ module Piggly
172
173
  end
173
174
 
174
175
  def execute_tests
175
- if defined? Spec::Runner
176
+ if defined? Test::Unit::AutoRunner
177
+ Test::Unit::AutoRunner.run
178
+ elsif defined? Spec::Runner
176
179
  Spec::Runner.run
177
180
  else
178
- Test::Unit::AutoRunner.run
181
+ raise "Neither RSpec nor Test::Unit were detected"
179
182
  end
180
183
  end
181
184
 
@@ -13,7 +13,7 @@ grammar Piggly
13
13
  procedureHeader
14
14
  name:tIdentifier tSpace?
15
15
  parameters:parameterList tSpace
16
- procedureReturn tSpace
16
+ procedureReturn
17
17
  return:tType tSpace kwAS tSpace
18
18
  procedureBody
19
19
  procedureFooter <Procedure>
@@ -24,7 +24,7 @@ grammar Piggly
24
24
  end
25
25
 
26
26
  rule procedureReturn
27
- 'returns' tSpace 'setof'? <TextNode>
27
+ 'returns' tSpace ( 'setof' tSpace )? <TextNode>
28
28
  end
29
29
 
30
30
  rule procedureBody
@@ -61,32 +61,28 @@ module Piggly
61
61
  elements[5]
62
62
  end
63
63
 
64
- def tSpace2
64
+ def return
65
65
  elements[6]
66
66
  end
67
67
 
68
- def return
68
+ def tSpace2
69
69
  elements[7]
70
70
  end
71
71
 
72
- def tSpace3
72
+ def kwAS
73
73
  elements[8]
74
74
  end
75
75
 
76
- def kwAS
76
+ def tSpace3
77
77
  elements[9]
78
78
  end
79
79
 
80
- def tSpace4
81
- elements[10]
82
- end
83
-
84
80
  def procedureBody
85
- elements[11]
81
+ elements[10]
86
82
  end
87
83
 
88
84
  def procedureFooter
89
- elements[12]
85
+ elements[11]
90
86
  end
91
87
  end
92
88
 
@@ -125,27 +121,23 @@ module Piggly
125
121
  r7 = _nt_procedureReturn
126
122
  s0 << r7
127
123
  if r7
128
- r8 = _nt_tSpace
124
+ r8 = _nt_tType
129
125
  s0 << r8
130
126
  if r8
131
- r9 = _nt_tType
127
+ r9 = _nt_tSpace
132
128
  s0 << r9
133
129
  if r9
134
- r10 = _nt_tSpace
130
+ r10 = _nt_kwAS
135
131
  s0 << r10
136
132
  if r10
137
- r11 = _nt_kwAS
133
+ r11 = _nt_tSpace
138
134
  s0 << r11
139
135
  if r11
140
- r12 = _nt_tSpace
136
+ r12 = _nt_procedureBody
141
137
  s0 << r12
142
138
  if r12
143
- r13 = _nt_procedureBody
139
+ r13 = _nt_procedureFooter
144
140
  s0 << r13
145
- if r13
146
- r14 = _nt_procedureFooter
147
- s0 << r14
148
- end
149
141
  end
150
142
  end
151
143
  end
@@ -280,6 +272,12 @@ module Piggly
280
272
  def tSpace
281
273
  elements[1]
282
274
  end
275
+ end
276
+
277
+ module ProcedureReturn1
278
+ def tSpace
279
+ elements[1]
280
+ end
283
281
 
284
282
  end
285
283
 
@@ -307,11 +305,24 @@ module Piggly
307
305
  r2 = _nt_tSpace
308
306
  s0 << r2
309
307
  if r2
308
+ i4, s4 = index, []
310
309
  if has_terminal?('setof', false, index)
311
- r4 = instantiate_node(SyntaxNode,input, index...(index + 5))
310
+ r5 = instantiate_node(SyntaxNode,input, index...(index + 5))
312
311
  @index += 5
313
312
  else
314
313
  terminal_parse_failure('setof')
314
+ r5 = nil
315
+ end
316
+ s4 << r5
317
+ if r5
318
+ r6 = _nt_tSpace
319
+ s4 << r6
320
+ end
321
+ if s4.last
322
+ r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
323
+ r4.extend(ProcedureReturn0)
324
+ else
325
+ @index = i4
315
326
  r4 = nil
316
327
  end
317
328
  if r4
@@ -324,7 +335,7 @@ module Piggly
324
335
  end
325
336
  if s0.last
326
337
  r0 = instantiate_node(TextNode,input, i0...index, s0)
327
- r0.extend(ProcedureReturn0)
338
+ r0.extend(ProcedureReturn1)
328
339
  else
329
340
  @index = i0
330
341
  r0 = nil
data/lib/piggly/task.rb CHANGED
@@ -23,7 +23,7 @@ module Piggly
23
23
  @test_files = []
24
24
  @proc_files = []
25
25
  @ruby_opts = []
26
- @output_dir = 'piggly/output'
26
+ @report_dir = 'piggly/report'
27
27
  @cache_root = 'piggly/cache'
28
28
  @piggly_path = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'piggly'))
29
29
  @piggly_opts = ''
@@ -47,7 +47,7 @@ module Piggly
47
47
 
48
48
  ruby opts.join(' ') + ' ' +
49
49
  @piggly_opts + ' ' +
50
- %{-o #{quote @output_dir} } +
50
+ %{-o #{quote @report_dir} } +
51
51
  %{-c #{quote @cache_root} } +
52
52
  proc_files.map{|s| %[-s "#{s}" ] }.join +
53
53
  test_files.map{|f| quote(f) }.join(' ')
@@ -2,11 +2,11 @@ module Piggly
2
2
  module VERSION
3
3
  MAJOR = 1
4
4
  MINOR = 2
5
- TINY = 0
5
+ TINY = 1
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
 
9
- RELEASE_DATE = '2010-04-19'
9
+ RELEASE_DATE = '2010-04-22'
10
10
 
11
11
  def self.to_s
12
12
  STRING
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: piggly
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyle Putnam
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-04-19 00:00:00 +00:00
12
+ date: 2010-04-22 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency