piggly 1.2.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +163 -0
  3. data/Rakefile +29 -15
  4. data/bin/piggly +4 -244
  5. data/lib/piggly.rb +19 -17
  6. data/lib/piggly/command.rb +9 -0
  7. data/lib/piggly/command/base.rb +148 -0
  8. data/lib/piggly/command/report.rb +162 -0
  9. data/lib/piggly/command/test.rb +157 -0
  10. data/lib/piggly/command/trace.rb +90 -0
  11. data/lib/piggly/command/untrace.rb +78 -0
  12. data/lib/piggly/compiler.rb +7 -5
  13. data/lib/piggly/compiler/cache_dir.rb +119 -0
  14. data/lib/piggly/compiler/coverage_report.rb +63 -0
  15. data/lib/piggly/compiler/trace_compiler.rb +105 -0
  16. data/lib/piggly/config.rb +47 -22
  17. data/lib/piggly/dumper.rb +9 -0
  18. data/lib/piggly/dumper/index.rb +121 -0
  19. data/lib/piggly/dumper/qualified_name.rb +36 -0
  20. data/lib/piggly/dumper/qualified_type.rb +81 -0
  21. data/lib/piggly/dumper/reified_procedure.rb +142 -0
  22. data/lib/piggly/dumper/skeleton_procedure.rb +102 -0
  23. data/lib/piggly/installer.rb +84 -42
  24. data/lib/piggly/parser.rb +43 -49
  25. data/lib/piggly/parser/grammar.tt +289 -313
  26. data/lib/piggly/parser/nodes.rb +270 -211
  27. data/lib/piggly/parser/traversal.rb +35 -33
  28. data/lib/piggly/parser/treetop_ruby19_patch.rb +1 -1
  29. data/lib/piggly/profile.rb +81 -60
  30. data/lib/piggly/reporter.rb +5 -18
  31. data/lib/piggly/reporter/base.rb +103 -0
  32. data/lib/piggly/reporter/html_dsl.rb +63 -0
  33. data/lib/piggly/reporter/index.rb +108 -0
  34. data/lib/piggly/reporter/procedure.rb +104 -0
  35. data/lib/piggly/reporter/resources/highlight.js +21 -0
  36. data/lib/piggly/reporter/{piggly.css → resources/piggly.css} +52 -12
  37. data/lib/piggly/reporter/{sortable.js → resources/sortable.js} +0 -0
  38. data/lib/piggly/tags.rb +280 -0
  39. data/lib/piggly/task.rb +191 -40
  40. data/lib/piggly/util.rb +8 -27
  41. data/lib/piggly/util/blankslate.rb +114 -0
  42. data/lib/piggly/util/cacheable.rb +19 -0
  43. data/lib/piggly/util/enumerable.rb +44 -0
  44. data/lib/piggly/util/file.rb +17 -0
  45. data/lib/piggly/util/process_queue.rb +96 -0
  46. data/lib/piggly/util/thunk.rb +39 -0
  47. data/lib/piggly/version.rb +8 -8
  48. data/spec/examples/compiler/cacheable_spec.rb +190 -0
  49. data/spec/examples/compiler/report_spec.rb +25 -0
  50. data/spec/{compiler → examples/compiler}/trace_spec.rb +7 -57
  51. data/spec/examples/config_spec.rb +61 -0
  52. data/spec/examples/dumper/index_spec.rb +197 -0
  53. data/spec/examples/dumper/procedure_spec.rb +116 -0
  54. data/spec/{grammar → examples/grammar}/expression_spec.rb +60 -60
  55. data/spec/{grammar → examples/grammar}/statements/assignment_spec.rb +15 -15
  56. data/spec/examples/grammar/statements/declaration_spec.rb +21 -0
  57. data/spec/{grammar → examples/grammar}/statements/exception_spec.rb +10 -10
  58. data/spec/{grammar → examples/grammar}/statements/if_spec.rb +47 -34
  59. data/spec/{grammar → examples/grammar}/statements/loop_spec.rb +5 -5
  60. data/spec/{grammar → examples/grammar}/statements/sql_spec.rb +11 -11
  61. data/spec/{grammar → examples/grammar}/tokens/comment_spec.rb +11 -11
  62. data/spec/{grammar → examples/grammar}/tokens/datatype_spec.rb +14 -8
  63. data/spec/{grammar → examples/grammar}/tokens/identifier_spec.rb +26 -10
  64. data/spec/{grammar → examples/grammar}/tokens/keyword_spec.rb +5 -5
  65. data/spec/{grammar → examples/grammar}/tokens/label_spec.rb +7 -7
  66. data/spec/{grammar → examples/grammar}/tokens/literal_spec.rb +1 -1
  67. data/spec/examples/grammar/tokens/lval_spec.rb +50 -0
  68. data/spec/{grammar → examples/grammar}/tokens/number_spec.rb +1 -1
  69. data/spec/{grammar → examples/grammar}/tokens/sqlkeywords_spec.rb +1 -1
  70. data/spec/{grammar → examples/grammar}/tokens/string_spec.rb +9 -9
  71. data/spec/{grammar → examples/grammar}/tokens/whitespace_spec.rb +1 -1
  72. data/spec/examples/installer_spec.rb +59 -0
  73. data/spec/examples/parser/nodes_spec.rb +73 -0
  74. data/spec/examples/parser/traversal_spec.rb +14 -0
  75. data/spec/examples/parser_spec.rb +115 -0
  76. data/spec/examples/profile_spec.rb +153 -0
  77. data/spec/{reporter/html_spec.rb → examples/reporter/html/dsl_spec.rb} +0 -0
  78. data/spec/examples/reporter/html/index_spec.rb +0 -0
  79. data/spec/examples/reporter/html_spec.rb +1 -0
  80. data/spec/examples/reporter_spec.rb +0 -0
  81. data/spec/{compiler → examples}/tags_spec.rb +10 -10
  82. data/spec/examples/task_spec.rb +0 -0
  83. data/spec/examples/util/cacheable_spec.rb +41 -0
  84. data/spec/examples/util/enumerable_spec.rb +64 -0
  85. data/spec/examples/util/file_spec.rb +40 -0
  86. data/spec/examples/util/process_queue_spec.rb +16 -0
  87. data/spec/examples/util/thunk_spec.rb +58 -0
  88. data/spec/examples/version_spec.rb +0 -0
  89. data/spec/issues/007_spec.rb +25 -0
  90. data/spec/issues/008_spec.rb +73 -0
  91. data/spec/issues/018_spec.rb +25 -0
  92. data/spec/spec_helper.rb +253 -9
  93. metadata +136 -93
  94. data/README.markdown +0 -116
  95. data/lib/piggly/compiler/cache.rb +0 -151
  96. data/lib/piggly/compiler/pretty.rb +0 -67
  97. data/lib/piggly/compiler/queue.rb +0 -46
  98. data/lib/piggly/compiler/tags.rb +0 -244
  99. data/lib/piggly/compiler/trace.rb +0 -91
  100. data/lib/piggly/filecache.rb +0 -40
  101. data/lib/piggly/parser/parser.rb +0 -11794
  102. data/lib/piggly/reporter/html.rb +0 -207
  103. data/spec/compiler/cache_spec.rb +0 -9
  104. data/spec/compiler/pretty_spec.rb +0 -9
  105. data/spec/compiler/queue_spec.rb +0 -3
  106. data/spec/compiler/rewrite_spec.rb +0 -3
  107. data/spec/config_spec.rb +0 -58
  108. data/spec/filecache_spec.rb +0 -70
  109. data/spec/fixtures/snippets.sql +0 -158
  110. data/spec/grammar/tokens/lval_spec.rb +0 -50
  111. data/spec/parser_spec.rb +0 -8
  112. data/spec/profile_spec.rb +0 -5
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ module Piggly
4
+
5
+ describe Config do
6
+ before do
7
+ @config = Config.new
8
+ end
9
+
10
+ it "has class accessors and mutators" do
11
+ @config.should respond_to(:cache_root)
12
+ @config.should respond_to(:cache_root=)
13
+ @config.should respond_to(:report_root)
14
+ @config.should respond_to(:report_root=)
15
+ @config.should respond_to(:trace_prefix)
16
+ @config.should respond_to(:trace_prefix=)
17
+ end
18
+
19
+ it "has default values" do
20
+ @config.cache_root = nil
21
+ @config.cache_root.should_not be_nil
22
+ @config.cache_root.should =~ /cache$/
23
+
24
+ @config.report_root = nil
25
+ @config.report_root.should_not be_nil
26
+ @config.report_root.should =~ /reports$/
27
+
28
+ @config.trace_prefix = nil
29
+ @config.trace_prefix.should_not be_nil
30
+ @config.trace_prefix.should == 'PIGGLY'
31
+ end
32
+
33
+ describe "path" do
34
+ it "doesn't reparent absolute paths" do
35
+ @config.path('/tmp', '/usr/bin/ps').should == '/usr/bin/ps'
36
+ @config.path('A:/data/tmp', 'C:/USER/tmp').should == 'C:/USER/tmp'
37
+ @config.path('/tmp/data', '../data.txt').should == '../data.txt'
38
+ end
39
+
40
+ it "reparents relative paths" do
41
+ @config.path('/tmp', 'note.txt').should == '/tmp/note.txt'
42
+ end
43
+
44
+ it "doesn't require path parameter" do
45
+ @config.path('/tmp').should == '/tmp'
46
+ end
47
+ end
48
+
49
+ describe "mkpath" do
50
+ it "creates root if doesn't exist" do
51
+ FileUtils.should_receive(:makedirs).with('x/y').once.and_return(true)
52
+ @config.mkpath('x/y', 'z')
53
+ end
54
+
55
+ it "throws an error on path components that exist as files" do
56
+ lambda { @config.mkpath('/etc/passwd/file') }.should raise_error(Errno::EEXIST)
57
+ end
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,197 @@
1
+ require "spec_helper"
2
+
3
+ module Piggly
4
+
5
+ describe Dumper::Index do
6
+ before do
7
+ # make sure not to create directories all over the file system during the test
8
+ Config.stub(:mkpath).and_return{|root, file| File.join(root, file) }
9
+
10
+ @config = Config.new
11
+ @index = Dumper::Index.new(@config)
12
+ end
13
+
14
+ context "when cache file doesn't exist" do
15
+ it "is empty" do
16
+ File.should_receive(:exists?).with(@index.path).and_return(false)
17
+ @index.procedures.should be_empty
18
+ end
19
+ end
20
+
21
+ context "when cache file exists" do
22
+ before do
23
+ File.stub(:exists?).with(@index.path).and_return(true)
24
+ end
25
+
26
+ context "when the cache index file is empty" do
27
+ it "is empty" do
28
+ File.should_receive(:read).with(@index.path).and_return([].to_yaml)
29
+ @index.procedures.should be_empty
30
+ end
31
+ end
32
+
33
+ context "when the cache index file has two entries" do
34
+ before do
35
+ @first = Dumper::ReifiedProcedure.from_hash \
36
+ "oid" => "1000",
37
+ "name" => "iterate",
38
+ "source" => "FIRST PROCEDURE SOURCE CODE"
39
+
40
+ @second = Dumper::ReifiedProcedure.from_hash \
41
+ "oid" => "2000",
42
+ "name" => "login",
43
+ "source" => "SECOND PROCEDURE SOURCE CODE"
44
+
45
+ File.stub(:read).with(@first.source_path(@config)).
46
+ and_return(@first.source(@config))
47
+
48
+ File.stub(:read).with(@second.source_path(@config)).
49
+ and_return(@second.source(@config))
50
+
51
+ File.stub(:read).with(@index.path).
52
+ and_return(YAML.dump([@first, @second]))
53
+ end
54
+
55
+ it "has two procedures" do
56
+ @index.procedures.should have(2).things
57
+ end
58
+
59
+ it "is indexed by identifier" do
60
+ @index[@first.identifier].identifier.should == @first.identifier
61
+ @index[@second.identifier].identifier.should == @second.identifier
62
+ end
63
+
64
+ it "reads each procedure's source_path" do
65
+ @index[@first.identifier].source(@config).should == @first.source(@config)
66
+ @index[@second.identifier].source(@config).should == @second.source(@config)
67
+ end
68
+
69
+ context "when the procedures used to be identified using another method" do
70
+ it "renames each procedure using the current identifier"
71
+ it "updates the index with the current identified_using"
72
+ it "writes the updated index to disk"
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "update" do
78
+ it "caches the source of new procedures"
79
+ it "updates the cached source of updated procedures"
80
+ it "purges the cached source of outdated procedures"
81
+ it "writes the cache index to disk"
82
+ it "does not write procedure source code within the cache index"
83
+ end
84
+
85
+ describe "label" do
86
+ def q(*ns)
87
+ Dumper::QualifiedName.new(*ns)
88
+ end
89
+
90
+ before do
91
+ @procedure = mock(:oid => 1,
92
+ :name => q("public", "foo"),
93
+ :type => q("private", "int"),
94
+ :arg_modes => ["in", "in"],
95
+ :arg_names => [],
96
+ :arg_types => [q("private", "int"), q("private", "varchar")])
97
+ end
98
+
99
+ context "when name is unique" do
100
+ context "and there is only one schema" do
101
+ before do
102
+ @index.stub(:procedures =>
103
+ [ @procedure,
104
+ mock(:oid => 2,
105
+ :name => q("public", "bar"),
106
+ :type => q("private", "int"),
107
+ :arg_modes => ["in"],
108
+ :arg_names => [],
109
+ :arg_types => []) ])
110
+ end
111
+
112
+ it "specifies schema.name" do
113
+ @index.label(@procedure).should == "foo"
114
+ end
115
+ end
116
+
117
+ context "and there is more than one schema" do
118
+ before do
119
+ @index.stub(:procedures =>
120
+ [ @procedure,
121
+ mock(:oid => 2,
122
+ :name => q("schema", "foo"),
123
+ :type => q("private", "int"),
124
+ :arg_modes => ["in"],
125
+ :arg_names => [],
126
+ :arg_types => []) ])
127
+ end
128
+
129
+ it "specifies schema.name" do
130
+ @index.label(@procedure).should == "public.foo"
131
+ end
132
+ end
133
+ end
134
+
135
+ context "when name is not unique" do
136
+ context "and schema.name is unique" do
137
+ before do
138
+ @index.stub(:procedures =>
139
+ [ @procedure,
140
+ mock(:oid => 2,
141
+ :name => q("schema", "foo"),
142
+ :type => q("private", "int"),
143
+ :arg_modes => ["in"],
144
+ :arg_names => [],
145
+ :arg_types => []) ])
146
+ end
147
+
148
+ it "specifies schema.name" do
149
+ @index.label(@procedure).should == "public.foo"
150
+ end
151
+ end
152
+
153
+ context "and schema.name is not unique" do
154
+ context "but argument types are unique" do
155
+ before do
156
+ @index.stub(:procedures =>
157
+ [ @procedure,
158
+ mock(:oid => 2,
159
+ :name => q("public", "foo"),
160
+ :type => q("private", "int"),
161
+ :arg_modes => ["in"],
162
+ :arg_names => [],
163
+ :arg_types => []) ])
164
+ end
165
+
166
+ it "specifies schema.name(types)" do
167
+ @index.label(@procedure).should ==
168
+ "foo(private.int, private.varchar)"
169
+ end
170
+ end
171
+
172
+ context "and argument types are not unique" do
173
+ context "but argument modes are unique" do
174
+ before do
175
+ @index.stub(:procedures =>
176
+ [ @procedure,
177
+ mock(:oid => 2,
178
+ :name => q("public", "foo"),
179
+ :type => q("private", "int"),
180
+ :arg_modes => ["out", "out"],
181
+ :arg_names => [],
182
+ :arg_types => [q("private", "int"), q("private", "varchar")]) ])
183
+ end
184
+
185
+ it "specifies schema.name(types and modes)" do
186
+ @index.label(@procedure).should ==
187
+ "foo(in private.int, in private.varchar)"
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
194
+
195
+ end
196
+
197
+ end
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+
3
+ module Piggly
4
+
5
+ describe Dumper::ReifiedProcedure do
6
+ describe "all" do
7
+ before do
8
+ # stub connection
9
+ end
10
+ end
11
+
12
+ describe "from_hash" do
13
+ it "abbreviates known return types"
14
+ it "leaves alone unknown argument types"
15
+
16
+ it "abbreviates known return types"
17
+ it "leaves alone unknown argument types"
18
+
19
+ it "maps known volatilities"
20
+ it "leaves alone unknown volatilities"
21
+
22
+ it "maps known argument modes"
23
+ it "leaves alone unknown argument modes"
24
+ end
25
+
26
+ describe "store_source" do
27
+ context "when source is already instrumented" do
28
+ it "raises an error"
29
+ end
30
+
31
+ context "when the procedure was identified using the current configuration setting" do
32
+ it "does not attempt to remove any files"
33
+ it "writes to the current location"
34
+ it "has the current identified_using property"
35
+ end
36
+
37
+ context "when the procedure was identified using some other configuration setting" do
38
+ it "removes any old report files"
39
+ it "removes any old trace cache files"
40
+ it "removes the old source cache files"
41
+ it "writes to the current location"
42
+ it "updates the identified_using property"
43
+ end
44
+ end
45
+ end
46
+
47
+ describe Dumper::SkeletonProcedure do
48
+ describe "definition" do
49
+ it "specifies namespace and function name"
50
+ it "specifies source code between dollar-quoted string tags"
51
+
52
+ context "with argument modes" do
53
+ it "specifies argument modes"
54
+ end
55
+
56
+ context "without argument modes" do
57
+ it "doesn't specify argument modes"
58
+ end
59
+
60
+ context "with strict modifier" do
61
+ it "specifies STRICT token"
62
+ end
63
+
64
+ context "without strict modifier" do
65
+ it "doesn't specify STRICT token"
66
+ end
67
+
68
+ context "with security definer modifier" do
69
+ it "specifies SECURITY DEFINER token"
70
+ end
71
+
72
+ context "without security definer modifier" do
73
+ it "doesn't specify SECURITY DEFINER token"
74
+ end
75
+
76
+ context "with set-returning type" do
77
+ it "specifies SETOF token"
78
+ end
79
+
80
+ context "without non set-returning type" do
81
+ it "doesn't specify SETOF token"
82
+ end
83
+
84
+ context "with stable volatility" do
85
+ it "specifies STABLE token"
86
+ end
87
+ end
88
+
89
+ describe "source_path" do
90
+ it "has a .plpgsql extension"
91
+ it "is within the Dumper directory"
92
+ end
93
+
94
+ describe "purge_source" do
95
+ context "when the procedure was identified using the current configuration setting" do
96
+ it "removes any old report files"
97
+ it "removes any old trace cache files"
98
+ it "removes the old source cache files"
99
+ it "removes the current report files"
100
+ it "removes the current trace cache files"
101
+ it "removes the current source cache files"
102
+ it "doesn't attempt to remove any other files"
103
+ end
104
+
105
+ context "when the procedure was identified using some other configuration setting" do
106
+ it "removes the current report files"
107
+ it "removes the current trace cache files"
108
+ it "removes the current source cache files"
109
+ it "doesn't attempt to remove any other files"
110
+ end
111
+ end
112
+
113
+ describe "equality operator"
114
+ end
115
+
116
+ end
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
1
+ require 'spec_helper'
2
2
 
