git-commit-notifier 0.8.0 → 0.8.1
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.
- data/LICENSE +1 -1
 - data/README.textile +20 -5
 - data/Rakefile +40 -20
 - data/VERSION +1 -1
 - data/bin/git-commit-notifier +8 -1
 - data/config/git-notifier-config.yml.sample +41 -15
 - data/git-commit-notifier.gemspec +50 -24
 - data/lib/commit_hook.rb +104 -74
 - data/lib/diff_to_html.rb +120 -52
 - data/lib/emailer.rb +43 -22
 - data/lib/git.rb +36 -26
 - data/lib/logger.rb +48 -0
 - data/lib/result_processor.rb +9 -5
 - data/{test → spec}/fixtures/existing_file_one_line.txt +0 -0
 - data/{test → spec}/fixtures/git-notifier-group-email-by-push.yml +2 -0
 - data/{test → spec}/fixtures/git-notifier-ignore-merge.yml +0 -0
 - data/{test → spec}/fixtures/git-notifier-with-merge.yml +0 -0
 - data/{test → spec}/fixtures/git_log +0 -0
 - data/{test → spec}/fixtures/git_show_055850e7d925110322b8db4e17c3b840d76e144c +0 -0
 - data/{test → spec}/fixtures/git_show_51b986619d88f7ba98be7d271188785cbbb541a0 +0 -0
 - data/{test → spec}/fixtures/git_show_a4629e707d80a5769f7a71ca6ed9471015e14dc9 +0 -0
 - data/{test → spec}/fixtures/git_show_dce6ade4cdc2833b53bd600ef10f9bce83c7102d +0 -0
 - data/{test → spec}/fixtures/git_show_e28ad77bba0574241e6eb64dfd0c1291b221effe +0 -0
 - data/spec/fixtures/git_show_ff037a73fc1094455e7bbf506171a3f3cf873ae6 +18 -0
 - data/{test → spec}/fixtures/new_file_one_line.txt +0 -0
 - data/spec/lib/commit_hook_spec.rb +88 -0
 - data/spec/lib/diff_to_html_spec.rb +168 -0
 - data/spec/lib/emailer_spec.rb +102 -0
 - data/spec/lib/git_spec.rb +93 -0
 - data/spec/lib/logger_spec.rb +63 -0
 - data/spec/lib/result_processor_spec.rb +102 -0
 - data/{test/test_helper.rb → spec/spec_helper.rb} +14 -12
 - data/template/email.html.erb +2 -2
 - data/template/styles.css +2 -1
 - metadata +110 -31
 - data/test/unit/test_commit_hook.rb +0 -43
 - data/test/unit/test_diff_to_html.rb +0 -160
 - data/test/unit/test_result_processor.rb +0 -95
 
    
        data/lib/logger.rb
    ADDED
    
    | 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'tmpdir'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class Logger
         
     | 
| 
      
 4 
     | 
    
         
            +
              DEFAULT_LOG_DIRECTORY = Dir.tmpdir.freeze
         
     | 
| 
      
 5 
     | 
    
         
            +
              LOG_NAME = 'git-commit-notifier.log'.freeze
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              attr_reader :log_directory
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def initialize(config)
         
     | 
| 
      
 10 
     | 
    
         
            +
                @enabled = !!(config['debug'] && config['debug']['enabled'])
         
     | 
| 
      
 11 
     | 
    
         
            +
                @log_directory = debug? ? (config['debug']['log_directory'] || DEFAULT_LOG_DIRECTORY) : nil
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def debug?
         
     | 
| 
      
 15 
     | 
    
         
            +
                @enabled
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              def log_path
         
     | 
| 
      
 19 
     | 
    
         
            +
                return nil unless debug?
         
     | 
| 
      
 20 
     | 
    
         
            +
                File.join(log_directory, LOG_NAME)
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def debug(msg)
         
     | 
| 
      
 24 
     | 
    
         
            +
                return unless debug?
         
     | 
| 
      
 25 
     | 
    
         
            +
                File.open(log_path, 'a') do |f|
         
     | 
