public
Description: Simple Ruby 1.8/1.9 code comparison app
Homepage: http://codefluency.com
Clone URL: git://github.com/bruce/compare-1-9.git
Extensive styling
bruce (author)
Tue Jan 15 00:07:06 -0800 2008
commit  ca5ae8c4ec1fbbad20c4b1ab44df615f3356588e
tree    90aa940f5228652bf096aa1e701698170b94bd62
parent  a302dea818e946d54b97b673982b373ae921504f
...
 
 
1
2
3
4
 
 
 
 
5
6
7
...
1
2
3
4
5
 
6
7
8
9
10
11
12
0
@@ -1,7 +1,12 @@
0
+require 'paginator'
0
+
0
 class ComparisonsController < ApplicationController
0
   
0
   def index
0
- @comparisons = Comparison.find(:all)
0
+ @pager = Paginator.new(Comparison.count, 10) do |offset, per_page|
0
+ Comparison.find(:all, :include => :results, :limit => per_page, :offset => offset)
0
+ end
0
+ @page = @pager.page(params[:page])
0
   end
0
   
0
   def new
...
17
18
19
 
20
21
22
...
29
30
31
32
 
33
34
 
35
36
 
37
38
39
40
41
42
43
44
 
 
 
45
 
46
47
48
49
50
51
52
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
55
56
...
17
18
19
20
21
22
23
...
30
31
32
 
33
34
 
35
36
 
37
38
39
40
 
 
 
 
 
41
42
43
44
45
46
47
 
 
 
 
 
 
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
0
@@ -17,6 +17,7 @@ module ComparisonsHelper
0
     in_error = false
0
     lines.each_with_index do |line, offset|
0
       classes = ["line_#{offset + 1}"]
0
+ classes << "first-line" if offset == 0
0
       if options[:errors] && line =~ /^-:(\d+):/
0
         in_error = true
0
         classes << "code_error code_error_line_#{$1}"
0
@@ -29,28 +30,35 @@ module ComparisonsHelper
0
     output
0
   end
0
   
0
- def show_output(text)
0
+ def show_output(text, html_options={})
0
     if text.blank?
0
- content_tag(:td, 'No output', :class => :blank)
0
+ content_tag(:td, 'No output', :class => "#{html_options[:class]} blank")
0
     else
0
- content_tag(:td, format_output(text))
0
+ content_tag(:td, format_output(text), html_options={})
0
     end
0
   end
0
   
0
- def benchmark_info_for(comparison)
0
- if (errors = comparison.results.select { |r| !r.success? }).any?
0
- return content_tag(:span, "Error in #{errors.map(&:version).to_sentence}", :class => 'bad-result')
0
- end
0
- results = comparison.results.sort_by(&:real_time)
0
+ def benchmark_info_for(*results)
0
+ options = results.last.is_a?(Hash) ? results.pop : {}
0
+ results = results.sort_by(&:real_time)
0
     longest = results.last.real_time
0
+ has_errors = results.any? { |r| !r.success? }
0
     content_tag(:ul,
0
       results.map { |r|
0
- percent = r.real_time / longest * 100
0
- content_tag(:li, "#{r.version} <span class='time'>#{'%.8f' % r.real_time}s</span>",
0
- :class => (r.id == results.first.id ? 'winner' : 'loser'),
0
- :style => "width:#{percent}%;")
0
- }.join,
0
- :class => 'bars')
0
+ if !options[:only] || options[:only].id == r.id
0
+ if !r.success?
0
+ content_tag(:span, "Error#{options[:only] ? '' : ' in ' + r.version}", :class => 'bad-result')
0
+ else
0
+ percent = r.real_time / longest * 100
0
+ content_tag(:li, "#{r.version unless options[:only]} <span class='time'>#{'%.8f' % r.real_time}s</span>",
0
+ :class => (r.id == results.first.id ? 'winner' : 'loser'),
0
+ :style => "width:#{percent}%;")
0
+ end
0
+ else
0
+ nil
0
+ end
0
+ }.compact.join,
0
+ :class => "bars bars-#{has_errors ? 'with-errors' : 'without-errors'}")
0
   end
0
     
0
 end
...
7
8
9
10
 
11
12
13
...
53
54
55
56
57
58
59
60
61
62
63
64
 
 
65
66
67
68
69
 
 
 
 
 
 
 
 
 
70
71
72
...
7
8
9
 
10
11
12
13
...
53
54
55
 
 
 
 
 
 
 
 
 
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
0
@@ -7,7 +7,7 @@ class Comparison < ActiveRecord::Base
0
     '1.9' => '/usr/local/bin/ruby1.9'
0
   }
0
   
0
- has_many :results, :order => 'version asc'
0
+ has_many :results, :order => 'version asc', :dependent => :destroy
0
   
0
   validates_presence_of :name
0
   validates_presence_of :code
0
@@ -53,20 +53,22 @@ class Comparison < ActiveRecord::Base
0
         stdin.puts code
0
         stdin.close
0
       end