3
3
  module Piggly
4
4
  describe Parser, "expressions" do
@@ -15,39 +15,39 @@ module Piggly
15
15
 
16
16
  it "can be a blank expression" do
17
17
  node, rest = parse_some(:expressionUntilSemiColon, ';')
18
- node.should be_a(Expression)
18
+ node.should be_expression
19
19
  node.source_text.should == ''
20
20
  rest.should == ';'
21
21
  end
22
22
 
23
23
  it "can be a comment" do
24
24
  node, rest = parse_some(:expressionUntilSemiColon, "/* comment */;")
25
- node.should be_a(Expression)
26
- node.count{|e| e.is_a?(TComment) }.should == 1
25
+ node.should be_expression
26
+ node.count{|e| e.comment? }.should == 1
27
27
 
28
28
  node, rest = parse_some(:expressionUntilSemiColon, "-- comment\n;")
29
- node.should be_a(Expression)
30
- node.count{|e| e.is_a?(TComment) }.should == 1
29
+ node.should be_expression
30
+ node.count{|e| e.comment? }.should == 1
31
31
  end
32
32
 
33
33
  it "can be a string" do
34
34
  node, rest = parse_some(:expressionUntilSemiColon, "'string';")
35
- node.should be_a(Expression)
36
- node.count{|e| e.is_a?(TString) }.should == 1
35
+ node.should be_expression
36
+ node.count{|e| e.string? }.should == 1
37
37
 