| 
      
 26 
     | 
    
         
            +
                  f.puts msg
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def file(file_path)
         
     | 
| 
      
 31 
     | 
    
         
            +
                return unless debug?
         
     | 
| 
      
 32 
     | 
    
         
            +
                orig_dest_name = File.join(log_directory, File.basename(file_path))
         
     | 
| 
      
 33 
     | 
    
         
            +
                dest_name = orig_dest_name
         
     | 
| 
      
 34 
     | 
    
         
            +
                counter = 1
         
     | 
| 
      
 35 
     | 
    
         
            +
                while File.exists?(dest_name)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  counter += 1
         
     | 
| 
      
 37 
     | 
    
         
            +
                  dest_name = "#{orig_dest_name}.#{counter}"
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
                debug("Save file #{file_path} for debugging purposes to #{dest_name}")
         
     | 
| 
      
 40 
     | 
    
         
            +
                File.copy(file_path, dest_name)
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            __END__
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
             vim: tabstop=2:expandtab:shiftwidth=2
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
    
        data/lib/result_processor.rb
    CHANGED
    
    | 
         @@ -12,6 +12,14 @@ class ResultProcessor 
     | 
|
| 
       12 
12 
     | 
    
         
             
                [array_of_lines(@result[:removal]), array_of_lines(@result[:addition])]
         
     | 
| 
       13 
13 
     | 
    
         
             
              end
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
      
 15 
     | 
    
         
            +
              def length_in_chars(diff)
         
     | 
| 
      
 16 
     | 
    
         
            +
                diff.inject(0) do |length, s|
         
     | 
| 
      
 17 
     | 
    
         
            +
                  token = s[:token]
         
     | 
| 
      
 18 
     | 
    
         
            +
                  token_length = token.respond_to?(:jlength) ? token.jlength : token.length
         
     | 
| 
      
 19 
     | 
    
         
            +
                  length + token_length
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
       15 
23 
     | 
    
         
             
              private
         
     | 
| 
       16 
24 
     | 
    
         | 
| 
       17 
25 
     | 
    
         
             
              def initialize(diff)
         
     | 
| 
         @@ -46,15 +54,11 @@ class ResultProcessor 
     | 
|
| 
       46 
54 
     | 
    
         
             
                @diff.insert(position, { :action => :discard_b, :token => token} )
         
     | 
| 
       47 
55 
     | 
    
         
             
              end
         
     | 
| 
       48 
56 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
              def length_in_chars(diff)
         
     | 
| 
       50 
     | 
    
         
            -
                diff.inject(0) { |length, s| length + s[:token].size}
         
     | 
| 
       51 
     | 
    
         
            -
              end
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
57 
     | 
    
         
             
              def filter_replaced_lines
         
     | 
| 
       54 
58 
     | 
    
         
             
                # if a block is replaced by an other one, lcs-diff will find even the single common word between the old and the new content
         
     | 
| 
       55 
59 
     | 
    
         
             
                # no need for intelligent diff in this case, simply show the removed and the added block with no highlighting
         
     | 
| 
       56 
60 
     | 
    
         
             
                # rule: if less than 33% of a block is not a match, we don't need intelligent diff for that block
         
     | 
| 
       57 
     | 
    
         
            -
                match_length = length_in_chars(@diff.select { |d| d[:action] == :match})
         
     | 
| 
      
 61 
     | 
    
         
            +
                match_length = length_in_chars(@diff.select { |d| d[:action] == :match })
         
     | 
| 
       58 
62 
     | 
    
         
             
                total_length = length_in_chars(@diff)
         
     | 
| 
       59 
63 
     | 
    
         | 
| 
       60 
64 
     | 
    
         
             
                if total_length.to_f / match_length > 3.3
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            commit ff037a73fc1094455e7bbf506171a3f3cf873ae6
         
     | 
| 
      
 2 
     | 
    
         
            +
            Author: Mokevnin Kirill <mokevnin@gmail.com>
         
     | 
