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,13 @@
1
+ .bundle
2
+ .rvmrc
3
+ .svn
4
+ .DS_Store
5
+ /coverage
6
+ /examples/coverage
7
+ /doc
8
+ /pkg
9
+ /log
10
+ /tmp
11
+ sqlnet.log
12
+ Gemfile.lock
13
+ /spec/sandbox
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'jeweler'
4
+ gem 'rspec', '~> 1.3.0'
5
+ gem 'thor', '~> 0.14.2'
6
+ gem 'ruby-plsql', '~> 0.4.3'
7
+ gem 'nokogiri', '>= 1.4.3'
8
+
9
+ platforms :ruby do
10
+ gem 'ruby-oci8', '~> 2.0.4'
11
+ end
@@ -0,0 +1,5 @@
1
+ == 0.1.0 2010-10-01
2
+
3
+ * Initial release
4
+ * Created command line utility plsql-spec for initialization and tests run
5
+ * Created PL/SQL code coverage reporting
@@ -0,0 +1,55 @@
1
+ Installing on Windows
2
+ =====================
3
+
4
+ Ruby installation on Windows is a little bit different than installation on Mac OS X or Linux therefore here is description of steps for preparing Windows computer for ruby-plsql-spec.
5
+
6
+ Install Ruby
7
+ ------------
8
+
9
+ Download and install Ruby 1.8.7 from [Ruby Installer for Windows](http://www.rubyinstaller.org/).
10
+ (If you prefer you can try to install also Ruby 1.9.2 but it might be more difficult to install ruby-oci8 on this latest Ruby version on Windows).
11
+
12
+ When installing then select checkbox to add Ruby to your PATH.
13
+
14
+ Verify from command line that you have Ruby installed:
15
+
16
+ ruby -v
17
+
18
+ Install Oracle client
19
+ ---------------------
20
+
21
+ You should have Oracle client installed on your computer and its dll directory should be in PATH.
22
+
23
+ If you do not have Oracle client installed then the easiest way is to install [Oracle Instant Client](http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html) - install Basic and SQL*Plus packages. After installation include Oracle Instant Client directory in PATH.
24
+
25
+ If needed you can create tnsnames.ora file and enter TNS connections there so that later TNS aliases can be used for connection. Set TNS_ADMIN environment variable to point to directory where tnsnames.ora file is located.
26
+
27
+ Verify installation and try to connect to database using sqlplus.
28
+
29
+ Install ruby-oci8
30
+ -----------------
31
+
32
+ [ruby-oci8](http://ruby-oci8.rubyforge.org/en/) Ruby library is providing access to Oracle database from Ruby using OCI interface (provided by Oracle client). Install it with
33
+
34
+ gem install ruby-oci8
35
+
36
+ If you are behind firewall with proxy server then specify proxy server use -p option, e.g.:
37
+
38
+ gem install ruby-oci8 -p http://proxy.example.com:8080
39
+
40
+ Install ruby-plsql-spec
41
+ -----------------------
42
+
43
+ Install ruby-plsql-spec with
44
+
45
+ gem install ruby-plsql-spec
46
+
47
+ Validate installation
48
+ ---------------------
49
+
50
+ From command line run `irb` and try to connect to some Oracle database (use appropriate username/password/database instead of "hr","hr","orcl"):
51
+
52
+ require "rubygems"
53
+ require "ruby-plsql"
54
+ plsql.connect! "hr","hr","orcl"
55
+ plsql.dual.all
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009-2010 Raimonds Simanovskis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,91 @@
1
+ ruby-plsql-spec
2
+ ===============
3
+ PL/SQL unit testing with Ruby
4
+ -----------------------------
5
+
6
+ Unit testing of PL/SQL procedures with Ruby libraries:
7
+
8
+ * [ruby-plsql](http://github.com/rsim/ruby-plsql) - Ruby API for calling PL/SQL procedures
9
+ * [RSpec](http://rspec.info) - Ruby testing (or behavior driven development) framework
10
+
11
+ Examples
12
+ --------
13
+
14
+ PL/SQL procedure examples are in `examples/source` subdirectory, test examples are in `examples/spec` subdirectory.
15
+
16
+ * `BETWNSTR` - example from [utPLSQL project](http://utplsql.sourceforge.net/)
17
+ * `AWARD_BONUS` - example from [SQL Developer 2.1 tutorial](http://www.oracle.com/technology/obe/11gr2_db_prod/appdev/sqldev/sqldev_unit_test/sqldev_unit_test.htm)
18
+ * `REMOVE_ROOMS_BY_NAME` - example from [Quest Code Tester for Oracle tutorial](http://www.quest.com/code-tester-for-oracle/product-demo/chap02.htm)
19
+
20
+ Installing
21
+ ----------
22
+
23
+ See [Installing on Windows](INSTALL-Windows.markdown) in separate file.
24
+
25
+ * Install [Ruby 1.8.7 or Ruby 1.9.2](http://www.ruby-lang.org/en/downloads/)
26
+ * Install Oracle client, e.g. [Oracle Instant Client](http://www.oracle.com/technology/tech/oci/instantclient/index.html)
27
+ * Install ruby-oci8 and ruby-plsql-spec (prefix with sudo if necessary)
28
+
29
+ gem install ruby-oci8
30
+ gem install ruby-plsql-spec
31
+
32
+ Another alternative is to use [JRuby](http://jruby.org) if for example it is necessary also to test Java classes / methods using Ruby.
33
+
34
+ * Install [JRuby](http://jruby.org/download)
35
+ * Copy Oracle JDBC driver (e.g. ojdbc14.jar) to JRUBY_HOME/lib directory
36
+ * Install ruby-plsql-spec (prefix with sudo if necessary)
37
+
38
+ jruby -S gem install ruby-plsql-spec
39
+
40
+ Initializing project directory
41
+ ------------------------------
42
+
43
+ In your project directory execute
44
+
45
+ plsql-spec init
46
+
47
+ which will create `spec` directory where test files will be located.
48
+
49
+ Modify `spec/database.yml` file and specify database connection which should be used when running tests. In `database:` parameter specify either TNS connection name or use "servername/databasename" or "servername:port/databasename" to specify host, port and database name.
50
+
51
+ Start creating tests in files with `_spec.rb` at the end of file name. If there will be not so many files then you can place them directly in `spec` directory. If there will be many tests files then create separate directories per module / functionality group and place tests files in subdirectories. You can also create `factories` and `helpers` subdirectories per each module / functionality group.
52
+
53
+ Executing tests
54
+ ---------------
55
+
56
+ All tests can be run from command line using
57
+
58
+ plsql-spec run
59
+
60
+ or if you want to run tests just from one file then use, e.g.
61
+
62
+ plsql-spec run spec/example_spec.rb
63
+
64
+ You can get additional help about `plsql-spec` command line utility with
65
+
66
+ plsql-spec help
67
+
68
+ Code coverage reporting
69
+ -----------------------
70
+
71
+ If you would like to see PL/SQL code coverage report (which lines of code were executed during tests run) then run tests with --coverage option:
72
+
73
+ plsql-spec run --coverage
74
+
75
+ Coverage reports will be created as HTML files in coverage/ directory. Open with your browser coverage/index.html file.
76
+
77
+ Code coverage is gathered using DBMS_PROFILER package. Please take into account that only those packages will be analyzed to which current database session user has CREATE privilege.
78
+
79
+ How to start?
80
+ -------------
81
+
82
+ Read blog post about [Oracle PL/SQL unit testing with Ruby](http://blog.rayapps.com/2009/11/27/oracle-plsql-unit-testing-with-ruby).
83
+
84
+ If you are not familiar with Ruby I recommend to start with [Ruby in Twenty Minutes](http://www.ruby-lang.org/en/documentation/quickstart/) tutorial. Then you can take a look on some [RSpec examples](http://rspec.info/documentation/) how to write and structure tests. And then you can take a look at [ruby-plsql own tests](http://github.com/rsim/ruby-plsql/blob/master/spec/plsql/procedure_spec.rb) to see how to pass parameters and verify results for different PL/SQL data types.
85
+
86
+ How to customize ruby-plsql-spec for my project?
87
+ --------------------------------------------
88
+
89
+ * Review spec/spec_helper.rb file and modify if needed directories where you will store additional required files (helper files, factory files, source files).
90
+ * Review and or create new helper files in `spec\helpers` directory.
91
+ * Create new factory methods for test data creation in `factories` directory (see example in `examples/spec/factories`).
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "ruby-plsql-spec"
8
+ gem.summary = "Oracle PL/SQL unit testing framework using Ruby and RSpec"
9
+ gem.description = <<-EOS
10
+ ruby-plsql-spec is Oracle PL/SQL unit testing framework which is built using Ruby programming language, ruby-plsql library and RSpec testing framework.
11
+ EOS
12
+ gem.email = "raimonds.simanovskis@gmail.com"
13
+ gem.homepage = "http://github.com/rsim/ruby-plsql-spec"
14
+ gem.authors = ["Raimonds Simanovskis"]
15
+ gem.add_dependency "ruby-plsql", ">= 0.4.3"
16
+ gem.add_dependency "thor", ">= 0.14.2"
17
+ gem.add_dependency "rspec", "~> 1.3.0"
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'spec/rake/spectask'
25
+ Spec::Rake::SpecTask.new(:spec) do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.spec_files = FileList['spec/plsql/**/*_spec.rb']
28
+ end
29
+
30
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
31
+ spec.libs << 'lib' << 'spec'
32
+ spec.pattern = 'spec/plsql/**/*_spec.rb'
33
+ spec.rcov = true
34
+ spec.rcov_opts = ['--exclude', '/Library,spec/']
35
+ end
36
+
37
+ task :spec => :check_dependencies
38
+
39
+ task :default => :spec
40
+
41
+ require 'rake/rdoctask'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'doc'
46
+ rdoc.title = "ruby-plsql-spec #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ruby-plsql-spec'
4
+
5
+ PLSQL::Spec::CLI.start
@@ -0,0 +1,29 @@
1
+ # example from SQL Developer 2.1 tutorial
2
+ # http://www.oracle.com/technology/obe/11gr2_db_prod/appdev/sqldev/sqldev_unit_test/sqldev_unit_test.htm
3
+
4
+ # Uncomment to create table employees2 which is used by award_bonus procedure
5
+ # plsql.execute "DROP TABLE employees2" rescue nil
6
+ # plsql.execute "CREATE TABLE employees2 AS SELECT * FROM employees WHERE ROWNUM < 0"
7
+ # plsql.execute "DROP SEQUENCE employees2_seq" rescue nil
8
+ # plsql.execute "CREATE SEQUENCE employees2_seq"
9
+
10
+ plsql.execute <<-SQL
11
+ CREATE OR REPLACE
12
+ PROCEDURE award_bonus (
13
+ emp_id NUMBER, sales_amt NUMBER) AS
14
+ commission REAL;
15
+ comm_missing EXCEPTION;
16
+ BEGIN
17
+ SELECT commission_pct INTO commission
18
+ FROM employees2
19
+ WHERE employee_id = emp_id;
20
+
21
+ IF commission IS NULL THEN
22
+ RAISE comm_missing;
23
+ ELSE
24
+ UPDATE employees2
25
+ SET salary = NVL(salary,0) + sales_amt*commission
26
+ WHERE employee_id = emp_id;
27
+ END IF;
28
+ END;
29
+ SQL
@@ -0,0 +1,19 @@
1
+ # example from utPLSQL project (http://utplsql.sourceforge.net/)
2
+ plsql.execute <<-SQL
3
+ CREATE OR REPLACE FUNCTION betwnstr (
4
+ string_in IN VARCHAR2,
5
+ start_in IN INTEGER,
6
+ end_in IN INTEGER
7
+ )
8
+ RETURN VARCHAR2
9
+ IS
10
+ l_start PLS_INTEGER := start_in;
11
+ BEGIN
12
+ IF l_start = 0
13
+ THEN
14
+ l_start := 1;
15
+ END IF;
16
+
17
+ RETURN (SUBSTR (string_in, l_start, end_in - l_start + 1));
18
+ END;
19
+ SQL
@@ -0,0 +1,45 @@
1
+ # example from Code Tester for Oracle tutorial
2
+ # http://www.quest.com/code-tester-for-oracle/product-demo/chap02.htm
3
+
4
+ # Setup test tables
5
+ plsql.execute "DROP TABLE room_contents" rescue nil
6
+ plsql.execute "DROP TABLE rooms" rescue nil
7
+
8
+ plsql.execute <<-SQL
9
+ CREATE TABLE rooms (
10
+ room_key NUMBER PRIMARY KEY,
11
+ name VARCHAR2(100)
12
+ )
13
+ SQL
14
+ plsql.execute <<-SQL
15
+ CREATE TABLE room_contents (
16
+ contents_key NUMBER PRIMARY KEY,
17
+ room_key NUMBER,
18
+ name VARCHAR2(100)
19
+ )
20
+ SQL
21
+
22
+ # Foreign key to rooms. Note: this is not a CASCADE DELETE
23
+ # key. Child data is NOT removed when the parent is
24
+ # removed.
25
+
26
+ plsql.execute <<-SQL
27
+ ALTER TABLE room_contents ADD CONSTRAINT
28
+ fk_rooms FOREIGN KEY (room_key)
29
+ REFERENCES rooms (room_key)
30
+ SQL
31
+
32
+ plsql.execute <<-SQL
33
+ CREATE OR REPLACE PROCEDURE remove_rooms_by_name (
34
+ name_in IN rooms.name%TYPE)
35
+ IS
36
+ BEGIN
37
+ IF NAME_IN IS NULL
38
+ THEN
39
+ RAISE PROGRAM_ERROR;
40
+ END IF;
41
+
42
+ DELETE FROM rooms WHERE name LIKE name_in;
43
+
44
+ END;
45
+ SQL
@@ -0,0 +1,207 @@
1
+ plsql.execute <<-SQL
2
+ CREATE OR REPLACE PACKAGE what_is_profiled
3
+ IS
4
+ TYPE aa1 IS TABLE OF VARCHAR2 (100)
5
+ INDEX BY PLS_INTEGER;
6
+ TYPE aa2 IS TABLE OF VARCHAR2 (100)
7
+ INDEX BY PLS_INTEGER;
8
+ PROCEDURE proc1 (arg IN NUMBER, arg2 OUT VARCHAR2);
9
+ FUNCTION func1
10
+ RETURN VARCHAR2;
11
+
12
+ procedure driver ;
13
+ END what_is_profiled;
14
+ SQL
15
+
16
+ plsql.execute <<-SQL
17
+ CREATE OR REPLACE PACKAGE BODY what_is_profiled
18
+ IS
19
+ TYPE p_aa1 IS TABLE OF VARCHAR2 (100)
20
+ INDEX BY PLS_INTEGER;
21
+
22
+ TYPE p_aa2 IS TABLE OF VARCHAR2 (100)
23
+ INDEX BY PLS_INTEGER;
24
+
25
+ PROCEDURE loops (arg IN NUMBER, arg2 OUT VARCHAR2)
26
+ IS
27
+ val
28
+ INTEGER;
29
+ condition1 boolean := true;
30
+ condition2 boolean
31
+ :=
32
+ true;
33
+
34
+ BEGIN
35
+ FOR indx IN 1 .. 100
36
+ LOOP
37
+ NULL;
38
+ END LOOP;
39
+
40
+ FOR
41
+ indx
42
+ IN
43
+ 1
44
+ ..
45
+ 100
46
+ LOOP
47
+ val := 1;
48
+ END
49
+ LOOP;
50
+
51
+ FOR indx IN 1 .. 100 LOOP NULL; END LOOP;
52
+
53
+ FOR rec IN (SELECT *
54
+ FROM all_source
55
+ WHERE ROWNUM < 101)
56
+ LOOP
57
+ val := 1;
58
+ END LOOP;
59
+
60
+ FOR
61
+ rec
62
+ IN
63
+ (
64
+ SELECT *
65
+ FROM all_source
66
+ WHERE ROWNUM < 101
67
+ )
68
+ LOOP
69
+ val := 1;
70
+ END
71
+ LOOP;
72
+
73
+ WHILE (condition1 AND condition2)
74
+ LOOP
75
+ condition1 := FALSE;
76
+ END LOOP;
77
+
78
+ WHILE
79
+ (
80
+ condition1
81
+ AND
82
+ condition2
83
+ )
84
+ LOOP
85
+ condition1
86
+ :=
87
+ FALSE
88
+ ;
89
+ END LOOP;
90
+
91
+ DECLARE
92
+ indx INTEGER := 1;
93
+ BEGIN
94
+ LOOP
95
+ EXIT WHEN indx > 100;
96
+ indx := indx + 1;
97
+ END LOOP;
98
+ END;
99
+
100
+ DECLARE
101
+ indx INTEGER := 1;
102
+ BEGIN
103
+ LOOP
104
+ EXIT
105
+ WHEN
106
+ indx
107
+ >
108
+ 100;
109
+ indx := indx +
110
+ 1
111
+ ;
112
+ END LOOP;
113
+ END;
114
+ END;
115
+
116
+ PROCEDURE conditionals
117
+ IS
118
+ a
119
+ boolean;
120
+ b boolean;
121
+ c boolean
122
+ ;
123
+ BEGIN
124
+ IF (a AND b OR c)
125
+ THEN
126
+ NULL;
127
+ elsif
128
+ a
129
+ then
130
+ null;
131
+ else
132
+ dbms_output.put_line ('a');
133
+ END IF;
134
+
135
+ a := case
136
+ true
137
+ when true
138
+ then
139
+ false
140
+ when
141
+ false then
142
+ true
143
+ else
144
+ false
145
+ end
146
+ ;
147
+ a := case true
148
+ when true
149
+ then
150
+ false
151
+ when
152
+ false then
153
+ true
154
+ else
155
+ false
156
+ end
157
+ ;
158
+
159
+ case when
160
+ sysdate > sysdate + 1
161
+ then
162
+ a := false;
163
+ when 1 > 2 then
164
+ b := false;
165
+ when 1
166
+ > 2
167
+ then
168
+ c := false;
169
+ else null; end case;
170
+ END;
171
+
172
+ FUNCTION p_func1
173
+ RETURN VARCHAR2
174
+ IS
175
+ BEGIN
176
+ RETURN NULL;
177
+ END;
178
+
179
+ PROCEDURE proc1 (arg IN NUMBER, arg2 OUT VARCHAR2)
180
+ IS
181
+ BEGIN
182
+ NULL;
183
+ END;
184
+
185
+ FUNCTION func1
186
+ RETURN VARCHAR2
187
+ IS
188
+ BEGIN
189
+ RETURN p_func1;
190
+ END;
191
+
192
+ procedure driver is
193
+ l varchar2(100);
194
+ begin
195
+ loops(1, l);
196
+ conditionals;
197
+ proc1
198
+ (
199
+ 1
200
+ ,
201
+ l);
202
+ GOTO checkloop;
203
+ <<checkloop>>
204
+ dbms_output.put_line ('a');
205
+ end;
206
+ END what_is_profiled;
207
+ SQL