38
38
  node, rest = parse_some(:expressionUntilSemiColon, "$$ string $$;")
39
- node.should be_a(Expression)
40
- node.count{|e| e.is_a?(TString) }.should == 1
39
+ node.should be_expression
40
+ node.count{|e| e.string? }.should == 1
41
41
  end
42
42
 
43
43
  it "can be an arithmetic expression" do
44
44
  node, rest = parse_some(:expressionUntilSemiColon, "10 * (3 + x);")
45
- node.should be_a(Expression)
45
+ node.should be_expression
46
46
  end
47
47
 
48
48
  it "can be an SQL statement" do
49
49
  node, rest = parse_some(:expressionUntilSemiColon, "SELECT id FROM dataset;")
50
- node.should be_a(Expression)
50
+ node.should be_expression
51
51
  end
52
52
 
53
53
  it "can be an expression with comments embedded" do
@@ -56,8 +56,8 @@ module Piggly
56
56
  FROM "dataset" /* ; */ -- previous comments shouldn't terminate expression
57
57
  WHERE value IS /*NOT*/ NULL;
58
58
  SQL
59
- node.should be_a(Expression)
60
- node.count{|e| e.is_a?(TComment) }.should == 4
59
+ node.should be_expression
60
+ node.count{|e| e.comment? }.should == 4
61
61
  end
