ruby-plsql-spec 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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