| 
      
 3 
     | 
    
         
            +
            Date:   Tue Oct 26 15:31:13 2010 +0400
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                remove debug put
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            diff --git a/app/models/user.rb b/app/models/user.rb
         
     | 
| 
      
 8 
     | 
    
         
            +
            index ac9399f..ea2e351 100644
         
     | 
| 
      
 9 
     | 
    
         
            +
            --- a/app/models/user.rb
         
     | 
| 
      
 10 
     | 
    
         
            +
            +++ b/app/models/user.rb
         
     | 
| 
      
 11 
     | 
    
         
            +
            @@ -226,7 +226,6 @@ class User < ActiveRecord::Base
         
     | 
| 
      
 12 
     | 
    
         
            +
                 all_stats.keys.each do |type|
         
     | 
| 
      
 13 
     | 
    
         
            +
                   all_stats[type].each do |st|
         
     | 
| 
      
 14 
     | 
    
         
            +
                     stat_line = {type => st[:value]}
         
     | 
| 
      
 15 
     | 
    
         
            +
            -        puts "type #{type} st #{st}"
         
     | 
| 
      
 16 
     | 
    
         
            +
                     if results[st[:shift]]
         
     | 
| 
      
 17 
     | 
    
         
            +
                       results[st[:shift]].merge!(stat_line)
         
     | 
| 
      
 18 
     | 
    
         
            +
                     else
         
     | 
| 
         
            File without changes
         
     | 
| 
         @@ -0,0 +1,88 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path('../../spec_helper', __FILE__)
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'commit_hook'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            describe CommitHook do
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              it "should ignore merge" do
         
     | 
| 
      
 7 
     | 
    
         
            +
                # 4 commits, one email for each of them, without merge
         
     | 
| 
      
 8 
     | 
    
         
            +
                run_with_config('spec/fixtures/git-notifier-ignore-merge.yml', 4)
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              it "should hook with merge" do
         
     | 
| 
      
 12 
     | 
    
         
            +
                # 5 commits, one email for each of them, with merge mail
         
     | 
| 
      
 13 
     | 
    
         
            +
                run_with_config('spec/fixtures/git-notifier-with-merge.yml', 5)
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              it "should hook group email by push" do
         
     | 
| 
      
 17 
     | 
    
         
            +
                # 1 commit for the push, all commits in the one message
         
     | 
| 
      
 18 
     | 
    
         
            +
                run_with_config('spec/fixtures/git-notifier-group-email-by-push.yml', 1)
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              def run_with_config(config, times)
         
     | 
| 
      
 22 
     | 
    
         
            +
                expect_repository_access
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                emailer = mock!.send.times(times).subject
         
     | 
| 
      
 25 
     | 
    
         
            +
                mock(Emailer).new(anything, anything) { emailer }.times(times)
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                mock(CommitHook).info(/Sending mail/)
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                any_instance_of(DiffToHtml, :check_handled_commits => lambda { |commits, branch| commits })
         
     | 
| 
      
 30 
     | 
    
         
            +
                CommitHook.run config, REVISIONS.first, REVISIONS.last, 'refs/heads/master'
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              def test_commit_from
         
     | 
| 
      
 34 
     | 
    
         
            +
                # 1 commit with a from: adress
         
     | 
| 
      
 35 
     | 
    
         
            +
                expect_repository_access
         
     | 
| 
      
 36 
     | 
    
         
            +
                emailer = mock!.send.subject
         
     | 
| 
      
 37 
     | 
    
         
            +
                mock(Emailer).new(anything, hash_including(:from_address => "max@example.com")) { emailer }
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                CommitHook.run 'spec/fixtures/git-notifier-group-email-by-push.yml', REVISIONS.first, REVISIONS.last, 'refs/heads/master'
         
     | 
| 
      
 40 
     | 
    
         
            +
               end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              def expect_repository_access
         
     | 
| 
      
 43 
     | 
    
         
            +
                mock(Git).log(REVISIONS.first, REVISIONS.last) { IO.read(FIXTURES_PATH + 'git_log') }
         
     | 
| 
      
 44 
     | 
    
         
            +
                mock(Git).mailing_list_address { 'recipient@test.com' }
         
     | 
