ruby-plsql-spec 0.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.
Files changed (47) hide show
  1. data/.gitignore +13 -0
  2. data/Gemfile +11 -0
  3. data/History.txt +5 -0
  4. data/INSTALL-Windows.markdown +55 -0
  5. data/License.txt +20 -0
  6. data/README.markdown +91 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/bin/plsql-spec +5 -0
  10. data/examples/source/award_bonus.rb +29 -0
  11. data/examples/source/betwnstr.rb +19 -0
  12. data/examples/source/remove_rooms_by_name.rb +45 -0
  13. data/examples/source/what_is_profiled.rb +207 -0
  14. data/examples/spec/award_bonus_spec.rb +35 -0
  15. data/examples/spec/betwnstr_spec.rb +24 -0
  16. data/examples/spec/database.yml +16 -0
  17. data/examples/spec/factories/employee_factory.rb +23 -0
  18. data/examples/spec/helpers/inspect_helpers.rb +17 -0
  19. data/examples/spec/helpers/oracle_ebs_helpers.rb +32 -0
  20. data/examples/spec/helpers/time_helpers.rb +5 -0
  21. data/examples/spec/oracle_ebs_spec.rb +61 -0
  22. data/examples/spec/remove_rooms_by_name_spec.rb +51 -0
  23. data/examples/spec/spec_helper.rb +78 -0
  24. data/examples/spec/what_is_profiled_spec.rb +12 -0
  25. data/lib/plsql/coverage.rb +262 -0
  26. data/lib/plsql/coverage/coverage.css +277 -0
  27. data/lib/plsql/coverage/details.html.erb +35 -0
  28. data/lib/plsql/coverage/index.html.erb +71 -0
  29. data/lib/plsql/coverage/jquery.min.js +154 -0
  30. data/lib/plsql/coverage/jquery.tablesorter.min.js +2 -0
  31. data/lib/plsql/coverage/proftab.sql +66 -0
  32. data/lib/plsql/coverage/rcov.js +43 -0
  33. data/lib/plsql/coverage/table_line.html.erb +15 -0
  34. data/lib/plsql/spec.rb +5 -0
  35. data/lib/plsql/spec/cli.rb +81 -0
  36. data/lib/plsql/spec/templates/database.yml +16 -0
  37. data/lib/plsql/spec/templates/helpers/inspect_helpers.rb +17 -0
  38. data/lib/plsql/spec/templates/helpers/time_helpers.rb +5 -0
  39. data/lib/plsql/spec/templates/spec_helper.rb +78 -0
  40. data/lib/plsql/spec/version.rb +5 -0
  41. data/lib/ruby-plsql-spec.rb +1 -0
  42. data/ruby-plsql-spec.gemspec +113 -0
  43. data/spec/plsql/coverage_spec.rb +246 -0
  44. data/spec/plsql/spec/cli_spec.rb +264 -0
  45. data/spec/spec.opts +6 -0
  46. data/spec/spec_helper.rb +61 -0
  47. metadata +177 -0
