metric_fu 4.8.0 → 4.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.metrics +1 -66
- data/.travis.yml +1 -0
- data/CONTRIBUTORS +13 -11
- data/DEV.md +21 -18
- data/Gemfile +1 -2
- data/Gemfile.devtools +0 -1
- data/HISTORY.md +7 -1
- data/README.md +79 -19
- data/Rakefile +0 -1
- data/checksum/metric_fu-4.8.0.gem.sha512 +1 -0
- data/gem_tasks/usage_test.rake +30 -0
- data/lib/metric_fu/configuration.rb +6 -1
- data/lib/metric_fu/data_structures/line_numbers.rb +1 -1
- data/lib/metric_fu/environment.rb +2 -7
- data/lib/metric_fu/logging/mf_debugger.rb +4 -4
- data/lib/metric_fu/metric.rb +2 -2
- data/lib/metric_fu/metrics/cane/template_awesome/cane.html.erb +74 -85
- data/lib/metric_fu/metrics/churn/churn.rb +1 -2
- data/lib/metric_fu/metrics/flay/template_awesome/flay.html.erb +2 -1
- data/lib/metric_fu/metrics/flog/template_awesome/flog.html.erb +2 -1
- data/lib/metric_fu/metrics/rails_best_practices/template_awesome/rails_best_practices.html.erb +2 -1
- data/lib/metric_fu/metrics/rcov/external_client.rb +24 -0
- data/lib/metric_fu/metrics/rcov/rcov.rb +9 -100
- data/lib/metric_fu/metrics/rcov/rcov_format_coverage.rb +140 -0
- data/lib/metric_fu/metrics/rcov/simplecov_formatter.rb +64 -0
- data/lib/metric_fu/metrics/rcov/template_awesome/rcov.html.erb +5 -1
- data/lib/metric_fu/metrics/reek/reek_grapher.rb +7 -1
- data/lib/metric_fu/metrics/reek/template_awesome/reek.html.erb +2 -1
- data/lib/metric_fu/metrics/roodi/template_awesome/roodi.html.erb +2 -1
- data/lib/metric_fu/metrics/stats/template_awesome/stats.html.erb +2 -2
- data/lib/metric_fu/reporting/graphs/grapher.rb +5 -20
- data/lib/metric_fu/reporting/templates/awesome/awesome_template.rb +1 -1
- data/lib/metric_fu/reporting/templates/awesome/layout.html.erb +8 -3
- data/lib/metric_fu/reporting/templates/javascripts/bluff_graph.js +15 -0
- data/lib/metric_fu/reporting/templates/javascripts/excanvas.js +1 -1
- data/lib/metric_fu/reporting/templates/javascripts/highcharts.js +294 -0
- data/lib/metric_fu/reporting/templates/javascripts/highcharts_graph.js +38 -0
- data/lib/metric_fu/reporting/templates/javascripts/standalone-framework.js +17 -0
- data/lib/metric_fu/reporting/templates/javascripts/utils.js +9 -0
- data/lib/metric_fu/templates/css/bluff.css +10 -10
- data/lib/metric_fu/templates/css/integrity.css +3 -0
- data/lib/metric_fu/templates/report.html.erb +3 -4
- data/lib/metric_fu/version.rb +1 -1
- data/metric_fu.gemspec +1 -0
- data/spec/fixtures/coverage.rb +13 -0
- data/spec/fixtures/exit0.sh +3 -0
- data/spec/fixtures/exit1.sh +3 -0
- data/spec/metric_fu/formatter/html_spec.rb +2 -2
- data/spec/metric_fu/metrics/rcov/simplecov_formatter_spec.rb +41 -0
- data/spec/spec_helper.rb +7 -8
- data/spec/support/usage_test.rb +134 -0
- data/spec/usage_test_spec.rb +69 -0
- metadata +39 -3
- metadata.gz.sig +0 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
createGraphElement("div");
|
2
|
+
|
3
|
+
if(document.getElementById('graph')) {
|
4
|
+
var chart = new Highcharts.Chart({
|
5
|
+
chart: {
|
6
|
+
animation: false,
|
7
|
+
renderTo: 'graph'
|
8
|
+
},
|
9
|
+
legend: {
|
10
|
+
align: 'center',
|
11
|
+
verticalAlign: 'top',
|
12
|
+
y: 25
|
13
|
+
},
|
14
|
+
plotOptions: {
|
15
|
+
line: {
|
16
|
+
animation: false,
|
17
|
+
lineWidth: 3,
|
18
|
+
marker: {
|
19
|
+
radius: 6
|
20
|
+
},
|
21
|
+
pointPlacement: 'on'
|
22
|
+
}
|
23
|
+
},
|
24
|
+
title: {
|
25
|
+
text: graph_title
|
26
|
+
},
|
27
|
+
xAxis: {
|
28
|
+
categories: graph_labels,
|
29
|
+
tickmarkPlacement: 'on'
|
30
|
+
},
|
31
|
+
yAxis: {
|
32
|
+
maxPadding: 0,
|
33
|
+
min: 0,
|
34
|
+
minPadding: 0
|
35
|
+
},
|
36
|
+
series: graph_series
|
37
|
+
});
|
38
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
/*
|
2
|
+
Highcharts JS v3.0.9 (2014-01-15)
|
3
|
+
|
4
|
+
Standalone Highcharts Framework
|
5
|
+
|
6
|
+
License: MIT License
|
7
|
+
*/
|
8
|
+
var HighchartsAdapter=function(){function o(c){function b(b,a,d){b.removeEventListener(a,d,!1)}function d(b,a,d){d=b.HCProxiedMethods[d.toString()];b.detachEvent("on"+a,d)}function a(a,c){var f=a.HCEvents,i,g,k,j;if(a.removeEventListener)i=b;else if(a.attachEvent)i=d;else return;c?(g={},g[c]=!0):g=f;for(j in g)if(f[j])for(k=f[j].length;k--;)i(a,j,f[j][k])}c.HCExtended||Highcharts.extend(c,{HCExtended:!0,HCEvents:{},bind:function(a,b){var d=this,c=this.HCEvents,g;if(d.addEventListener)d.addEventListener(a,
|
9
|
+
b,!1);else if(d.attachEvent){g=function(a){b.call(d,a)};if(!d.HCProxiedMethods)d.HCProxiedMethods={};d.HCProxiedMethods[b.toString()]=g;d.attachEvent("on"+a,g)}c[a]===r&&(c[a]=[]);c[a].push(b)},unbind:function(c,h){var f,i;c?(f=this.HCEvents[c]||[],h?(i=HighchartsAdapter.inArray(h,f),i>-1&&(f.splice(i,1),this.HCEvents[c]=f),this.removeEventListener?b(this,c,h):this.attachEvent&&d(this,c,h)):(a(this,c),this.HCEvents[c]=[])):(a(this),this.HCEvents={})},trigger:function(a,b){var d=this.HCEvents[a]||
|
10
|
+
[],c=d.length,g,k,j;k=function(){b.defaultPrevented=!0};for(g=0;g<c;g++){j=d[g];if(b.stopped)break;b.preventDefault=k;b.target=this;if(!b.type)b.type=a;j.call(this,b)===!1&&b.preventDefault()}}});return c}var r,l=document,p=[],m=[],q,n;Math.easeInOutSine=function(c,b,d,a){return-d/2*(Math.cos(Math.PI*c/a)-1)+b};return{init:function(c){if(!l.defaultView)this._getStyle=function(b,d){var a;return b.style[d]?b.style[d]:(d==="opacity"&&(d="filter"),a=b.currentStyle[d.replace(/\-(\w)/g,function(b,a){return a.toUpperCase()})],
|
11
|
+
d==="filter"&&(a=a.replace(/alpha\(opacity=([0-9]+)\)/,function(b,a){return a/100})),a===""?1:a)},this.adapterRun=function(b,d){var a={width:"clientWidth",height:"clientHeight"}[d];if(a)return b.style.zoom=1,b[a]-2*parseInt(HighchartsAdapter._getStyle(b,"padding"),10)};if(!Array.prototype.forEach)this.each=function(b,d){for(var a=0,c=b.length;a<c;a++)if(d.call(b[a],b[a],a,b)===!1)return a};if(!Array.prototype.indexOf)this.inArray=function(b,d){var a,c=0;if(d)for(a=d.length;c<a;c++)if(d[c]===b)return c;
|
12
|
+
return-1};if(!Array.prototype.filter)this.grep=function(b,d){for(var a=[],c=0,h=b.length;c<h;c++)d(b[c],c)&&a.push(b[c]);return a};n=function(b,c,a){this.options=c;this.elem=b;this.prop=a};n.prototype={update:function(){var b;b=this.paths;var d=this.elem,a=d.element;b&&a?d.attr("d",c.step(b[0],b[1],this.now,this.toD)):d.attr?a&&d.attr(this.prop,this.now):(b={},b[d]=this.now+this.unit,Highcharts.css(d,b));this.options.step&&this.options.step.call(this.elem,this.now,this)},custom:function(b,c,a){var e=
|
13
|
+
this,h=function(a){return e.step(a)},f;this.startTime=+new Date;this.start=b;this.end=c;this.unit=a;this.now=this.start;this.pos=this.state=0;h.elem=this.elem;h()&&m.push(h)===1&&(q=setInterval(function(){for(f=0;f<m.length;f++)m[f]()||m.splice(f--,1);m.length||clearInterval(q)},13))},step:function(b){var c=+new Date,a;a=this.options;var e;if(this.elem.stopAnimation)a=!1;else if(b||c>=a.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();b=this.options.curAnim[this.prop]=
|
14
|
+
!0;for(e in a.curAnim)a.curAnim[e]!==!0&&(b=!1);b&&a.complete&&a.complete.call(this.elem);a=!1}else e=c-this.startTime,this.state=e/a.duration,this.pos=a.easing(e,0,1,a.duration),this.now=this.start+(this.end-this.start)*this.pos,this.update(),a=!0;return a}};this.animate=function(b,d,a){var e,h="",f,i,g;b.stopAnimation=!1;if(typeof a!=="object"||a===null)e=arguments,a={duration:e[2],easing:e[3],complete:e[4]};if(typeof a.duration!=="number")a.duration=400;a.easing=Math[a.easing]||Math.easeInOutSine;
|
15
|
+
a.curAnim=Highcharts.extend({},d);for(g in d)i=new n(b,a,g),f=null,g==="d"?(i.paths=c.init(b,b.d,d.d),i.toD=d.d,e=0,f=1):b.attr?e=b.attr(g):(e=parseFloat(HighchartsAdapter._getStyle(b,g))||0,g!=="opacity"&&(h="px")),f||(f=parseFloat(d[g])),i.custom(e,f,h)}},_getStyle:function(c,b){return window.getComputedStyle(c).getPropertyValue(b)},getScript:function(c,b){var d=l.getElementsByTagName("head")[0],a=l.createElement("script");a.type="text/javascript";a.src=c;a.onload=b;d.appendChild(a)},inArray:function(c,
|
16
|
+
b){return b.indexOf?b.indexOf(c):p.indexOf.call(b,c)},adapterRun:function(c,b){return parseInt(HighchartsAdapter._getStyle(c,b),10)},grep:function(c,b){return p.filter.call(c,b)},map:function(c,b){for(var d=[],a=0,e=c.length;a<e;a++)d[a]=b.call(c[a],c[a],a,c);return d},offset:function(c){for(var b=0,d=0;c;)b+=c.offsetLeft,d+=c.offsetTop,c=c.offsetParent;return{left:b,top:d}},addEvent:function(c,b,d){o(c).bind(b,d)},removeEvent:function(c,b,d){o(c).unbind(b,d)},fireEvent:function(c,b,d,a){var e;l.createEvent&&
|
17
|
+
(c.dispatchEvent||c.fireEvent)?(e=l.createEvent("Events"),e.initEvent(b,!0,!0),e.target=c,Highcharts.extend(e,d),c.dispatchEvent?c.dispatchEvent(e):c.fireEvent(b,e)):c.HCExtended===!0&&(d=d||{},c.trigger(b,d));d&&d.defaultPrevented&&(a=null);a&&a(d)},washMouseEvent:function(c){return c},stop:function(c){c.stopAnimation=!0},each:function(c,b){return Array.prototype.forEach.call(c,b)}}}();
|
@@ -0,0 +1,9 @@
|
|
1
|
+
function createGraphElement(elementType) {
|
2
|
+
var graphContainer = document.getElementById("graph_container");
|
3
|
+
|
4
|
+
if(graphContainer) {
|
5
|
+
var graphElement = document.createElement(elementType);
|
6
|
+
graphElement.setAttribute("id", "graph");
|
7
|
+
graphContainer.appendChild(graphElement);
|
8
|
+
}
|
9
|
+
}
|
@@ -1,15 +1,15 @@
|
|
1
1
|
.bluff-tooltip {
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
background: #fff;
|
3
|
+
border: 1px solid #d1edf5;
|
4
|
+
padding: 8px 8px 6px;
|
5
5
|
}
|
6
6
|
.bluff-tooltip .color {
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
display: block;
|
8
|
+
height: 4px;
|
9
|
+
width: 30px;
|
10
|
+
margin: 0 0 4px;
|
11
|
+
overflow: hidden;
|
12
12
|
}
|
13
13
|
.bluff-tooltip .data {
|
14
|
-
|
15
|
-
}
|
14
|
+
font-weight: bold;
|
15
|
+
}
|
@@ -1,10 +1,9 @@
|
|
1
1
|
<html>
|
2
2
|
<head>
|
3
3
|
<style>
|
4
|
-
|
5
|
-
<%= inline_css('css/bluff.css') if MetricFu.configuration.graph_engine == :bluff %>
|
6
|
-
<%= inline_css('css/rcov.css') if @metrics.has_key?(:rcov) %>
|
4
|
+
<%= inline_css('css/syntax.css') %>
|
7
5
|
</style>
|
6
|
+
<title>Analyzed File Report</title>
|
8
7
|
</head>
|
9
8
|
<body>
|
10
9
|
<table cellpadding='0' cellspacing='0' class='ruby'>
|
@@ -27,6 +26,6 @@
|
|
27
26
|
</td>
|
28
27
|
</tr>
|
29
28
|
<% end %>
|
30
|
-
|
29
|
+
</table>
|
31
30
|
</body>
|
32
31
|
</html>
|
data/lib/metric_fu/version.rb
CHANGED
data/metric_fu.gemspec
CHANGED
@@ -67,7 +67,7 @@ describe MetricFu::Formatter::HTML do
|
|
67
67
|
it "copies common javascripts to the output directory" do
|
68
68
|
expect {
|
69
69
|
MetricFu::Formatter::HTML.new.finish
|
70
|
-
}.to create_file("#{directory('output_directory')}/
|
70
|
+
}.to create_file("#{directory('output_directory')}/highcharts*.js")
|
71
71
|
end
|
72
72
|
|
73
73
|
it "creates graphs for appropriate metrics" do
|
@@ -118,7 +118,7 @@ describe MetricFu::Formatter::HTML do
|
|
118
118
|
it "copies common javascripts to the custom output directory" do
|
119
119
|
expect {
|
120
120
|
MetricFu::Formatter::HTML.new(output: @output).finish
|
121
|
-
}.to create_file("#{directory('base_directory')}/#{@output}/
|
121
|
+
}.to create_file("#{directory('base_directory')}/#{@output}/highcharts*.js")
|
122
122
|
end
|
123
123
|
|
124
124
|
it "creates graphs for appropriate metrics in the custom output directory " do
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'simplecov'
|
3
|
+
require 'metric_fu/metrics/rcov/simplecov_formatter'
|
4
|
+
|
5
|
+
describe SimpleCov::Formatter::MetricFu do
|
6
|
+
before do
|
7
|
+
@rcov_file = subject.coverage_file_path
|
8
|
+
File.delete( @rcov_file ) if File.exists?( @rcov_file )
|
9
|
+
|
10
|
+
@result = SimpleCov::Result.new(
|
11
|
+
{
|
12
|
+
FIXTURE.fixtures_path.join('coverage.rb').expand_path.to_s =>
|
13
|
+
[1,1,1,1,nil,1,0,1,1,nil,0,1,1]
|
14
|
+
}
|
15
|
+
)
|
16
|
+
|
17
|
+
# Set to default encoding
|
18
|
+
Encoding.default_internal = nil if defined?(Encoding)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "test_format" do
|
22
|
+
SimpleCov::Formatter::MetricFu.new.format( @result )
|
23
|
+
|
24
|
+
expect(File.exists?( @rcov_file )).to be_truthy
|
25
|
+
end
|
26
|
+
|
27
|
+
it "test_encoding" do
|
28
|
+
# This is done in many rails environments
|
29
|
+
Encoding.default_internal = 'UTF-8' if defined?(Encoding)
|
30
|
+
|
31
|
+
SimpleCov::Formatter::MetricFu.new.format( @result )
|
32
|
+
end
|
33
|
+
|
34
|
+
it "test_create_content" do
|
35
|
+
content = SimpleCov::Formatter::MetricFu::FormatLikeRCov.new(@result).format
|
36
|
+
test = "\="*80
|
37
|
+
|
38
|
+
expect(content).to match(/#{test}/)
|
39
|
+
expect(content).to match(/!! value \* value/)
|
40
|
+
end
|
41
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,27 +1,26 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# add lib to the load path just like rubygems does
|
2
|
+
$:.unshift File.expand_path("../../lib", __FILE__)
|
3
3
|
if ENV['COVERAGE']
|
4
4
|
require 'simplecov'
|
5
5
|
formatters = [SimpleCov::Formatter::HTMLFormatter]
|
6
6
|
begin
|
7
7
|
puts '[COVERAGE] Running with SimpleCov HTML Formatter'
|
8
|
-
require '
|
9
|
-
formatters << SimpleCov::Formatter::
|
10
|
-
puts '[COVERAGE] Running with SimpleCov
|
8
|
+
require 'metric_fu/metrics/rcov/simplecov_formatter'
|
9
|
+
formatters << SimpleCov::Formatter::MetricFu
|
10
|
+
puts '[COVERAGE] Running with SimpleCov MetricFu Formatter'
|
11
11
|
rescue LoadError
|
12
|
-
puts '[COVERAGE] SimpleCov
|
12
|
+
puts '[COVERAGE] SimpleCov MetricFu formatter could not be loaded'
|
13
13
|
end
|
14
14
|
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ *formatters ]
|
15
15
|
SimpleCov.start
|
16
16
|
end
|
17
17
|
|
18
|
+
require 'rspec/autorun'
|
18
19
|
require 'date'
|
19
20
|
require 'test_construct'
|
20
21
|
require 'json'
|
21
22
|
require 'pry-nav'
|
22
23
|
|
23
|
-
# add lib to the load path just like rubygems does
|
24
|
-
$:.unshift File.expand_path("../../lib", __FILE__)
|
25
24
|
require 'metric_fu'
|
26
25
|
include MetricFu
|
27
26
|
def mf_log(msg); mf_debug(msg); end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# usage_test = UsageTest.new
|
2
|
+
# usage_test.test_files(EXAMPLE_FILES)
|
3
|
+
|
4
|
+
# puts "SUCCESS!"
|
5
|
+
# Process.exit! 0
|
6
|
+
require 'metric_fu/logging/mf_debugger'
|
7
|
+
require 'open3'
|
8
|
+
class UsageTest
|
9
|
+
def initialize
|
10
|
+
@markdown = Redcarpet::Markdown.new(HTMLRenderAndVerifyCodeBlocks, :fenced_code_blocks => true)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_files(paths)
|
14
|
+
in_test_directory do
|
15
|
+
Array(paths).each do |path|
|
16
|
+
puts "Testing #{path}"
|
17
|
+
@markdown.render(File.read(path))
|
18
|
+
puts
|
19
|
+
end
|
20
|
+
end
|
21
|
+
puts "SUCCESS!"
|
22
|
+
Process.exit! 0
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def in_test_directory
|
28
|
+
Dir.mktmpdir do |dir|
|
29
|
+
Dir.chdir(dir) {
|
30
|
+
`git init; touch README; git add README; git commit -m 'first'`
|
31
|
+
yield
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
SnippetRunner = Struct.new(:code, :language) do
|
37
|
+
include MfDebugger
|
38
|
+
SystemCommandError = Class.new(StandardError)
|
39
|
+
TestResult = Struct.new(:success, :captured_output)
|
40
|
+
|
41
|
+
def test!
|
42
|
+
time = Time.now
|
43
|
+
test_result = run_code
|
44
|
+
mf_debug "#{Time.now - time} seconds"
|
45
|
+
if test_result.success
|
46
|
+
print '.'
|
47
|
+
else
|
48
|
+
puts 'x'
|
49
|
+
puts "Red :( language: #{language}, code #{code}, #{test_result.captured_output}"
|
50
|
+
Process.exit! 1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def run_code(test_result = TestResult.new(:no_result,''))
|
55
|
+
test_result.captured_output = case language
|
56
|
+
when 'ruby' then eval_ruby
|
57
|
+
when 'sh' then run_system_command
|
58
|
+
else mf_debug "Cannot test language: #{language.inspect}"
|
59
|
+
end
|
60
|
+
test_result.success = true
|
61
|
+
test_result
|
62
|
+
rescue StandardError => run_error
|
63
|
+
test_result.captured_output = exception_message(run_error)
|
64
|
+
test_result.success = false
|
65
|
+
test_result
|
66
|
+
rescue SystemExit => system_exit
|
67
|
+
puts "I am a system exit"
|
68
|
+
test_result.captured_output = exception_message(system_exit)
|
69
|
+
test_result.success = system_exit.success?
|
70
|
+
test_result
|
71
|
+
end
|
72
|
+
|
73
|
+
def eval_ruby(fail_on_empty=false)
|
74
|
+
capture_output(fail_on_empty) do
|
75
|
+
instance_eval(code)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def run_system_command(fail_on_empty=true)
|
80
|
+
out = ''
|
81
|
+
err = ''
|
82
|
+
pid = :not_set
|
83
|
+
exit_status = :not_set
|
84
|
+
Open3.popen3(code) do |stdin, stdout, stderr, wait_thr|
|
85
|
+
out << stdout.read.chomp
|
86
|
+
err << stderr.read.chomp
|
87
|
+
pid = wait_thr.pid
|
88
|
+
exit_status = wait_thr.value
|
89
|
+
end
|
90
|
+
exit_code = exit_status.exitstatus
|
91
|
+
case exit_code
|
92
|
+
when 0 then "Ran with exit status #{exit_code}"
|
93
|
+
when (1..Float::INFINITY) then fail SystemCommandError.new("Failed with exit status #{exit_code}. #{err}----#{out}")
|
94
|
+
else fail SystemCommandError.new("Execution failed with exit status #{exit_code}. #{err}----#{out}")
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
def exception_message(e)
|
100
|
+
"#{e.class}\t#{e.message}"
|
101
|
+
end
|
102
|
+
|
103
|
+
def capture_output(fail_on_empty)
|
104
|
+
exception = nil
|
105
|
+
stderr = :not_set
|
106
|
+
stdout = :not_set
|
107
|
+
MfDebugger::Logger.capture_output(STDOUT) do
|
108
|
+
stdout =
|
109
|
+
MfDebugger::Logger.capture_output(STDERR) do
|
110
|
+
begin
|
111
|
+
stderr = yield
|
112
|
+
rescue Exception => e
|
113
|
+
exception = e
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
if [nil, '', :not_set].none? {|c| c == stderr }
|
118
|
+
mf_debug "Captured STDERR"
|
119
|
+
stderr
|
120
|
+
elsif [nil, '', :not_set].none? {|c| c == stdout }
|
121
|
+
mf_debug "Captured STDOUT"
|
122
|
+
stdout
|
123
|
+
elsif exception
|
124
|
+
mf_debug "Captured Exception"
|
125
|
+
raise exception
|
126
|
+
else
|
127
|
+
mf_debug "Captured Nothing"
|
128
|
+
if fail_on_empty
|
129
|
+
fail SystemCommandError.new 'No output generated or exception caught'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
describe 'usage test' do
|
2
|
+
ROOT_PATH = File.expand_path("..", File.dirname(__FILE__))
|
3
|
+
require File.join(ROOT_PATH, 'spec/support/usage_test')
|
4
|
+
|
5
|
+
context 'evaluating ruby code' do
|
6
|
+
specify 'succeeds when the code runs without errors' do
|
7
|
+
code = "1 + 1"
|
8
|
+
test_result = SnippetRunner.new(code, 'ruby').run_code
|
9
|
+
expect(test_result.captured_output).to eq(2)
|
10
|
+
expect(test_result.success).to eq(true)
|
11
|
+
end
|
12
|
+
specify 'fails when the code raises a standard error' do
|
13
|
+
code = "fail NameError.new('no name')"
|
14
|
+
test_result = SnippetRunner.new(code, 'ruby').run_code
|
15
|
+
expect(test_result.captured_output).to match('NameError')
|
16
|
+
expect(test_result.captured_output).to match('no name')
|
17
|
+
expect(test_result.success).to eq(false)
|
18
|
+
end
|
19
|
+
specify 'succeeds when the code exits with a zero exit status' do
|
20
|
+
code = "puts 1 + 1; exit 0"
|
21
|
+
test_result = SnippetRunner.new(code, 'ruby').run_code
|
22
|
+
expect(test_result.captured_output).to match('SystemExit')
|
23
|
+
expect(test_result.success).to eq(true)
|
24
|
+
end
|
25
|
+
specify 'fails when the code exits with a non-zero exit status' do
|
26
|
+
code = "puts 1 + 1; exit 1"
|
27
|
+
test_result = SnippetRunner.new(code, 'ruby').run_code
|
28
|
+
expect(test_result.captured_output).to match('SystemExit')
|
29
|
+
expect(test_result.success).to eq(false)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
context 'evaluating shell commands' do
|
34
|
+
specify 'succeeds when the command runs without errors' do
|
35
|
+
code = "which ruby"
|
36
|
+
test_result = SnippetRunner.new(code, 'sh').run_code
|
37
|
+
expect(test_result.captured_output).to match("exit status 0")
|
38
|
+
expect(test_result.success).to eq(true)
|
39
|
+
end
|
40
|
+
specify 'fails when the command runs with an error' do
|
41
|
+
code = "sandwhich_fu ruby"
|
42
|
+
test_result = SnippetRunner.new(code, 'sh').run_code
|
43
|
+
expect(test_result.captured_output).to match(failed_command_error)
|
44
|
+
expect(test_result.success).to eq(false)
|
45
|
+
end
|
46
|
+
specify 'succeeds when the code exits with a zero exit status' do
|
47
|
+
code = "sh #{fixtures_path.join('exit0.sh').to_path}"
|
48
|
+
test_result = SnippetRunner.new(code, 'sh').run_code
|
49
|
+
expect(test_result.captured_output).to match("exit status 0")
|
50
|
+
expect(test_result.success).to eq(true)
|
51
|
+
end
|
52
|
+
specify 'fails when the code exits with a non-zero exit status' do
|
53
|
+
code = "sh #{fixtures_path.join('exit1.sh').to_path}"
|
54
|
+
test_result = SnippetRunner.new(code, 'sh').run_code
|
55
|
+
expect(test_result.captured_output).to match("exit status 1")
|
56
|
+
expect(test_result.success).to eq(false)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
def failed_command_error
|
62
|
+
defined?(JRUBY_VERSION) ? 'IOError' : 'Errno::ENOENT'
|
63
|
+
end
|
64
|
+
|
65
|
+
def fixtures_path
|
66
|
+
fixtures_dir = File.join(File.expand_path('..', File.dirname(__FILE__)), 'spec', 'fixtures')
|
67
|
+
Pathname(fixtures_dir)
|
68
|
+
end
|
69
|
+
end
|