| 
      
 45 
     | 
    
         
            +
                REVISIONS.each do |rev|
         
     | 
| 
      
 46 
     | 
    
         
            +
                  mock(Git).show(rev) { IO.read(FIXTURES_PATH + "git_show_#{rev}") }
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              describe :logger do
         
     | 
| 
      
 51 
     | 
    
         
            +
                it "should be nstance of logger" do
         
     | 
| 
      
 52 
     | 
    
         
            +
                  stub(CommitHook).config { {} }
         
     | 
| 
      
 53 
     | 
    
         
            +
                  CommitHook.logger.should be_kind_of(Logger)
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              describe :show_error do
         
     | 
| 
      
 58 
     | 
    
         
            +
                it "should write error to stderr" do
         
     | 
| 
      
 59 
     | 
    
         
            +
                  mock($stderr).puts("\n").times(2)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  mock($stderr).puts(/GIT\sNOTIFIER\sPROBLEM/).times(2)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  mock($stderr).puts('yes')
         
     | 
| 
      
 62 
     | 
    
         
            +
                  CommitHook.show_error('yes')
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
              describe :info do
         
     | 
| 
      
 67 
     | 
    
         
            +
                it "should write to and flush stdout" do
         
     | 
| 
      
 68 
     | 
    
         
            +
                  mock($stdout).puts('msg')
         
     | 
| 
      
 69 
     | 
    
         
            +
                  mock($stdout).flush
         
     | 
| 
      
 70 
     | 
    
         
            +
                  CommitHook.info('msg')
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              describe :run do
         
     | 
| 
      
 75 
     | 
    
         
            +
                it "should report error when no recipients specified" do
         
     | 
| 
      
 76 
     | 
    
         
            +
                  mock(File).exists?(:noconfig) { false }
         
     | 
| 
      
 77 
     | 
    
         
            +
                  mock(Git).mailing_list_address { nil }
         
     | 
| 
      
 78 
     | 
    
         
            +
                  mock(CommitHook).show_error(/recipient/)
         
     | 
| 
      
 79 
     | 
    
         
            +
                  CommitHook.run(:noconfig, :rev1, :rev2, 'master')
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            __END__
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
             vim: tabstop=2 expandtab shiftwidth=2
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,168 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path('../../spec_helper', __FILE__)
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'diff_to_html'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'git'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'hpricot'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            describe DiffToHtml do
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              describe :lines_are_sequential? do
         
     | 
| 
      
 10 
     | 
    
         
            +
                before(:all) do
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @diff_to_html = DiffToHtml.new
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                it "should be true if left line numbers are sequential" do
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @diff_to_html.lines_are_sequential?({
         
     | 
| 
      
 16 
     | 
    
         
            +
                    :added => 2,
         
     | 
| 
      
 17 
     | 
    
         
            +
                    :removed => 2
         
     | 
| 
      
 18 
     | 
    
         
            +
                  }, {
         
     | 
| 
      
 19 
     | 
    
         
            +
                    :added => 3,
         
     | 
| 
      
 20 
     | 
    
         
            +
                    :removed => 6
         
     | 
| 
      
 21 
     | 
    
         
            +
                  }).should be_true
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                it "should be true if right line numbers are sequential" do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @diff_to_html.lines_are_sequential?({
         
     | 
| 
      
 26 
     | 
    
         
            +
                    :added => 2,
         
     | 
| 
      
 27 
     | 
    
         
            +
                    :removed => 2
         
     | 
| 
      
 28 
     | 
    
         
            +
                  }, {
         
     | 
| 
      
 29 
     | 
    
         
            +
                    :added => 7,
         
     | 
| 
      
 30 
     | 
    
         
            +
                    :removed => 3
         
     | 
| 
      
 31 
     | 
    
         
            +
                  }).should be_true
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                it "should be false unless line numbers are sequential" do
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @diff_to_html.lines_are_sequential?({
         
     | 
| 
      
 36 
     | 
    
         
            +
                    :added => 2,
         
     | 
| 
      
 37 
     | 
    
         
            +
                    :removed => 2
         
     | 
| 
      
 38 
     | 
    
         
            +
                  }, {
         
     | 
| 
      
 39 
     | 
    
         
            +
                    :added => 4,
         
     | 
| 
      
 40 
     | 
    
         
            +
                    :removed => 6
         
     | 
| 
      
 41 
     | 
    
         
            +
                  }).should be_false
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                it "should be true if left line numbers are sequential (right are nil)" do
         
     | 