62
62
 
63
63
  it "can be an expression with strings and comments embedded" do
@@ -68,9 +68,9 @@ module Piggly
68
68
  AND length(value) > 10 -- 3. this comment in tail doesn't contain any 'string's
69
69
  /* 4. farewell comment in tail */;
70
70
  SQL
71
- node.should be_a(Expression)
72
- node.count{|e| e.is_a?(TComment) }.should == 4
73
- node.count{|e| e.is_a?(TString) }.should == 1
71
+ node.should be_expression
72
+ node.count{|e| e.comment? }.should == 4
73
+ node.count{|e| e.string? }.should == 1
74
74
  end
75
75
 
76
76
  it "can be an expression with strings embedded" do
@@ -81,19 +81,19 @@ module Piggly
81
81
  AND value <> '; this should not terminate expression'
82
82
  AND created_at = '2001-01-01';
83
83
  SQL
84
- node.should be_a(Expression)
85
- node.count{|e| e.is_a?(TString) }.should == 2
84
+ node.should be_expression
85
+ node.count{|e| e.string? }.should == 2
86
86
  end
87
87
 
88
- it "should combine trailing whitespace into 'tail' node" do
88
+ it "combines trailing whitespace into 'tail' node" do
89
89
  node, rest = parse_some(:expressionUntilSemiColon, "a := x + y \t;")