0
- %w(stdout stderr).each do |channel|
0
- output = eval "#{channel}.read.strip"
0
- case output
0
- when /[^[:print:]]/
0
- record.update("binary_#{channel}" => true)
0
- else
0
- record.update(channel => output)
0
- end
0
- end
0
+ save_output_from(:stdout, stdout, record)
0
+ save_output_from(:stderr, stderr, record)
0
       record.update(:benchmark => benchmark)
0
     end
0
     record.merge(:exit_code => status.exitstatus.to_i)
0
   end
0
   
0
+ def save_output_from(name, channel, record={})
0
+ case output = channel.read.strip
0
+ when /[^[:print:][:cntrl:]]/
0
+ record.update("binary_#{name}" => true)
0
+ else
0
+ record.update(name => output)
0
+ end
0
+ end
0
+
0
   def binary?(string)
0
     string =~ /[^[:print:]]/
0
   end
...
1
2
 
3
4
5
6
7
8
 
9
10
...
1
 
2
3
4
5
6
7
 
8
9
10
0
@@ -1,9 +1,9 @@
0
 <tr class='<%= cycle *%w(odd even) %>'>
0
- <td>
0
+ <td class='name'>
0
     <%= link_to comparison.name, comparison %>
0
     <% unless comparison.description.blank? %>
0
       <p class='description'><%= truncate(comparison.description) %></p>
0
     <% end %>
0
   </td>
0
- <td><%= benchmark_info_for comparison %></td>
0
+ <td class='performance'><%= benchmark_info_for(*comparison.results) %></td>
0
 </tr>
0
\ No newline at end of file
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
24
...
1
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
0
@@ -1,23 +1,25 @@
0
 <%= error_messages_for :comparison %>
0
 <% form_for @comparison, :html => {:multipart => true} do |f| %>
0
- <ul>
0
- <li>
0
- <label for='comparison_name'>Name:</label>
0
- <%= f.text_field :name %>
0
- </li>
0
- <li>
0
- <label for='comparison_description'>Description</label><br/>
0
- <%= f.text_area :description, :cols => 80, :rows => 5 %>
0
- </li>
0
- <li>
0
- <label for='comparison_code'>Code</label><br/>
0
- <%= f.text_area :code, :cols => 80, :rows => 5 %><br>
0
- <p>
0
- or upload a file:
0
- <%= f.file_field :file %>
0
- </p>
0
- </li>
0
- <p>The code will be executed on Ruby <%= Comparison::VERSIONS.keys.sort.to_sentence %>.</p>
0
- <%= submit_tag "Save" %>
0
- </ul>
0
+ <fieldset>
0
+ <ul>
0
+ <li>
0
+ <label for='comparison_name'>Name:</label>
0
+ <%= f.text_field :name %>
0
+ </li>
0
+ <li>
0
+ <label for='comparison_description'>Description</label><br/>
0
+ <%= f.text_field :description, :size => 80 %>
0
+ </li>
0
+ <li>
0
+ <label for='comparison_code'>Code</label><br/>
0
+ <%= f.text_area :code, :cols => 80, :rows => 5 %><br>
0
+ <p>
0
+ or upload a file:
0
+ <%= f.file_field :file %>
0
+ </p>
0
+ </li>
0
+ <p class='note'>The code will be executed on Ruby <%= Comparison::VERSIONS.keys.sort.to_sentence %>.</p>
0
+ <%= submit_tag "Save" %>
0
+ </ul>
0
+ </fieldset>
0
 <% end %>
0
\ No newline at end of file
...
1
 
 
 
 
 
 
 
2
3
4
...
 