| 
      
 45 
     | 
    
         
            +
                  @diff_to_html.lines_are_sequential?({
         
     | 
| 
      
 46 
     | 
    
         
            +
                    :added => 2,
         
     | 
| 
      
 47 
     | 
    
         
            +
                    :removed => 2
         
     | 
| 
      
 48 
     | 
    
         
            +
                  }, {
         
     | 
| 
      
 49 
     | 
    
         
            +
                    :added => 3,
         
     | 
| 
      
 50 
     | 
    
         
            +
                    :removed => nil
         
     | 
| 
      
 51 
     | 
    
         
            +
                  }).should be_true
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                it "should be true if right line numbers are sequential (left are nil)" do
         
     | 
| 
      
 55 
     | 
    
         
            +
                  @diff_to_html.lines_are_sequential?({
         
     | 
| 
      
 56 
     | 
    
         
            +
                    :added => nil,
         
     | 
| 
      
 57 
     | 
    
         
            +
                    :removed => 2
         
     | 
| 
      
 58 
     | 
    
         
            +
                  }, {
         
     | 
| 
      
 59 
     | 
    
         
            +
                    :added => 7,
         
     | 
| 
      
 60 
     | 
    
         
            +
                    :removed => 3
         
     | 
| 
      
 61 
     | 
    
         
            +
                  }).should be_true
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                it "should be false unless line numbers are sequential (nils)" do
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @diff_to_html.lines_are_sequential?({
         
     | 
| 
      
 66 
     | 
    
         
            +
                    :added => nil,
         
     | 
| 
      
 67 
     | 
    
         
            +
                    :removed => nil
         
     | 
| 
      
 68 
     | 
    
         
            +
                  }, {
         
     | 
| 
      
 69 
     | 
    
         
            +
                    :added => 4,
         
     | 
| 
      
 70 
     | 
    
         
            +
                    :removed => 6
         
     | 
| 
      
 71 
     | 
    
         
            +
                  }).should be_false
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
              describe :unique_commits_per_branch? do
         
     | 
| 
      
 76 
     | 
    
         
            +
                it "should be false unless specified in config" do
         
     | 
| 
      
 77 
     | 
    
         
            +
                  diff = DiffToHtml.new(nil, {})
         
     | 
| 
      
 78 
     | 
    
         
            +
                  diff.should_not be_unique_commits_per_branch
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                it "should be false if specified as false in config" do
         
     | 
| 
      
 82 
     | 
    
         
            +
                  diff = DiffToHtml.new(nil, { 'unique_commits_per_branch' => false })
         
     | 
| 
      
 83 
     | 
    
         
            +
                  diff.should_not be_unique_commits_per_branch
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                it "should be true if specified as true in config" do
         
     | 
| 
      
 87 
     | 
    
         
            +
                  diff = DiffToHtml.new(nil, { 'unique_commits_per_branch' => true })
         
     | 
| 
      
 88 
     | 
    
         
            +
                  diff.should be_unique_commits_per_branch
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
              end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
              describe :get_previous_commits do
         
     | 
| 
      
 93 
     | 
    
         
            +
                it "should read and parse previous file if it exists" do
         
     | 
| 
      
 94 
     | 
    
         
            +
                  fn = DiffToHtml::HANDLED_COMMITS_FILE
         
     | 
| 
      
 95 
     | 
    
         
            +
                  diff = DiffToHtml.new
         
     | 
| 
      
 96 
     | 
    
         
            +
                  mock(File).exists?(fn) { true }
         
     | 
| 
      
 97 
     | 
    
         
            +
                  mock(IO).read(fn) { "a\nb" }
         
     | 