90
- node.should be_a(Expression)
90
+ node.should be_expression
91
91
  node.tail.source_text.should == " \t"
92
92
  end
93
93
 
94
- it "should combine trailing comments into 'tail' node" do
94
+ it "combines trailing comments into 'tail' node" do
95
95
  node, rest = parse_some(:expressionUntilSemiColon, "a := x + y /* note -- comment */;")
96
- node.should be_a(Expression)
96
+ node.should be_expression
97
97
  node.tail.source_text.should == ' /* note -- comment */'
98
98
 
99
99
  node, rest = parse_some(:expressionUntilSemiColon, <<-SQL)
@@ -103,7 +103,7 @@ module Piggly
103
103
  AND length(value) > 10 -- 3. this comment in tail doesn't contain any 'string's
104
104
  /* 4. farewell comment in tail */;
105
105
  SQL
106
- node.tail.count{|e| e.is_a?(TComment) }.should == 2
106
+ node.tail.count{|e| e.comment? }.should == 2
107
107
  end
108
108
  end
109
109
 
@@ -127,22 +127,22 @@ module Piggly
127
127
 
128
128
  it "can be a string" do
129
129
  node, rest = parse_some(:expressionUntilThen, "'string' THEN")
130
- node.should be_a(Expression)
131
- node.count{|e| e.is_a?(TString) }.should == 1
130
+ node.should be_expression
131
+ node.count{|e| e.string? }.should == 1
132
132
 
