metric_fu 4.8.0 → 4.9.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 (57) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.metrics +1 -66
  5. data/.travis.yml +1 -0
  6. data/CONTRIBUTORS +13 -11
  7. data/DEV.md +21 -18
  8. data/Gemfile +1 -2
  9. data/Gemfile.devtools +0 -1
  10. data/HISTORY.md +7 -1
  11. data/README.md +79 -19
  12. data/Rakefile +0 -1
  13. data/checksum/metric_fu-4.8.0.gem.sha512 +1 -0
  14. data/gem_tasks/usage_test.rake +30 -0
  15. data/lib/metric_fu/configuration.rb +6 -1
  16. data/lib/metric_fu/data_structures/line_numbers.rb +1 -1
  17. data/lib/metric_fu/environment.rb +2 -7
  18. data/lib/metric_fu/logging/mf_debugger.rb +4 -4
  19. data/lib/metric_fu/metric.rb +2 -2
  20. data/lib/metric_fu/metrics/cane/template_awesome/cane.html.erb +74 -85
  21. data/lib/metric_fu/metrics/churn/churn.rb +1 -2
  22. data/lib/metric_fu/metrics/flay/template_awesome/flay.html.erb +2 -1
  23. data/lib/metric_fu/metrics/flog/template_awesome/flog.html.erb +2 -1
  24. data/lib/metric_fu/metrics/rails_best_practices/template_awesome/rails_best_practices.html.erb +2 -1
  25. data/lib/metric_fu/metrics/rcov/external_client.rb +24 -0
  26. data/lib/metric_fu/metrics/rcov/rcov.rb +9 -100
  27. data/lib/metric_fu/metrics/rcov/rcov_format_coverage.rb +140 -0
  28. data/lib/metric_fu/metrics/rcov/simplecov_formatter.rb +64 -0
  29. data/lib/metric_fu/metrics/rcov/template_awesome/rcov.html.erb +5 -1
  30. data/lib/metric_fu/metrics/reek/reek_grapher.rb +7 -1
  31. data/lib/metric_fu/metrics/reek/template_awesome/reek.html.erb +2 -1
  32. data/lib/metric_fu/metrics/roodi/template_awesome/roodi.html.erb +2 -1
  33. data/lib/metric_fu/metrics/stats/template_awesome/stats.html.erb +2 -2
  34. data/lib/metric_fu/reporting/graphs/grapher.rb +5 -20
  35. data/lib/metric_fu/reporting/templates/awesome/awesome_template.rb +1 -1
  36. data/lib/metric_fu/reporting/templates/awesome/layout.html.erb +8 -3
  37. data/lib/metric_fu/reporting/templates/javascripts/bluff_graph.js +15 -0
  38. data/lib/metric_fu/reporting/templates/javascripts/excanvas.js +1 -1
  39. data/lib/metric_fu/reporting/templates/javascripts/highcharts.js +294 -0
  40. data/lib/metric_fu/reporting/templates/javascripts/highcharts_graph.js +38 -0
  41. data/lib/metric_fu/reporting/templates/javascripts/standalone-framework.js +17 -0
  42. data/lib/metric_fu/reporting/templates/javascripts/utils.js +9 -0
  43. data/lib/metric_fu/templates/css/bluff.css +10 -10
  44. data/lib/metric_fu/templates/css/integrity.css +3 -0
  45. data/lib/metric_fu/templates/report.html.erb +3 -4
  46. data/lib/metric_fu/version.rb +1 -1
  47. data/metric_fu.gemspec +1 -0
  48. data/spec/fixtures/coverage.rb +13 -0
  49. data/spec/fixtures/exit0.sh +3 -0
  50. data/spec/fixtures/exit1.sh +3 -0
  51. data/spec/metric_fu/formatter/html_spec.rb +2 -2
  52. data/spec/metric_fu/metrics/rcov/simplecov_formatter_spec.rb +41 -0
  53. data/spec/spec_helper.rb +7 -8
  54. data/spec/support/usage_test.rb +134 -0
  55. data/spec/usage_test_spec.rb +69 -0
  56. metadata +39 -3
  57. 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
- background: #fff;
3
- border: 1px solid #d1edf5;
4
- padding: 8px 8px 6px;
2
+ background: #fff;
3
+ border: 1px solid #d1edf5;
4
+ padding: 8px 8px 6px;
5
5
  }
6
6
  .bluff-tooltip .color {
7
- display: block;
8
- height: 4px;
9
- width: 30px;
10
- margin: 0 0 4px;
11
- overflow: hidden;
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
- font-weight: bold;
15
- }
14
+ font-weight: bold;
15
+ }
@@ -312,6 +312,9 @@ a {
312
312
  display: block;
313
313
  margin-top: 1em;
314
314
  margin-left: 2em; }
315
+ #content div#graph {
316
+ width: 100%;
317
+ height: 600px; }
315
318
 
316
319
  a.success {
317
320
  color: #bbf8aa; }
@@ -1,10 +1,9 @@
1
1
  <html>
2
2
  <head>
3
3
  <style>
4
- <%= inline_css('css/syntax.css') %>
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
- <table>
29
+ </table>
31
30
  </body>
32
31
  </html>
@@ -1,3 +1,3 @@
1
1
  module MetricFu
2
- VERSION = '4.8.0'
2
+ VERSION = '4.9.0'
3
3
  end
data/metric_fu.gemspec CHANGED
@@ -64,5 +64,6 @@ Gem::Specification.new do |s|
64
64
  s.add_development_dependency 'test_construct'
65
65
  # ensure we have a JSON parser
66
66
  s.add_development_dependency 'json'
67
+ s.add_development_dependency 'simplecov'
67
68
 
68
69
  end
@@ -0,0 +1,13 @@
1
+ class SomeClass
2
+ def method_1
3
+ 1+1
4
+ end
5
+
6
+ def method_2 ( value )
7
+ value * value
8
+ end
9
+
10
+ def method_3
11
+ "über"
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+ which ruby
3
+ exit 0
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+ which ruby
3
+ exit 1
@@ -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')}/bluff*.js")
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}/bluff*.js")
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
- require 'rspec/autorun'
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 'simplecov-rcov-text'
9
- formatters << SimpleCov::Formatter::RcovTextFormatter
10
- puts '[COVERAGE] Running with SimpleCov Rcov Formatter'
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 Rcov formatter could not be loaded'
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