| 
      
 98 
     | 
    
         
            +
                  diff.get_previous_commits(fn).should == %w[a b]
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
              end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
              it "multiple commits" do
         
     | 
| 
      
 103 
     | 
    
         
            +
                mock(Git).log(REVISIONS.first, REVISIONS.last) { IO.read(FIXTURES_PATH + 'git_log') }
         
     | 
| 
      
 104 
     | 
    
         
            +
                REVISIONS.each do |rev|
         
     | 
| 
      
 105 
     | 
    
         
            +
                  mock(Git).show(rev) { IO.read(FIXTURES_PATH + 'git_show_' + rev) }
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                diff = DiffToHtml.new
         
     | 
| 
      
 109 
     | 
    
         
            +
                mock(diff).check_handled_commits(anything, 'master') { |commits, branch| commits }
         
     | 
| 
      
 110 
     | 
    
         
            +
                diff.diff_between_revisions REVISIONS.first, REVISIONS.last, 'testproject', 'master'
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                diff.result.should have(5).commits # one result for each of the commits
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                diff.result.each do |html|
         
     | 
| 
      
 115 
     | 
    
         
            +
                  html.should_not be_include('@@') # diff correctly processed
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                # first commit
         
     | 
| 
      
 119 
     | 
    
         
            +
                hp = Hpricot diff.result.first[:html_content]
         
     | 
| 
      
 120 
     | 
    
         
            +
                (hp/"table").should have(2).tables # 2 files updated - one table for each of the files
         
     | 
| 
      
 121 
     | 
    
         
            +
                (hp/"table/tr/").each do |td|
         
     | 
| 
      
 122 
     | 
    
         
            +
                  if td.inner_html == "require 'iconv'"
         
     | 
| 
      
 123 
     | 
    
         
            +
                    # first added line in changeset a4629e707d80a5769f7a71ca6ed9471015e14dc9
         
     | 
| 
      
 124 
     | 
    
         
            +
                    td.parent.search('td')[0].inner_text.should == '' # left
         
     | 
| 
      
 125 
     | 
    
         
            +
                    td.parent.search('td')[1].inner_text.should == '2' # right
         
     | 
| 
      
 126 
     | 
    
         
            +
                    td.parent.search('td')[2].inner_html.should == "require 'iconv'" # change
         
     | 
| 
      
 127 
     | 
    
         
            +
                  end
         
     | 
| 
      
 128 
     | 
    
         
            +
                end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                # second commit
         
     | 
| 
      
 131 
     | 
    
         
            +
                hp = Hpricot diff.result[1][:html_content]
         
     | 
| 
      
 132 
     | 
    
         
            +
                (hp/"table").should have(1).table # 1 file updated
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                # third commit - dce6ade4cdc2833b53bd600ef10f9bce83c7102d
         
     | 
| 
      
 135 
     | 
    
         
            +
                hp = Hpricot diff.result[2][:html_content]
         
     | 
| 
      
 136 
     | 
    
         
            +
                (hp/"table").should have(6).tables # 6 files updated
         
     | 
| 
      
 137 
     | 
    
         
            +
                (hp/"h2")[1].inner_text.should == 'Added binary file railties/doc/guides/source/images/icons/callouts/11.png'
         
     | 
| 
      
 138 
     | 
    
         
            +
                (hp/"h2")[2].inner_text.should == 'Deleted binary file railties/doc/guides/source/icons/up.png'
         
     | 
| 
      
 139 
     | 
    
         
            +
                (hp/"h2")[3].inner_text.should == 'Deleted file railties/doc/guides/source/icons/README'
         
     | 
| 
      
 140 
     | 
    
         
            +
                (hp/"h2")[4].inner_text.should == 'Added file railties/doc/guides/source/images/icons/README'
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                # fourth commit - 51b986619d88f7ba98be7d271188785cbbb541a0
         
     | 
| 
      
 143 
     | 
    
         
            +
                hp = Hpricot diff.result[3][:html_content]
         
     | 