133
133
  node, rest = parse_some(:expressionUntilThen, "$$ string $$ THEN")
134
- node.should be_a(Expression)
135
- node.count{|e| e.is_a?(TString) }.should == 1
134
+ node.should be_expression
135
+ node.count{|e| e.string? }.should == 1
136
136
  end
137
137
 
138
138
  it "can be an arithmetic expression" do
139
139
  node, rest = parse_some(:expressionUntilThen, "10 * (3 + x) THEN")
140
- node.should be_a(Expression)
140
+ node.should be_expression
141
141
  end
142
142
 
143
143
  it "can be an SQL statement" do
144
144
  node, rest = parse_some(:expressionUntilThen, "SELECT id FROM dataset THEN")
145
- node.should be_a(Expression)
145
+ node.should be_expression
146
146
  end
147
147
 
148
148
  it "can be an expression with comments embedded" do
@@ -151,8 +151,8 @@ module Piggly
151
151
  FROM "dataset" /* THEN */ -- previous comments shouldn't terminate expression
152
152
  WHERE value IS /*NOT*/ NULL THEN
153
153
  SQL
154
- node.should be_a(Expression)
155
- node.count{|e| e.is_a?(TComment) }.should == 4
154
+ node.should be_expression
155
+ node.count{|e| e.comment? }.should == 4
156
156
  end