@@ -0,0 +1,246 @@
1
+ require "spec_helper"
2
+
3
+ describe "Coverage" do
4
+ def drop_profiler_tables
5
+ %w(plsql_profiler_data plsql_profiler_units plsql_profiler_runs).each do |table_name|
6
+ plsql.execute "drop table #{table_name} cascade constraints" rescue nil
7
+ end
8
+ end
9
+
10
+ before(:all) do
11
+ PLSQL::Coverage.reset_cache
12
+
13
+ plsql.connect! CONNECTION_PARAMS
14
+ drop_profiler_tables
15
+ @source = <<-SQL
16
+ CREATE OR REPLACE FUNCTION test_profiler RETURN VARCHAR2 IS
17
+ BEGIN
18
+ RETURN 'test_profiler';
19
+ EXCEPTION
20
+ WHEN OTHERS THEN
21
+ RETURN 'others';
22
+ END;
23
+ SQL
24
+ plsql.execute @source
25
+
26
+ @coverage_data = {
27
+ DATABASE_USER.upcase => {
28
+ "TEST_PROFILER" => {
29
+ 1=>0,
30
+ 3=>1,
31
+ 6=>0,
32
+ 7=>1
33
+ }
34
+ }
35
+ }
36
+
37
+ FileUtils.rm_rf(destination_root)
38
+ @directory = File.join(destination_root, 'coverage')
39
+ end
40
+
41
+ after(:all) do
42
+ plsql.execute "DROP FUNCTION test_profiler" rescue nil
43
+ drop_profiler_tables
44
+ end
45
+
46
+ describe "start" do
47
+ before(:all) do
48
+ @start_result = PLSQL::Coverage.start
49
+ end
50
+
51
+ it "should start coverage collection" do
52
+ @start_result.should be_true
53
+ end
54
+
55
+ it "should create profiler tables" do
56
+ %w(plsql_profiler_data plsql_profiler_units plsql_profiler_runs).each do |table_name|
57
+ plsql.send(table_name).should be_a(PLSQL::Table)
58
+ end
59
+ end
60
+
61
+ it "should start collecting profiler data" do
62
+ plsql.plsql_profiler_runs.all.should_not be_empty
63
+ end
64
+
65
+ end
66
+
67
+ describe "stop" do
68
+ before(:all) do
69
+ PLSQL::Coverage.start
70
+ plsql.test_profiler
71
+ @stop_result = PLSQL::Coverage.stop
72
+ end
73
+
74
+ it "should stop coverage collection" do
75
+ @stop_result.should be_true
76
+ end
77
+
78
+ it "should populate profiler data table" do
79
+ plsql.plsql_profiler_data.all.should_not be_empty
80
+ end
81
+
82
+ end
83
+
84
+ describe "cleanup" do
85
+ before(:each) do
86
+ PLSQL::Coverage.start
87
+ plsql.test_profiler
88
+ PLSQL::Coverage.stop
89
+ end
90
+
91
+ it "should drop profiler tables" do
92
+ PLSQL::Coverage.cleanup.should be_true
93
+ %w(plsql_profiler_data plsql_profiler_units plsql_profiler_runs).each do |table_name|
94
+ PLSQL::Table.find(plsql, table_name.to_sym).should be_nil
95
+ end
96
+ end
97
+
98
+ it "should delete profiler table data when profiler tables already were present" do
99
+ # simulate that profiler tables were already present
100
+ PLSQL::Coverage.reset_cache
101
+ lambda {
102
+ PLSQL::Coverage.start
103
+ plsql.test_profiler
104
+ PLSQL::Coverage.stop
105
+ PLSQL::Coverage.cleanup
106
+ }.should_not change {
107
+ [plsql.plsql_profiler_data.all, plsql.plsql_profiler_units.all, plsql.plsql_profiler_runs.all]
108
+ }
109
+ end
110
+ end
111
+
112
+ describe "get coverage data" do
113
+ before(:all) do
114
+ PLSQL::Coverage.start
115
+ plsql.test_profiler
116
+ PLSQL::Coverage.stop
117
+ end
118
+
119
+ it "should get profiler run results" do
120
+ PLSQL::Coverage.find.coverage_data.should == @coverage_data
121
+ end
122
+
123
+ it "should not get ignored schemas" do
124
+ PLSQL::Coverage.find.coverage_data(:ignore_schemas => [DATABASE_USER]).should be_empty
125
+ end
126
+
127
+ it "should get only objects with like condition" do
128
+ PLSQL::Coverage.find.coverage_data(:like => "#{DATABASE_USER}.test%").should == @coverage_data
129
+ end
130
+
131
+ it "should not get objects not matching like condition" do
132
+ PLSQL::Coverage.find.coverage_data(:like => "#{DATABASE_USER}.none%").should be_empty
133
+ end
134
+
135
+ end
136
+
137
+ describe "generate" do
138
+ def adjust_test_coverage
139
+ @test_coverage = @coverage_data[DATABASE_USER.upcase]['TEST_PROFILER'].dup
140
+ @test_coverage.delete(1) if @test_coverage[1] && @source.split("\n")[0] =~ /^CREATE OR REPLACE (.*)$/
141
+ end
142
+
143
+ def expected_coverages
144
+ total_lines = @source.split("\n").size
145
+ uncovered_lines = @test_coverage.count{|k,v| v==0}
146
+ executed_lines = @test_coverage.count{|k,v| v>0}
147
+ total_coverage_pct = '%.2f' % ((total_lines - uncovered_lines).to_f / total_lines * 100) + '%'
148
+ code_coverage_pct = '%.2f' % (executed_lines.to_f / (executed_lines + uncovered_lines) * 100) + '%'
149
+ [total_coverage_pct, code_coverage_pct]
150
+ end
151
+
152
+ before(:all) do
153
+ PLSQL::Coverage.start
154
+ plsql.test_profiler
155
+ PLSQL::Coverage.stop
156
+ PLSQL::Coverage.report(:directory => @directory)
157
+
158
+ adjust_test_coverage
159
+ end
160
+
161
+ describe "details report" do
162
+ before(:all) do
163
+ @details_doc = Nokogiri::HTML(File.read(File.join(@directory, "#{DATABASE_USER.upcase}-TEST_PROFILER.html")))
164
+ end
165
+
166
+ it "should generate HTML table with source lines" do
167
+ @source.split("\n").each_with_index do |line, i|
168
+ if i == 0 && line =~ /^CREATE OR REPLACE (.*)$/
169
+ line = $1
170
+ end
171
+ line.chomp!
172
+
173
+ # line should be present
174
+ a = @details_doc.at_css("table.details a[name=\"line#{i+1}\"]")
175
+ a.should_not be_nil
176
+
177
+ # source text should be present
178
+ a.parent.children[1].text.should == line
179
+
180
+ # table row should have correct class according to coverage data
181
+ tr = a.ancestors('tr')[0]
182
+ tr.attr('class').should == case @test_coverage[i+1]
183
+ when nil
184
+ 'inferred'
185
+ when 0
186
+ 'uncovered'
187
+ else
188
+ 'marked'
189
+ end
190
+ end
191
+ end
192
+
193
+ it "should generate HTML table with coverage percentage" do
194
+ @details_doc.css("table.report div.percent_graph_legend").map{|div| div.text}.should == expected_coverages
195
+ end
196
+
197
+ end
198
+
199
+ describe "index repot" do
200
+ before(:all) do
201
+ @index_doc = Nokogiri::HTML(File.read(File.join(@directory, "index.html")))
202
+ end
203
+
204
+ it "should generate HTML table with coverage percentage" do
205
+ @index_doc.css("table.report tbody div.percent_graph_legend").map{|div| div.text}.should == expected_coverages
206
+ @index_doc.css("table.report tfoot div.percent_graph_legend").map{|div| div.text}.should == expected_coverages
207
+ end
208
+
209
+ end
210
+
211
+ end
212
+
213
+ describe "using other connection" do
214
+ before(:all) do
215
+ plsql.logoff
216
+ plsql(:other).connect! CONNECTION_PARAMS
217
+
218
+ PLSQL::Coverage.start(:other)
219
+ plsql(:other).test_profiler
220
+ PLSQL::Coverage.stop(:other)
221
+ end
222
+
223
+ after(:all) do
224
+ plsql(:other).execute "DROP FUNCTION test_profiler" rescue nil
225
+ PLSQL::Coverage.cleanup(:other)
226
+ end
227
+
228
+ it "should start collecting profiler data" do
229
+ plsql(:other).plsql_profiler_runs.all.should_not be_empty
230
+ end
231
+
232
+ it "should populate profiler data table" do
233
+ plsql(:other).plsql_profiler_data.all.should_not be_empty
234
+ end
235
+
236
+ it "should get profiler run results" do
237
+ PLSQL::Coverage.find(:other).coverage_data.should == @coverage_data
238
+ end
239
+
240
+ it "should generate reports" do
241
+ PLSQL::Coverage.report :other, :directory => File.join(@directory, 'other')
242
+ File.file?(File.join(@directory, 'other/index.html')).should be_true
243
+ end
244
+ end
245
+
246
+ end
@@ -0,0 +1,264 @@
1
+ require 'spec_helper'
2
+
3
+ describe "plsql-spec" do
4
+
5
+ before(:all) do
6
+ @root_dir = destination_root
7
+ FileUtils.rm_rf(@root_dir)
8
+ FileUtils.mkdir_p(@root_dir)
9
+ end
10
+
11
+ def run_cli(*args)
12
+ Dir.chdir(@root_dir) do
13
+ @stdout = capture(:stdout) do
14
+ begin
15
+ PLSQL::Spec::CLI.start(args)
16
+ rescue SystemExit => e
17
+ @exit_status = e.status
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ def create_database_yml
24
+ content = "default:\n" <<
25
+ " username: #{DATABASE_USER}\n" <<
26
+ " password: #{DATABASE_PASSWORD}\n" <<
27
+ " database: #{DATABASE_NAME}\n"
28
+ content << " host: #{DATABASE_HOST}\n" if defined?(DATABASE_HOST)
29
+ content << " port: #{DATABASE_PORT}\n" if defined?(DATABASE_PORT)
30
+ File.open(File.join(@root_dir, 'spec/database.yml'), 'w') do |file|
31
+ file.write(content)
32
+ end
33
+ end
34
+
35
+ def inject_local_load_path
36
+ spec_helper_file = File.join(@root_dir, 'spec/spec_helper.rb')
37
+ content = File.read(spec_helper_file)
38
+ content.gsub! 'require "ruby-plsql-spec"',
39
+ "$:.unshift(File.expand_path('../../../../lib', __FILE__))\nrequire \"ruby-plsql-spec\""
40
+ File.open(spec_helper_file, 'w') do |file|
41
+ file.write(content)
42
+ end
43
+ end
44
+
45
+ def create_test(name, string)
46
+ file_content = <<-EOS
47
+ require 'spec_helper'
48
+
49
+ describe "test" do
50
+ it #{name.inspect} do
51
+ #{string}
52
+ end
53
+ end
54
+ EOS
55
+ Dir.chdir(@root_dir) do
56
+ File.open('spec/test_spec.rb', 'w') do |file|
57
+ file << file_content
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "init" do
63
+ before(:all) do
64
+ run_cli('init')
65
+ end
66
+
67
+ it "should create spec subdirectory" do
68
+ File.directory?(@root_dir + '/spec').should be_true
69
+ end
70
+
71
+ it "should create spec_helper.rb" do
72
+ File.file?(@root_dir + '/spec/spec_helper.rb').should be_true
73
+ end
74
+
75
+ it "should create database.yml" do
76
+ File.file?(@root_dir + '/spec/database.yml').should be_true
77
+ end
78
+
79
+ it "should create helpers/inspect_helpers.rb" do
80
+ File.file?(@root_dir + '/spec/helpers/inspect_helpers.rb').should be_true
81
+ end
82
+
83
+ it "should create factories subdirectory" do
84
+ File.directory?(@root_dir + '/spec/factories').should be_true
85
+ end
86
+
87
+ end
88
+
89
+ describe "run" do
90
+ before(:all) do
91
+ run_cli('init')
92
+ create_database_yml
93
+ inject_local_load_path
94
+ end
95
+
96
+ describe "successful tests" do
97
+ before(:all) do
98
+ create_test 'SYSDATE should not be NULL',
99
+ 'plsql.sysdate.should_not == NULL'
100
+ run_cli('run')
101
+ end
102
+
103
+ it "should report zero failures" do
104
+ @stdout.should =~ / 0 failures/
105
+ end
106
+
107
+ it "should not return failing exit status" do
108
+ @exit_status.should be_nil
109
+ end
110
+ end
111
+
112
+ describe "failing tests" do
113
+ before(:all) do
114
+ create_test 'SYSDATE should be NULL',
115
+ 'plsql.sysdate.should == NULL'
116
+ run_cli('run')
117
+ end
118
+
119
+ it "should report failures" do
120
+ @stdout.should =~ / 1 failure/
121
+ end
122
+
123
+ it "should return failing exit status" do
124
+ @exit_status.should == 1
125
+ end
126
+ end
127
+
128
+ describe "specified files" do
129
+ before(:all) do
130
+ create_test 'SYSDATE should not be NULL',
131
+ 'plsql.sysdate.should_not == NULL'
132
+ end
133
+
134
+ it "should report one file examples" do
135
+ run_cli('run', 'spec/test_spec.rb')
136
+ @stdout.should =~ /1 example/
137
+ end
138
+
139
+ it "should report two files examples" do
140
+ run_cli('run', 'spec/test_spec.rb', 'spec/test_spec.rb')
141
+ @stdout.should =~ /2 examples/
142
+ end
143
+ end
144
+
145
+ describe "with coverage" do
146
+ before(:all) do
147
+ plsql.connect! CONNECTION_PARAMS
148
+ plsql.execute <<-SQL
149
+ CREATE OR REPLACE FUNCTION test_profiler RETURN VARCHAR2 IS
150
+ BEGIN
151
+ RETURN 'test_profiler';
152
+ EXCEPTION
153
+ WHEN OTHERS THEN
154
+ RETURN 'others';
155
+ END;
156
+ SQL
157
+ create_test 'shoud test coverage',
158
+ 'plsql.test_profiler.should == "test_profiler"'
159
+ @index_file = File.join(@root_dir, 'coverage/index.html')
160
+ @details_file = File.join(@root_dir, "coverage/#{DATABASE_USER.upcase}-TEST_PROFILER.html")
161
+ end
162
+
163
+ after(:all) do
164
+ plsql.execute "DROP FUNCTION test_profiler" rescue nil
165
+ end
166
+
167
+ before(:each) do
168
+ FileUtils.rm_rf File.join(@root_dir, 'coverage')
169
+ end
170
+
171
+ after(:each) do
172
+ %w(PLSQL_COVERAGE PLSQL_COVERAGE_IGNORE_SCHEMAS PLSQL_COVERAGE_LIKE).each do |variable|
173
+ ENV.delete variable
174
+ end
175
+ end
176
+
177
+ it "should report zero failures" do
178
+ run_cli('run', '--coverage')
179
+ @stdout.should =~ / 0 failures/
180
+ end
181
+
182
+ it "should generate coverage reports" do
183
+ run_cli('run', '--coverage')
184
+ File.file?(@index_file).should be_true
185
+ File.file?(@details_file).should be_true
186
+ end
187
+
188
+ it "should generate coverage reports in specified directory" do
189
+ run_cli('run', '--coverage', 'plsql_coverage')
190
+ File.file?(@index_file.gsub('coverage', 'plsql_coverage')).should be_true
191
+ File.file?(@details_file.gsub('coverage', 'plsql_coverage')).should be_true
192
+ end
193
+
194
+ it "should not generate coverage report for ignored schema" do
195
+ run_cli('run', '--coverage', '--ignore_schemas', DATABASE_USER)
196
+ File.file?(@details_file).should be_false
197
+ end
198
+
199
+ it "should generate coverage report for objects matching like condition" do
200
+ run_cli('run', '--coverage', '--like', "#{DATABASE_USER}.%")
201
+ File.file?(@details_file).should be_true
202
+ end
203
+
204
+ it "should not generate coverage report for objects not matching like condition" do
205
+ run_cli('run', '--coverage', '--like', "#{DATABASE_USER}.aaa%")
206
+ File.file?(@details_file).should be_false
207
+ end
208
+
209
+ end
210
+
211
+ describe "with dbms_output" do
212
+ before(:all) do
213
+ plsql.connect! CONNECTION_PARAMS
214
+ plsql.execute <<-SQL
215
+ CREATE OR REPLACE PROCEDURE test_dbms_output IS
216
+ BEGIN
217
+ DBMS_OUTPUT.PUT_LINE('test_dbms_output');
218
+ END;
219
+ SQL
220
+ create_test 'shoud test dbms_output',
221
+ 'plsql.test_dbms_output.should be_nil'
222
+ end
223
+
224
+ after(:all) do
225
+ plsql.execute "DROP PROCEDURE test_dbms_output" rescue nil
226
+ end
227
+
228
+ after(:each) do
229
+ ENV.delete 'PLSQL_DBMS_OUTPUT'
230
+ end
231
+
232
+ it "should show DBMS_OUTPUT in standard output" do
233
+ run_cli('run', '--dbms_output')
234
+ @stdout.should =~ /DBMS_OUTPUT: test_dbms_output/
235
+ end
236
+
237
+ it "should not show DBMS_OUTPUT without specifying option" do
238
+ run_cli('run')
239
+ @stdout.should_not =~ /DBMS_OUTPUT: test_dbms_output/
240
+ end
241
+
242
+ end
243
+
244
+ end
245
+
246
+ describe "version" do
247
+ before(:all) do
248
+ run_cli('-v')
249
+ end
250
+
251
+ it "should show ruby-plsql-spec version" do
252
+ @stdout.should =~ /ruby-plsql-spec\s+#{PLSQL::Spec::VERSION.gsub('.','\.')}/
253
+ end
254
+
255
+ it "should show ruby-plsql version" do
256
+ @stdout.should =~ /ruby-plsql\s+#{PLSQL::VERSION.gsub('.','\.')}/
257
+ end
258
+
259
+ it "should show rspec version" do
260
+ @stdout.should =~ /rspec\s+#{::Spec::VERSION::STRING.gsub('.','\.')}/
261
+ end
262
+
263
+ end
264
+ end