| 
      
 144 
     | 
    
         
            +
                (hp/"table").should have(3).tables # 3 files updated
         
     | 
| 
      
 145 
     | 
    
         
            +
                (hp/"table/tr/").each do |td|
         
     | 
| 
      
 146 
     | 
    
         
            +
                  if td.inner_html =~ /create_btn/
         
     | 
| 
      
 147 
     | 
    
         
            +
                    cols = td.parent.search('td')
         
     | 
| 
      
 148 
     | 
    
         
            +
                    ['405', '408', ''].should be_include(cols[0].inner_text) # line 405 changed
         
     | 
| 
      
 149 
     | 
    
         
            +
                  end
         
     | 
| 
      
 150 
     | 
    
         
            +
                end
         
     | 
| 
      
 151 
     | 
    
         
            +
              end
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
              it "should get good diff when new branch created" do
         
     | 
| 
      
 154 
     | 
    
         
            +
                first_rev, last_rev = %w[ 0000000000000000000000000000000000000000 9b15cebcc5434e27c00a4a2acea43509f9faea21 ]
         
     | 
| 
      
 155 
     | 
    
         
            +
                mock(Git).branch_commits('rvm') { %w[ ff037a73fc1094455e7bbf506171a3f3cf873ae6 ] }
         
     | 
| 
      
 156 
     | 
    
         
            +
                %w[ ff037a73fc1094455e7bbf506171a3f3cf873ae6 ].each do |rev|
         
     | 
| 
      
 157 
     | 
    
         
            +
                  mock(Git).show(rev) { IO.read(FIXTURES_PATH + 'git_show_' + rev) }
         
     | 
| 
      
 158 
     | 
    
         
            +
                end
         
     | 
| 
      
 159 
     | 
    
         
            +
                diff = DiffToHtml.new
         
     | 
| 
      
 160 
     | 
    
         
            +
                mock(diff).check_handled_commits(anything, 'rvm') { |commits, branch| commits }
         
     | 
| 
      
 161 
     | 
    
         
            +
                diff.diff_between_revisions(first_rev, last_rev, 'tm-admin', 'rvm')
         
     | 
| 
      
 162 
     | 
    
         
            +
                diff.result.should have(1).commit
         
     | 
| 
      
 163 
     | 
    
         
            +
                hp = Hpricot diff.result.first[:html_content]
         
     | 
| 
      
 164 
     | 
    
         
            +
                (hp/"table").should have(1).table
         
     | 
| 
      
 165 
     | 
    
         
            +
                (hp/"tr.r").should have(1).row
         
     | 
| 
      
 166 
     | 
    
         
            +
              end
         
     | 
| 
      
 167 
     | 
    
         
            +
            end
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,102 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path('../../spec_helper', __FILE__)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'erb'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'emailer'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            describe Emailer do
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              describe :new do
         
     | 
| 
      
 9 
     | 
    
         
            +
                it "should assign config if given" do
         
     | 
| 
      
 10 
     | 
    
         
            +
                  Emailer.new({:a => :b}).config[:a].should == :b
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                it "should use empty hash unless config given" do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  cfg = Emailer.new(false).config
         
     | 
| 
      
 15 
     | 
    
         
            +
                  cfg.should be_kind_of(Hash)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  cfg.should be_empty
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                it "should not generate message from template" do
         
     | 
| 
      
 20 
     | 
    
         
            +
                  any_instance_of(Emailer) do |emailer|
         
     | 
| 
      
 21 
     | 
    
         
            +
                    dont_allow(emailer).generate_message
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  Emailer.new({})
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                it "should assign parameters from options" do
         
     | 
| 
      
 27 
     | 
    
         
            +
                  options = {}
         
     | 
| 
      
 28 
     | 
    
         
            +
                  Emailer::PARAMETERS.each do |name|
         
     | 
| 
      
 29 
     | 
    
         
            +
                    options[name.to_sym] = Faker::Lorem.sentence
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                  emailer = Emailer.new({}, options)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  options.each_pair do |key, value|
         
     | 
| 
      
 33 
     | 
    
         
            +
                    emailer.instance_variable_get("@#{key}").should == value
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
              describe :stylesheet_string do
         
     | 