157
157
 
158
158
  it "can be an expression with strings and comments embedded" do
@@ -163,9 +163,9 @@ module Piggly
163
163
  AND length(value) > 10 -- 3. this comment in tail doesn't contain any 'string's
164
164
  /* 4. farewell comment in tail */ THEN
165
165
  SQL
166
- node.should be_a(Expression)
167
- node.count{|e| e.is_a?(TComment) }.should == 4
168
- node.count{|e| e.is_a?(TString) }.should == 1
166
+ node.should be_expression
167
+ node.count{|e| e.comment? }.should == 4
168
+ node.count{|e| e.string? }.should == 1
169
169
  end
170
170
 
171
171
  it "can be an expression with strings embedded" do
@@ -176,19 +176,19 @@ module Piggly
176
176
  AND value <> ' THEN this should not terminate expression'
177
177
  AND created_at = '2001-01-01' THEN
178
178
  SQL
179
- node.should be_a(Expression)
180
- node.count{|e| e.is_a?(TString) }.should == 2
179
+ node.should be_expression
180
+ node.count{|e| e.string? }.should == 2
181
181
  end
182
182
 
183
- it "should combine trailing whitespace into 'tail' node" do
183
+ it "combines trailing whitespace into 'tail' node" do
184
184
  node, rest = parse_some(:expressionUntilThen, "a := x + y \tTHEN")
185
- node.should be_a(Expression)
185
+ node.should be_expression
186
186
  node.tail.source_text.should == " \t"
187
187
  end
188
188
 
189
- it "should combine trailing comments into 'tail' node" do
189
+ it "combines trailing comments into 'tail' node" do
190
190
  node, rest = parse_some(:expressionUntilThen, "a := x + y /* note -- comment */THEN")
191
- node.should be_a(Expression)
191
+ node.should be_expression
192
192
  node.tail.source_text.should == ' /* note -- comment */'
193
193
 
194
194
  node, rest = parse_some(:expressionUntilThen, <<-SQL)
@@ -198,7 +198,7 @@ module Piggly
198
198
  AND length(value) > 10 -- 3. this comment in tail doesn't contain any 'string's
199
199
  /* 4. farewell comment in tail */THEN
200
200
  SQL
201
- node.tail.count{|e| e.is_a?(TComment) }.should == 2
201
+ node.tail.count{|e| e.comment? }.should == 2
202
202
  end
203
203
  end
204
204
 
