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,2 @@
1
+
2
+ (function($){$.extend({tablesorter:new function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:'.',debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}var rows=table.tBodies[0].rows;if(table.tBodies[0].rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i<l;i++){var p=false;if($.metadata&&($($headers[i]).metadata()&&$($headers[i]).metadata().sorter)){p=getParserById($($headers[i]).metadata().sorter);}else if((table.config.headers[i]&&table.config.headers[i].sorter)){p=getParserById(table.config.headers[i].sorter);}if(!p){p=detectParserForColumn(table,cells[i]);}if(table.config.debug){parsersDebug+="column:"+i+" parser:"+p.id+"\n";}list.push(p);}}if(table.config.debug){log(parsersDebug);}return list;};function detectParserForColumn(table,node){var l=parsers.length;for(var i=1;i<l;i++){if(parsers[i].is($.trim(getElementText(table.config,node)),table,node)){return parsers[i];}}return parsers[0];}function getParserById(name){var l=parsers.length;for(var i=0;i<l;i++){if(parsers[i].id.toLowerCase()==name.toLowerCase()){return parsers[i];}}return false;}function buildCache(table){if(table.config.debug){var cacheTime=new Date();}var totalRows=(table.tBodies[0]&&table.tBodies[0].rows.length)||0,totalCells=(table.tBodies[0].rows[0]&&table.tBodies[0].rows[0].cells.length)||0,parsers=table.config.parsers,cache={row:[],normalized:[]};for(var i=0;i<totalRows;++i){var c=table.tBodies[0].rows[i],cols=[];cache.row.push($(c));for(var j=0;j<totalCells;++j){cols.push(parsers[j].format(getElementText(table.config,c.cells[j]),table,c.cells[j]));}cols.push(i);cache.normalized.push(cols);cols=null;};if(table.config.debug){benchmark("Building cache for "+totalRows+" rows:",cacheTime);}return cache;};function getElementText(config,node){if(!node)return"";var t="";if(config.textExtraction=="simple"){if(node.childNodes[0]&&node.childNodes[0].hasChildNodes()){t=node.childNodes[0].innerHTML;}else{t=node.innerHTML;}}else{if(typeof(config.textExtraction)=="function"){t=config.textExtraction(node);}else{t=$(node).text();}}return t;}function appendToTable(table,cache){if(table.config.debug){var appendTime=new Date()}var c=cache,r=c.row,n=c.normalized,totalRows=n.length,checkCell=(n[0].length-1),tableBody=$(table.tBodies[0]),rows=[];for(var i=0;i<totalRows;i++){rows.push(r[n[i][checkCell]]);if(!table.config.appender){var o=r[n[i][checkCell]];var l=o.length;for(var j=0;j<l;j++){tableBody[0].appendChild(o[j]);}}}if(table.config.appender){table.config.appender(table,rows);}rows=null;if(table.config.debug){benchmark("Rebuilt table:",appendTime);}applyWidget(table);setTimeout(function(){$(table).trigger("sortEnd");},0);};function buildHeaders(table){if(table.config.debug){var time=new Date();}var meta=($.metadata)?true:false,tableHeadersRows=[];for(var i=0;i<table.tHead.rows.length;i++){tableHeadersRows[i]=0;};$tableHeaders=$("thead th",table);$tableHeaders.each(function(index){this.count=0;this.column=index;this.order=formatSortingOrder(table.config.sortInitialOrder);if(checkHeaderMetadata(this)||checkHeaderOptions(table,index))this.sortDisabled=true;if(!this.sortDisabled){$(this).addClass(table.config.cssHeader);}table.config.headerList[index]=this;});if(table.config.debug){benchmark("Built headers:",time);log($tableHeaders);}return $tableHeaders;};function checkCellColSpan(table,rows,row){var arr=[],r=table.tHead.rows,c=r[row].cells;for(var i=0;i<c.length;i++){var cell=c[i];if(cell.colSpan>1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i<l;i++){getWidgetById(c[i]).format(table);}}function getWidgetById(name){var l=widgets.length;for(var i=0;i<l;i++){if(widgets[i].id.toLowerCase()==name.toLowerCase()){return widgets[i];}}};function formatSortingOrder(v){if(typeof(v)!="Number"){i=(v.toLowerCase()=="desc")?1:0;}else{i=(v==(0||1))?v:0;}return i;}function isValueInArray(v,a){var l=a.length;for(var i=0;i<l;i++){if(a[i][0]==v){return true;}}return false;}function setHeadersCss(table,$headers,list,css){$headers.removeClass(css[0]).removeClass(css[1]);var h=[];$headers.each(function(offset){if(!this.sortDisabled){h[this.column]=$(this);}});var l=list.length;for(var i=0;i<l;i++){h[list[i][0]].addClass(css[list[i][1]]);}}function fixColumnWidth(table,$headers){var c=table.config;if(c.widthFixed){var colgroup=$('<colgroup>');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('<col>').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;i<l;i++){var s=sortList[i],o=c.headerList[s[0]];o.count=s[1];o.count++;}}function multisort(table,sortList,cache){if(table.config.debug){var sortTime=new Date();}var dynamicExp="var sortWrapper = function(a,b) {",l=sortList.length;for(var i=0;i<l;i++){var c=sortList[i][0];var order=sortList[i][1];var s=(getCachedSortType(table.config.parsers,c)=="text")?((order==0)?"sortText":"sortTextDesc"):((order==0)?"sortNumeric":"sortNumericDesc");var e="e"+i;dynamicExp+="var "+e+" = "+s+"(a["+c+"],b["+c+"]); ";dynamicExp+="if("+e+") { return "+e+"; } ";dynamicExp+="else { ";}var orgOrderCol=cache.normalized[0].length-1;dynamicExp+="return a["+orgOrderCol+"]-b["+orgOrderCol+"];";for(var i=0;i<l;i++){dynamicExp+="}; ";}dynamicExp+="return 0; ";dynamicExp+="}; ";eval(dynamicExp);cache.normalized.sort(sortWrapper);if(table.config.debug){benchmark("Sorting on "+sortList.toString()+" and dir "+order+" time:",sortTime);}return cache;};function sortText(a,b){return((a<b)?-1:((a>b)?1:0));};function sortTextDesc(a,b){return((b<a)?-1:((b>a)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){$this.trigger("sortStart");var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){var $cell=$(this);var i=this.column;this.order=this.count++%2;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j<a.length;j++){if(a[j][0]!=i){config.sortList.push(a[j]);}}}config.sortList.push([i,this.order]);}else{if(isValueInArray(i,config.sortList)){for(var j=0;j<config.sortList.length;j++){var s=config.sortList[j],o=config.headerList[s[0]];if(s[0]==i){o.count=s[1];o.count++;s[1]=o.count%2;}}}else{config.sortList.push([i,this.order]);}};setTimeout(function(){setHeadersCss($this[0],$headers,config.sortList,sortCSS);appendToTable($this[0],multisort($this[0],config.sortList,cache));},1);return false;}}).mousedown(function(){if(config.cancelSelection){this.onselectstart=function(){return false};return false;}});$this.bind("update",function(){this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);}).bind("sorton",function(e,list){$(this).trigger("sortStart");config.sortList=list;var sortList=config.sortList;updateHeaderSortCount(this,sortList);setHeadersCss(this,$headers,sortList,sortCSS);appendToTable(this,multisort(this,sortList,cache));}).bind("appendCache",function(){appendToTable(this,cache);}).bind("applyWidgetId",function(e,id){getWidgetById(id).format(this);}).bind("applyWidgets",function(){applyWidget(this);});if($.metadata&&($(this).metadata()&&$(this).metadata().sortlist)){config.sortList=$(this).metadata().sortlist;}if(config.sortList.length>0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i<l;i++){if(parsers[i].id.toLowerCase()==parser.id.toLowerCase()){a=false;}}if(a){parsers.push(parser);};};this.addWidget=function(widget){widgets.push(widget);};this.formatFloat=function(s){var i=parseFloat(s);return(isNaN(i))?0:i;};this.formatInt=function(s){var i=parseInt(s);return(isNaN(i))?0:i;};this.isDigit=function(s,config){var DECIMAL='\\'+config.decimal;var exp='/(^[+]?0('+DECIMAL+'0+)?$)|(^([-+]?[1-9][0-9]*)$)|(^([-+]?((0?|[1-9][0-9]*)'+DECIMAL+'(0*[1-9][0-9]*)))$)|(^[-+]?[1-9]+[0-9]*'+DECIMAL+'0+$)/';return RegExp(exp).test($.trim(s));};this.clearTableBody=function(table){if($.browser.msie){function empty(){while(this.firstChild)this.removeChild(this.firstChild);}empty.apply(table.tBodies[0]);}else{table.tBodies[0].innerHTML="";}};}});$.fn.extend({tablesorter:$.tablesorter.construct});var ts=$.tablesorter;ts.addParser({id:"text",is:function(s){return true;},format:function(s){return $.trim(s.toLowerCase());},type:"text"});ts.addParser({id:"digit",is:function(s,table){var c=table.config;return $.tablesorter.isDigit(s,c);},format:function(s){return $.tablesorter.formatFloat(s);},type:"numeric"});ts.addParser({id:"currency",is:function(s){return/^[£$€?.]/.test(s);},format:function(s){return $.tablesorter.formatFloat(s.replace(new RegExp(/[^0-9.]/g),""));},type:"numeric"});ts.addParser({id:"ipAddress",is:function(s){return/^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s);},format:function(s){var a=s.split("."),r="",l=a.length;for(var i=0;i<l;i++){var item=a[i];if(item.length==2){r+="0"+item;}else{r+=item;}}return $.tablesorter.formatFloat(r);},type:"numeric"});ts.addParser({id:"url",is:function(s){return/^(https?|ftp|file):\/\/$/.test(s);},format:function(s){return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//),''));},type:"text"});ts.addParser({id:"isoDate",is:function(s){return/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s);},format:function(s){return $.tablesorter.formatFloat((s!="")?new Date(s.replace(new RegExp(/-/g),"/")).getTime():"0");},type:"numeric"});ts.addParser({id:"percent",is:function(s){return/\%$/.test($.trim(s));},format:function(s){return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g),""));},type:"numeric"});ts.addParser({id:"usLongDate",is:function(s){return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/));},format:function(s){return $.tablesorter.formatFloat(new Date(s).getTime());},type:"numeric"});ts.addParser({id:"shortDate",is:function(s){return/\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/.test(s);},format:function(s,table){var c=table.config;s=s.replace(/\-/g,"/");if(c.dateFormat=="us"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/,"$3/$1/$2");}else if(c.dateFormat=="uk"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/,"$3/$2/$1");}else if(c.dateFormat=="dd/mm/yy"||c.dateFormat=="dd-mm-yy"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/,"$1/$2/$3");}return $.tablesorter.formatFloat(new Date(s).getTime());},type:"numeric"});ts.addParser({id:"time",is:function(s){return/^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s);},format:function(s){return $.tablesorter.formatFloat(new Date("2000/01/01 "+s).getTime());},type:"numeric"});ts.addParser({id:"metadata",is:function(s){return false;},format:function(s,table,cell){var c=table.config,p=(!c.parserMetadataName)?'sortValue':c.parserMetadataName;return $(cell).metadata()[p];},type:"numeric"});ts.addWidget({id:"zebra",format:function(table){if(table.config.debug){var time=new Date();}$("tr:visible",table.tBodies[0]).filter(':even').removeClass(table.config.widgetZebra.css[1]).addClass(table.config.widgetZebra.css[0]).end().filter(':odd').removeClass(table.config.widgetZebra.css[0]).addClass(table.config.widgetZebra.css[1]);if(table.config.debug){$.tablesorter.benchmark("Applying Zebra widget",time);}}});})(jQuery);
@@ -0,0 +1,66 @@
1
+ drop table plsql_profiler_data cascade constraints;
2
+ drop table plsql_profiler_units cascade constraints;
3
+ drop table plsql_profiler_runs cascade constraints;
4
+
5
+ drop sequence plsql_profiler_runnumber;
6
+
7
+ create table plsql_profiler_runs
8
+ (
9
+ runid number primary key, -- unique run identifier,
10
+ -- from plsql_profiler_runnumber
11
+ related_run number, -- runid of related run (for client/
12
+ -- server correlation)
13
+ run_owner varchar2(32), -- user who started run
14
+ run_date date, -- start time of run
15
+ run_comment varchar2(2047), -- user provided comment for this run
16
+ run_total_time number, -- elapsed time for this run
17
+ run_system_info varchar2(2047), -- currently unused
18
+ run_comment1 varchar2(2047), -- additional comment
19
+ spare1 varchar2(256) -- unused
20
+ );
21
+
22
+ comment on table plsql_profiler_runs is
23
+ 'Run-specific information for the PL/SQL profiler';
24
+
25
+ create table plsql_profiler_units
26
+ (
27
+ runid number references plsql_profiler_runs,
28
+ unit_number number, -- internally generated library unit #
29
+ unit_type varchar2(32), -- library unit type
30
+ unit_owner varchar2(32), -- library unit owner name
31
+ unit_name varchar2(32), -- library unit name
32
+ -- timestamp on library unit, can be used to detect changes to
33
+ -- unit between runs
34
+ unit_timestamp date,
35
+ total_time number DEFAULT 0 NOT NULL,
36
+ spare1 number, -- unused
37
+ spare2 number, -- unused
38
+ --
39
+ primary key (runid, unit_number)
40
+ );
41
+
42
+ comment on table plsql_profiler_units is
43
+ 'Information about each library unit in a run';
44
+
45
+ create table plsql_profiler_data
46
+ (
47
+ runid number, -- unique (generated) run identifier
48
+ unit_number number, -- internally generated library unit #
49
+ line# number not null, -- line number in unit
50
+ total_occur number, -- number of times line was executed
51
+ total_time number, -- total time spent executing line
52
+ min_time number, -- minimum execution time for this line
53
+ max_time number, -- maximum execution time for this line
54
+ spare1 number, -- unused
55
+ spare2 number, -- unused
56
+ spare3 number, -- unused
57
+ spare4 number, -- unused
58
+ --
59
+ primary key (runid, unit_number, line#),
60
+ foreign key (runid, unit_number) references plsql_profiler_units
61
+ );
62
+
63
+ comment on table plsql_profiler_data is
64
+ 'Accumulated data from all profiler runs';
65
+
66
+ create sequence plsql_profiler_runnumber start with 1 nocache;
@@ -0,0 +1,43 @@
1
+ $(function() {
2
+ $("#report_table").tablesorter({
3
+ widgets: ['zebra'],
4
+ textExtraction: 'complex'
5
+ });
6
+
7
+ $('.filter').change(function(){
8
+ var ff = $('#file_filter').val(),
9
+ cf = $('#coverage_filter').val();
10
+ $('table#report_table tbody tr').each(function(i){
11
+ if ((this.className.split(" ").indexOf(ff) > -1) && (this.className.split(" ").indexOf(cf) > -1)) {
12
+ this.style.display = "";
13
+ } else {
14
+ this.style.display = "none";
15
+ };
16
+ restripe();
17
+ });
18
+ });
19
+
20
+ });
21
+
22
+ function restripe() {
23
+ i = 0;
24
+ $('table#report_table tbody tr').each(function(){
25
+ if (this.style.display != "none") {
26
+ i += 1;
27
+ classes = this.className.split(" ");
28
+ if ($.inArray("even",classes) != -1) {
29
+ classes.splice($.inArray("even",classes),1);
30
+ } else if ($.inArray("odd",classes) != -1) {
31
+ classes.splice($.inArray("odd",classes),1);
32
+ }
33
+ if (i % 2 === 0) {
34
+ this.className = classes.join(" ") + " odd";
35
+ } else {
36
+ this.className = classes.join(" ") + " even";
37
+ }
38
+ }
39
+ });
40
+ }
41
+
42
+ // Fix IE's lack of support for indexOf (!)
43
+ if (!Array.indexOf) { Array.prototype.indexOf = function(obj){ for(var i=0; i<this.length; i++){ if(this[i]==obj){return i;} } return -1; };}
@@ -0,0 +1,15 @@
1
+ <tr class="all_schemas all_coverage <%= schema %>_schema <%= ((code_coverage.to_i/10)..(code_coverage==100 ? 10 : 9)).map{|i| (i+1).to_s<<'0'}.join(' ') %>">
2
+ <td class="left_align"><a href="<%= file_name %>"><%= object_name %></a></td>
3
+ <td class='right_align'><tt><%= total_lines %></tt></td>
4
+ <td class='right_align'><tt><%= analyzed_lines %></tt></td>
5
+ <td class="left_align"><div class="percent_graph_legend"><tt class=''><%= '%.2f' % total_coverage %>%</tt></div>
6
+ <div class="percent_graph">
7
+ <div class="covered" style="width:<%= total_coverage.to_i %>px"></div>
8
+ <div class="uncovered" style="width:<%= 100 - total_coverage.to_i %>px"></div>
9
+ </div></td>
10
+ <td class="left_align"><div class="percent_graph_legend"><tt class=''><%= '%.2f' % code_coverage %>%</tt></div>
11
+ <div class="percent_graph">
12
+ <div class="covered" style="width:<%= code_coverage.to_i %>px"></div>
13
+ <div class="uncovered" style="width:<%= 100 - code_coverage.to_i %>px"></div>
14
+ </div></td>
15
+ </tr>
@@ -0,0 +1,5 @@
1
+ require 'spec'
2
+ require 'ruby-plsql'
3
+ require 'plsql/coverage'
4
+ require 'plsql/spec/cli'
5
+ require 'plsql/spec/version'
@@ -0,0 +1,81 @@
1
+ require 'thor'
2
+ require 'thor/actions'
3
+
4
+ module PLSQL
5
+ module Spec
6
+ class CLI < ::Thor
7
+ include Thor::Actions
8
+
9
+ def initialize(*)
10
+ super
11
+ self.source_paths << File.expand_path('../templates', __FILE__)
12
+ end
13
+
14
+ map 'run' => :run_tests, '-v' => :version
15
+
16
+ desc 'init', 'initialize spec subdirectory with default ruby-plsql-spec files'
17
+ def init
18
+ empty_directory 'spec'
19
+ %w(spec_helper.rb database.yml).each do |file|
20
+ copy_file file, "spec/#{file}"
21
+ end
22
+ directory 'helpers', 'spec/helpers'
23
+ empty_directory 'spec/factories'
24
+ say <<-EOS, :red
25
+
26
+ Please update spec/database.yml file and specify your database connection parameters.
27
+
28
+ Create tests in spec/ directory (or in subdirectories of it) in *_spec.rb files.
29
+
30
+ Run created tests with "plsql-spec run".
31
+ Run tests with "plsql-spec run --coverage" to generate code coverage report in coverage/ directory.
32
+ EOS
33
+ end
34
+
35
+ desc 'run [FILES]', 'run all *_spec.rb tests in spec subdirectory or specified files'
36
+ method_option :"dbms-output",
37
+ :type => :boolean,
38
+ :default => false,
39
+ :banner => "show DBMS_OUTPUT messages"
40
+ method_option :coverage,
41
+ :type => :string,
42
+ :banner => "generate code coverage report in specified directory (defaults to coverage/)"
43
+ method_option :"ignore-schemas",
44
+ :type => :array,
45
+ :banner => "which schemas to ignore when generating code coverage report"
46
+ method_option :like,
47
+ :type => :array,
48
+ :banner => "LIKE condition(s) for filtering which objects to include in code coverage report"
49
+ def run_tests(*files)
50
+ unless File.directory?('spec')
51
+ say "No spec subdirectory in current directory", :red
52
+ exit 1
53
+ end
54
+ ENV['PLSQL_DBMS_OUTPUT'] = 'true' if options[:"dbms-output"]
55
+ ENV['PLSQL_COVERAGE'] = options[:coverage] if options[:coverage]
56
+ ENV['PLSQL_COVERAGE_IGNORE_SCHEMAS'] = options[:"ignore-schemas"].join(',') if options[:"ignore-schemas"]
57
+ ENV['PLSQL_COVERAGE_LIKE'] = options[:like].join(',') if options[:like]
58
+ if files.empty?
59
+ say "Running all specs from spec/", :yellow
60
+ puts run('spec spec', :verbose => false)
61
+ else
62
+ say "Running specs from #{files.join(', ')}", :yellow
63
+ puts run("spec #{files.join(' ')}", :verbose => false)
64
+ end
65
+ unless $?.exitstatus == 0
66
+ say "Failing tests!", :red
67
+ exit 1
68
+ end
69
+ end
70
+
71
+ desc '-v', 'show ruby-plsql-spec and ruby-plsql version'
72
+ def version
73
+ say "ruby-plsql-spec #{PLSQL::Spec::VERSION}"
74
+ say "ruby-plsql #{PLSQL::VERSION}"
75
+ say "rspec #{::Spec::VERSION::STRING}"
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,16 @@
1
+ # Change default connection username, password and database.
2
+ # Specify also host and port if not using tnsnames.ora connection.
3
+ default:
4
+ username: hr
5
+ password: hr
6
+ database: orcl
7
+ # host: localhost
8
+ # port: 1521
9
+
10
+ # Add other connection if needed.
11
+ # You can access them with plsql(:other) where :other is connection name specified below.
12
+
13
+ # other:
14
+ # username: scott
15
+ # password: tiger
16
+ # database: xe
@@ -0,0 +1,17 @@
1
+ # As ruby-plsql returns NUMBER values as BigDecimal values in Ruby then
2
+ # change format how they are by default displayed
3
+ BigDecimal.class_eval do
4
+ def inspect
5
+ to_s('F')
6
+ end
7
+ end
8
+
9
+ # As ruby-plsql returns NULL as Ruby nil then change nil.inspect to return 'NULL'
10
+ NilClass.class_eval do
11
+ def inspect
12
+ 'NULL'
13
+ end
14
+ end
15
+
16
+ # NULL looks more like SQL NULL than nil
17
+ NULL = nil
@@ -0,0 +1,5 @@
1
+ # return current date with time 00:00:00
2
+ def Time.today
3
+ t = Time.now
4
+ Time.local(t.year, t.month, t.day)
5
+ end unless Time.respond_to?(:today)
@@ -0,0 +1,78 @@
1
+ require "rubygems"
2
+ require "ruby-plsql-spec"
3
+ require "yaml"
4
+
5
+ # create all connections specified in database.yml file
6
+ database_config_file = File.expand_path('../database.yml', __FILE__)
7
+ database_config = YAML.load(File.read(database_config_file))
8
+ database_config = {} unless database_config.is_a?(Hash)
9
+ database_connections = database_config.keys.map{|k| k.to_sym}
10
+
11
+ database_config.each do |name, params|
12
+ # change all keys to symbols
13
+ name = name.to_sym
14
+ symbol_params = Hash[*params.map{|k,v| [k.to_sym, v]}.flatten]
15
+
16
+ plsql(name).connect! symbol_params
17
+
18
+ # Set autocommit to false so that automatic commits after each statement are _not_ performed
19
+ plsql(name).connection.autocommit = false
20
+ # reduce network traffic in case of large resultsets
21
+ plsql(name).connection.prefetch_rows = 100
22
+ # log DBMS_OUTPUT to standard output
23
+ if ENV['PLSQL_DBMS_OUTPUT']
24
+ plsql(name).dbms_output_stream = STDOUT
25
+ end
26
+
27
+ # start code coverage collection
28
+ if ENV['PLSQL_COVERAGE']
29
+ PLSQL::Coverage.start(name)
30
+ end
31
+ end
32
+
33
+ # Do logoff when exiting to ensure that session temporary tables
34
+ # (used when calling procedures with table types defined in packages)
35
+ at_exit do
36
+ database_connections.each do |name|
37
+ if ENV['PLSQL_COVERAGE']
38
+ PLSQL::Coverage.stop(name)
39
+ coverage_directory = name == :default ? ENV['PLSQL_COVERAGE'] : "#{ENV['PLSQL_COVERAGE']}/#{name}"
40
+ options = {:directory => coverage_directory}
41
+ options[:ignore_schemas] = ENV['PLSQL_COVERAGE_IGNORE_SCHEMAS'].split(',') if ENV['PLSQL_COVERAGE_IGNORE_SCHEMAS']
42
+ options[:like] = ENV['PLSQL_COVERAGE_LIKE'].split(',') if ENV['PLSQL_COVERAGE_LIKE']
43
+ PLSQL::Coverage.report name, options
44
+ PLSQL::Coverage.cleanup name
45
+ end
46
+ plsql(name).logoff
47
+ end
48
+ end
49
+
50
+ Spec::Runner.configure do |config|
51
+ config.before(:each) do
52
+ database_connections.each do |name|
53
+ plsql(name).savepoint "before_each"
54
+ end
55
+ end
56
+ config.after(:each) do
57
+ # Always perform rollback to savepoint after each test
58
+ database_connections.each do |name|
59
+ plsql(name).rollback_to "before_each"
60
+ end
61
+ end
62
+ config.after(:all) do
63
+ # Always perform rollback after each describe block
64
+ database_connections.each do |name|
65
+ plsql(name).rollback
66
+ end
67
+ end
68
+ end
69
+
70
+ # require all helper methods which are located in any helpers subdirectories
71
+ Dir[File.dirname(__FILE__) + '/**/helpers/*.rb'].each {|f| require f}
72
+
73
+ # require all factory modules which are located in any factories subdirectories
74
+ Dir[File.dirname(__FILE__) + '/**/factories/*.rb'].each {|f| require f}
75
+
76
+ # If necessary add source directory to load path where PL/SQL procedures are defined.
77
+ # It is not required if PL/SQL procedures are already loaded in test database in some other way.
78
+ # $:.push File.dirname(__FILE__) + '/../source'
@@ -0,0 +1,5 @@
1
+ module PLSQL #:nodoc:
2
+ module Spec
3
+ VERSION = File.read(File.expand_path('../../../../VERSION', __FILE__)).chomp
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ require "plsql/spec"
@@ -0,0 +1,113 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{ruby-plsql-spec}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Raimonds Simanovskis"]
12
+ s.date = %q{2010-10-05}
13
+ s.default_executable = %q{plsql-spec}
14
+ s.description = %q{ruby-plsql-spec is Oracle PL/SQL unit testing framework which is built using Ruby programming language, ruby-plsql library and RSpec testing framework.
15
+ }
16
+ s.email = %q{raimonds.simanovskis@gmail.com}
17
+ s.executables = ["plsql-spec"]
18
+ s.extra_rdoc_files = [
19
+ "README.markdown"
20
+ ]
21
+ s.files = [
22
+ ".gitignore",
23
+ "Gemfile",
24
+ "History.txt",
25
+ "INSTALL-Windows.markdown",
26
+ "License.txt",
27
+ "README.markdown",
28
+ "Rakefile",
29
+ "VERSION",
30
+ "bin/plsql-spec",
31
+ "examples/source/award_bonus.rb",
32
+ "examples/source/betwnstr.rb",
33
+ "examples/source/remove_rooms_by_name.rb",
34
+ "examples/source/what_is_profiled.rb",
35
+ "examples/spec/award_bonus_spec.rb",
36
+ "examples/spec/betwnstr_spec.rb",
37
+ "examples/spec/database.yml",
38
+ "examples/spec/factories/employee_factory.rb",
39
+ "examples/spec/helpers/inspect_helpers.rb",
40
+ "examples/spec/helpers/oracle_ebs_helpers.rb",
41
+ "examples/spec/helpers/time_helpers.rb",
42
+ "examples/spec/oracle_ebs_spec.rb",
43
+ "examples/spec/remove_rooms_by_name_spec.rb",
44
+ "examples/spec/spec_helper.rb",
45
+ "examples/spec/what_is_profiled_spec.rb",
46
+ "lib/plsql/coverage.rb",
47
+ "lib/plsql/coverage/coverage.css",
48
+ "lib/plsql/coverage/details.html.erb",
49
+ "lib/plsql/coverage/index.html.erb",
50
+ "lib/plsql/coverage/jquery.min.js",
51
+ "lib/plsql/coverage/jquery.tablesorter.min.js",
52
+ "lib/plsql/coverage/proftab.sql",
53
+ "lib/plsql/coverage/rcov.js",
54
+ "lib/plsql/coverage/table_line.html.erb",
55
+ "lib/plsql/spec.rb",
56
+ "lib/plsql/spec/cli.rb",
57
+ "lib/plsql/spec/templates/database.yml",
58
+ "lib/plsql/spec/templates/helpers/inspect_helpers.rb",
59
+ "lib/plsql/spec/templates/helpers/time_helpers.rb",
60
+ "lib/plsql/spec/templates/spec_helper.rb",
61
+ "lib/plsql/spec/version.rb",
62
+ "lib/ruby-plsql-spec.rb",
63
+ "ruby-plsql-spec.gemspec",
64
+ "spec/plsql/coverage_spec.rb",
65
+ "spec/plsql/spec/cli_spec.rb",
66
+ "spec/spec.opts",
67
+ "spec/spec_helper.rb"
68
+ ]
69
+ s.homepage = %q{http://github.com/rsim/ruby-plsql-spec}
70
+ s.rdoc_options = ["--charset=UTF-8"]
71
+ s.require_paths = ["lib"]
72
+ s.rubygems_version = %q{1.3.7}
73
+ s.summary = %q{Oracle PL/SQL unit testing framework using Ruby and RSpec}
74
+ s.test_files = [
75
+ "spec/plsql/coverage_spec.rb",
76
+ "spec/plsql/spec/cli_spec.rb",
77
+ "spec/spec_helper.rb",
78
+ "examples/source/award_bonus.rb",
79
+ "examples/source/betwnstr.rb",
80
+ "examples/source/remove_rooms_by_name.rb",
81
+ "examples/source/what_is_profiled.rb",
82
+ "examples/spec/award_bonus_spec.rb",
83
+ "examples/spec/betwnstr_spec.rb",
84
+ "examples/spec/factories/employee_factory.rb",
85
+ "examples/spec/helpers/inspect_helpers.rb",
86
+ "examples/spec/helpers/oracle_ebs_helpers.rb",
87
+ "examples/spec/helpers/time_helpers.rb",
88
+ "examples/spec/oracle_ebs_spec.rb",
89
+ "examples/spec/remove_rooms_by_name_spec.rb",
90
+ "examples/spec/spec_helper.rb",
91
+ "examples/spec/what_is_profiled_spec.rb"
92
+ ]
93
+
94
+ if s.respond_to? :specification_version then
95
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
96
+ s.specification_version = 3
97
+
98
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
99
+ s.add_runtime_dependency(%q<ruby-plsql>, [">= 0.4.3"])
100
+ s.add_runtime_dependency(%q<thor>, [">= 0.14.2"])
101
+ s.add_runtime_dependency(%q<rspec>, ["~> 1.3.0"])
102
+ else
103
+ s.add_dependency(%q<ruby-plsql>, [">= 0.4.3"])
104
+ s.add_dependency(%q<thor>, [">= 0.14.2"])
105
+ s.add_dependency(%q<rspec>, ["~> 1.3.0"])
106
+ end
107
+ else
108
+ s.add_dependency(%q<ruby-plsql>, [">= 0.4.3"])
109
+ s.add_dependency(%q<thor>, [">= 0.14.2"])
110
+ s.add_dependency(%q<rspec>, ["~> 1.3.0"])
111
+ end
112
+ end
113
+