| 
      
 39 
     | 
    
         
            +
                it "should return default stylesheet if custom is not provided" do
         
     | 
| 
      
 40 
     | 
    
         
            +
                  emailer = Emailer.new({})
         
     | 
| 
      
 41 
     | 
    
         
            +
                  mock(IO).read(Emailer::DEFAULT_STYLESHEET_PATH) { 'ok' }
         
     | 
| 
      
 42 
     | 
    
         
            +
                  emailer.stylesheet_string.should == 'ok'
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                it "should return custom stylesheet if custom is provided" do
         
     | 
| 
      
 46 
     | 
    
         
            +
                  emailer = Emailer.new({'stylesheet' => '/path/to/custom/stylesheet'})
         
     | 
| 
      
 47 
     | 
    
         
            +
                  mock(IO).read('/path/to/custom/stylesheet') { 'ok' }
         
     | 
| 
      
 48 
     | 
    
         
            +
                  dont_allow(IO).read(Emailer::DEFAULT_STYLESHEET_PATH)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  emailer.stylesheet_string.should == 'ok'
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              describe :generate_message do
         
     | 
| 
      
 54 
     | 
    
         
            +
                it "should generate html" do
         
     | 
| 
      
 55 
     | 
    
         
            +
                  options = {}
         
     | 
| 
      
 56 
     | 
    
         
            +
                  Emailer::PARAMETERS.each do |name|
         
     | 
| 
      
 57 
     | 
    
         
            +
                    options[name.to_sym] = Faker::Lorem.sentence
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  emailer = Emailer.new({}, options)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  emailer.generate_message
         
     | 
| 
      
 61 
     | 
    
         
            +
                  emailer.instance_variable_get(:@html).should match(/html/)
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
              describe :template do
         
     | 
| 
      
 66 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 67 
     | 
    
         
            +
                  Emailer.reset_template
         
     | 
| 
      
 68 
     | 
    
         
            +
                  mock(IO).read(Emailer::TEMPLATE) { 'erb' }
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                it "should respond to result" do
         
     | 
| 
      
 72 
     | 
    
         
            +
                  Emailer.template.should respond_to(:result)
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                it "should return Erubis template if Erubis installed" do
         
     | 
| 
      
 76 
     | 
    
         
            +
                  mock(Emailer).require('erubis')
         
     | 
| 
      
 77 
     | 
    
         
            +
                  dont_allow(Emailer).require('erb')
         
     | 
| 
      
 78 
     | 
    
         
            +
                  unless defined?(Erubis)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    module Erubis
         
     | 
| 
      
 80 
     | 
    
         
            +
                      class Eruby
         
     | 
| 
      
 81 
     | 
    
         
            +
                        def initialize(erb)
         
     | 
| 
      
 82 
     | 
    
         
            +
                        end
         
     | 
| 
      
 83 
     | 
    
         
            +
                      end
         
     | 
| 
      
 84 
     | 
    
         
            +
                    end
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
                  mock.proxy(Erubis::Eruby).new('erb')
         
     | 
| 
      
 87 
     | 
    
         
            +
                  Emailer.template.should be_kind_of(Erubis::Eruby)
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                it "should return ERB template unless Erubis installed" do
         
     | 
| 
      
 91 
     | 
    
         
            +
                  mock(Emailer).require('erubis') { raise LoadError.new('erubis') }
         
     | 
| 
      
 92 
     | 
    
         
            +
                  mock(Emailer).require('erb')
         
     | 
| 
      
 93 
     | 
    
         
            +
                  mock.proxy(ERB).new('erb')
         
     | 
| 
      
 94 
     | 
    
         
            +
                  Emailer.template.should be_kind_of(ERB)
         
     | 
| 
      
 95 
     | 
    
         
            +
                end
         
     | 
| 
      
 96 
     | 
    
         
            +
              end
         
     | 
| 
      
 97 
     | 
    
         
            +
            end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            __END__
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
             vim: tabstop=2 expandtab shiftwidth=2
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     |