@@ -222,22 +222,22 @@ module Piggly
222
222
 
223
223
  it "can be a string" do
224
224
  node, rest = parse_some(:expressionUntilLoop, "'string' LOOP")
225
- node.should be_a(Expression)
226
- node.count{|e| e.is_a?(TString) }.should == 1
225
+ node.should be_expression
226
+ node.count{|e| e.string? }.should == 1
227
227
 
228
228
  node, rest = parse_some(:expressionUntilLoop, "$$ string $$ LOOP")
229
- node.should be_a(Expression)
230
- node.count{|e| e.is_a?(TString) }.should == 1
229
+ node.should be_expression
230
+ node.count{|e| e.string? }.should == 1
231
231
  end
232
232
 
233
233
  it "can be an arithmetic expression" do
234
234
  node, rest = parse_some(:expressionUntilLoop, "10 * (3 + x) LOOP")
235
- node.should be_a(Expression)
235
+ node.should be_expression
236
236
  end
237
237
 
238
238
  it "can be an SQL statement" do
239
239
  node, rest = parse_some(:expressionUntilLoop, "SELECT id FROM dataset LOOP")
240
- node.should be_a(Expression)
240
+ node.should be_expression
241
241
  end
242
242
 
243
243
  it "can be an expression with comments embedded" do
@@ -246,8 +246,8 @@ module Piggly
246
246
  FROM "dataset" /* LOOP */ -- previous comments shouldn't terminate expression
247
247
  WHERE value IS /*NOT*/ NULL LOOP
248
248
  SQL
249
- node.should be_a(Expression)
250
- node.count{|e| e.is_a?(TComment) }.should == 4
249
+ node.should be_expression
250
+ node.count{|e| e.comment? }.should == 4
251
251
  end
252
252
 
253
253
  it "can be an expression with strings and comments embedded" do
@@ -258,9 +258,9 @@ module Piggly
258
258
  AND length(value) > 10 -- 3. this comment in tail doesn't contain any 'string's
259
259
  /* 4. farewell comment in tail */ LOOP
260
260
  SQL
261
- node.should be_a(Expression)
262
- node.count{|e| e.is_a?(TComment) }.should == 4
263
- node.count{|e| e.is_a?(TString) }.should == 1
261
+ node.should be_expression
262
+ node.count{|e| e.comment? }.should == 4
263
+ node.count{|e| e.string? }.should == 1
264
264
  end
265
265
 
266
266
  it "can be an expression with strings embedded" do
@@ -271,19 +271,19 @@ module Piggly
271
271
  AND value <> ' LOOP this should not terminate expression'
272
272
  AND created_at = '2001-01-01' LOOP
273
273
  SQL
274
- node.should be_a(Expression)
275
- node.count{|e| e.is_a?(TString) }.should == 2
274
+ node.should be_expression
275
+ node.count{|e| e.string? }.should == 2
276
276
  end
277
277
 
278
- it "should combine trailing whitespace into 'tail' node" do
278
+ it "combines trailing whitespace into 'tail' node" do
279
279
  node, rest = parse_some(:expressionUntilLoop, "a := x + y \tLOOP")
280
- node.should be_a(Expression)
280
+ node.should be_expression
281
281
  node.tail.source_text.should == " \t"
282
282
  end
283
283
 
284
- it "should combine trailing comments into 'tail' node" do
284
+ it "combines trailing comments into 'tail' node" do
285
285
  node, rest = parse_some(:expressionUntilLoop, "a := x + y /* note -- comment */LOOP")
286
- node.should be_a(Expression)
286
+ node.should be_expression
287
287
  node.tail.source_text.should == ' /* note -- comment */'
288
288
 
289
289
  node, rest = parse_some(:expressionUntilLoop, <<-SQL)
@@ -293,7 +293,7 @@ module Piggly
293
293
  AND length(value) > 10 -- 3. this comment in tail doesn't contain any 'string's
294
294
  /* 4. farewell comment in tail */LOOP
295
295
  SQL
296
- node.tail.count{|e| e.is_a?(TComment) }.should == 2
296
+ node.tail.count{|e| e.comment? }.should == 2
297
297
  end
298
298
  end
299
299