1
2
3
4
5
6
7
8
9
10
0
@@ -1,3 +1,9 @@
0
-<h2>Edit `<%= @comparison.name %>'</h2>
0
+<h2>Editing &ldquo;<%= @comparison.name %>&rdquo;</h2>
0
+
0
+<ul class='actions'>
0
+ <li><%= link_to "All Comparisons", comparison_path, :class => 'icon up' %></li>
0
+ <li><%= link_to "View this", comparison_path, :class => 'icon show' %></li>
0
+ <li><%= link_to "Delete this", comparison_path, :method => :delete, :class => 'icon delete' %></li>
0
+</ul>
0
 
0
 <%= render :partial => 'form' %>
0
\ No newline at end of file
...
1
2
3
 
4
5
6
7
8
9
10
11
12
13
14
15
16
 
 
 
 
 
 
 
 
 
 
 
 
 
17
...
1
2
 
3
4
 
 
 
 
 
 
 
 
 
 
 
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
0
@@ -1,15 +1,17 @@
0
 <h2>Comparisons</h2>
0
 
0
-<p><%= link_to "New Comparison", new_comparison_path %></p>
0
+<ul class='actions'><li><%= link_to "Add Comparison", new_comparison_path, :class => 'add' %></li></ul>
0
 
0
-<table id='comparisons'>
0
- <thead>
0
- <tr>
0
- <th>Name</th>
0
- <th>Performance</th>
0
- </tr>
0
- </thead>
0
- <tbody>
0
- <%= render :partial => @comparisons %>
0
- </tbody>
0
-</table>
0
\ No newline at end of file
0
+<% if @page.items.any? %>
0
+ <table id='comparisons'>
0
+ <thead>
0
+ <tr>
0
+ <th>Name</th>
0
+ <th>Performance</th>
0
+ </tr>
0
+ </thead>
0
+ <tbody>
0
+ <%= render :partial => @page.items %>
0
+ </tbody>
0
+ </table>
0
+<% end %>
0
\ No newline at end of file
...
1
 
 
2
3
...
1
2
3
4
5
0
@@ -1,2 +1,4 @@
0
 <h2>New Comparison</h2>
0
+<p><%= link_to "All Comparisons", comparisons_path, :class => 'icon up' %></p>
0
+
0
 <%= render :partial => 'form' %>
0
\ No newline at end of file
...
1
2
3
4
5
6
 
 
 
 
 
7
8
9
10
11
12
 
13
14
15
 
16
17
18
19
20
21
 
 
 
 
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 
 
 
 
 
 
 
43
44
45
46
...
1
2
 
 
 
 
3
4
5
6
7
8
9
10
11
12
 
13
14
15
 
16
17
 
 
 
 
 
18
19
20
21
22
23
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
26
27
28
29
30
31
32
33
34
35
0
@@ -1,45 +1,34 @@
0
 <h2><%= @comparison.name %></h2>
0
 
0
-<%= link_to "All Comparisons", comparisons_path %>
0
-<%= link_to "Edit this Comparison", edit_comparison_path %>
0
-<%= link_to "Delete this Comparison", comparison_path, :method => :delete %>
0
-
0
+<ul class='actions'>
0
+ <li><%= link_to "All Comparisons", comparisons_path, :class => 'icon up' %></li>
0
+ <li><%= link_to "Edit this", edit_comparison_path, :class => 'icon edit' %></li>
0
+ <li><%= link_to "Delete this", comparison_path, :method => :delete, :class => 'icon delete' %></li>
0
+</ul>
0
 
0
 <% unless @comparison.description.blank? %>
0
   <div id='description'><%= textilize @comparison.description %></div>
0
 <% end %>
0
 
0
-<p><%= link_to "Show Code", '', :id => 'show-code' %></p>
0
+<p><%= link_to "Show Code", '', :id => 'show-code', :class => 'icon show-code' %></p>
0
 <%= format_code @comparison.code, :id => :code, :style => 'display:none;' %>
0
 
0
-<table>
0
+<table id='comparison'>
0
   <thead>
0
- <tr id='versions'>
0
- <th class='hide'>&nbsp;</th>
0
- <% @comparison.results.each do |result| %>
0
- <th><%= result.version %></th>
0
- <% end %>
0
+ <tr>
0
+ <th>Version</th>
0
+ <th>Output</th>
0
+ <th>Errors</th>
0
     </tr>
0
   </thead>
0
   <tbody>
0
- <tr id='exit_code'>
0
- <th>Exit Code</th>
0
- <% @comparison.results.each do |result| %>
0
- <td class='<%= result.exit_code == 0 ? 'good' : 'bad' %>'><%= result.exit_code %></td>
0
- <% end %>
0
- </tr>
0
- <tr id='stdout'>
0
- <th>Standard Out</th>
0
- <% @comparison.results.each do |result| %>
0
- <%= show_output result.stdout %>
0
- <% end %>
0
- </tr>
0
- <tr id='stderr'>
0
- <th>Standard Error</th>
0
- <% @comparison.results.each do |result| %>
0
- <%= show_output result.stderr %>
0
- <% end %>
0
- </tr>
0
+ <% @comparison.results.each do |result| %>
0
+ <tr>
0
+ <td class='version <%= result.success? ? 'success' : 'failure' %>'><%= result.version %><%= benchmark_info_for(*@comparison.results.dup.push(:only => result)) %></td>
0
+ <%= show_output result.stdout, :class => 'stdout' %>
0
+ <%= show_output result.stderr, :class => 'stdout' %>
0
+ </tr>
0
+ <% end %>
0
   </tbody>
0
 </table>
0
       
0
\ No newline at end of file
...
4
5
6
7
8
9
10
 
 
 
 
 
 
 
 
 
 
 
11
12
13
...
4
5
6
 
 
 
 
7
8
9
10
11
12
13
14
15
16
17
18
19
20
0
@@ -4,10 +4,17 @@ namespace :benchmarks do
0
     files = Dir[File.dirname(__FILE__) << "/benchmark/*.rb"]
0
     files.each do |file|
0
       puts "Running `#{File.basename(file)}'..."
0
- Comparison.create(
0
- :name => File.basename(file),
0
- :code => File.read(file)
0
- )
0
+ item = nil
0
+ begin
0
+ item = Comparison.create(
0
+ :name => File.basename(file),
0
+ :code => File.read(file),
0
+ :description => "Benchmark from the Ruby 1.9 repository"
0
+ )
0
+ rescue => e
0
+ item.destroy unless item.new_record?
0
+ puts "... could not execute (#{e})"
0
+ end
0
     end
0
   end
0
   
...
2463
2464
2465