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,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