linebyline 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
@@ -0,0 +1,5 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - ruby-head
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "bundler"
10
+ gem "jeweler", "~> 1.8.4"
11
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Julik Tarkhanov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,49 @@
1
+ = linebyline
2
+
3
+ Facilitates the comparison of files and IO buffers in tests. It will report the exact differences per line and character offset, it will report if
4
+ lines are too short or too long, and so on.
5
+
6
+ To use, include it in Minitest or Test::Unit
7
+
8
+ include LineByLine::Assertions
9
+
10
+ # ... and in one of your tests
11
+ def test_outputs_same
12
+ ref = File.open('ref_data.txt')
13
+ out = File.open('my_output.txt')
14
+ assert_same_buffer ref, out
15
+ end
16
+
17
+ The Assertions module expects the following methods on the object it is included into:
18
+
19
+ flunk(message)
20
+ assert(boolean)
21
+
22
+ so you can retrofit it to your Testing Framework Du Jour. Or you can include LineByLine itself,
23
+ and then use +compare_buffer!+ like so:
24
+
25
+ include LineByLine
26
+
27
+ # ... more tests
28
+ begin
29
+ compare_buffers! ref, out
30
+ rescue LineByLine::NotSame => mismatch
31
+ fail_test mismatch.message
32
+ end
33
+
34
+
35
+ == Contributing to linebyline
36
+
37
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
38
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
39
+ * Fork the project.
40
+ * Start a feature/bugfix branch.
41
+ * Commit and push until you are happy with your contribution.
42
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
43
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
44
+
45
+ == Copyright
46
+
47
+ Copyright (c) 2013 Julik Tarkhanov. See LICENSE.txt for
48
+ further details.
49
+
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ Bundler.setup(:default, :development)
6
+
7
+ require 'rake'
8
+ require 'jeweler'
9
+ require './lib/linebyline'
10
+
11
+ Jeweler::Tasks.new do |gem|
12
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
13
+ gem.name = "linebyline"
14
+ gem.version = LineByLine::VERSION
15
+ gem.homepage = "http://github.com/julik/linebyline"
16
+ gem.license = "MIT"
17
+ gem.summary = %Q{ Comparse two passed IO objects line by line (useful for tests) }
18
+ gem.description = %Q{ Can be used for comparing long outputs to references }
19
+ gem.email = "me@julik.nl"
20
+ gem.authors = ["Julik Tarkhanov"]
21
+ # dependencies defined in Gemfile
22
+ end
23
+ Jeweler::RubygemsDotOrgTasks.new
24
+
25
+ require 'rake/testtask'
26
+ Rake::TestTask.new(:test) do |test|
27
+ test.libs << 'lib' << 'test'
28
+ test.pattern = 'test/**/test_*.rb'
29
+ test.verbose = true
30
+ end
31
+
32
+ task :default => :test
@@ -0,0 +1,97 @@
1
+ module LineByLine
2
+
3
+ VERSION = '1.0.0'
4
+
5
+ # The class that handles the actual checks between two lines
6
+ class Checker < Struct.new(:lineno, :ref_line, :output_line)
7
+
8
+ attr_reader :failure
9
+
10
+ def register_mismatches!
11
+ catch :fail do
12
+ if ref_line.nil? && output_line
13
+ fail! "Reference buffer ended, but the output still has data"
14
+ end
15
+
16
+ if ref_line && output_line.nil?
17
+ fail! "Reference contains chars, while the output buffer ended"
18
+ end
19
+
20
+ if ref_line != output_line
21
+ min_len = [ref_line.length, output_line.length].sort.shift
22
+ min_len.times do | offset |
23
+ if ref_line[offset..offset] != output_line[offset..offset]
24
+ fail! "Line mismatch at column #{offset + 1}"
25
+ end
26
+ end
27
+ fail! "Lines have different lengths (%d expected, but was %d)" % [ref_line.length, output_line.length]
28
+ end
29
+ end
30
+ end
31
+
32
+ # Returns true if both lines are nil
33
+ def eof?
34
+ ref_line.nil? && output_line.nil?
35
+ end
36
+
37
+ # Records the failure and the details on where it occurred in the buffer
38
+ # into the @failure ivar
39
+ def fail! with_message
40
+ full_message = [with_message + " at line #{lineno}"]
41
+ full_message << " + #{ref_line.inspect}"
42
+ full_message << " - #{output_line.inspect}"
43
+
44
+ @failure = full_message.join("\n")
45
+ throw :fail
46
+ end
47
+ end
48
+
49
+ class NotSame < RuntimeError
50
+ end
51
+
52
+ # Compares two passed String or IO objects for equal content.
53
+ # If the contents does not match, a NotSame exception will be raised, and
54
+ # it's +NotSame#message+ will contain a very specific description of the mismatch,
55
+ # including the line number and offset into the line.
56
+ def compare_buffers!(expected, actual)
57
+
58
+ if expected.object_id == actual.object_id
59
+ raise NotSame, /The passed IO objects were the same thing/
60
+ end
61
+
62
+ # Wrap the passed strings in IOs if necessary
63
+ reference_io, io_under_test = [expected, actual].map do | str_or_io |
64
+ str_or_io.respond_to?(:gets) ? str_or_io : StringIO.new(str_or_io)
65
+ end
66
+
67
+ # There are subtle differences in how IO is handled on dfferent platforms (Darwin)
68
+ lineno = 0
69
+ loop do
70
+ # Increment the line counter
71
+ lineno += 1
72
+
73
+ checker = Checker.new(lineno, reference_io.gets, io_under_test.gets)
74
+ if checker.eof?
75
+ return
76
+ else
77
+ checker.register_mismatches!
78
+ raise NotSame, checker.failure if checker.failure
79
+ end
80
+ end
81
+ end
82
+
83
+ module Assertions
84
+ def self.included(into)
85
+ into.send(:include, LineByLine)
86
+ end
87
+
88
+ def assert_same_buffer(ref_buffer, actual_buffer, message = "The line should be identical but was not")
89
+ begin
90
+ compare_buffers! ref_buffer, actual_buffer
91
+ assert true
92
+ rescue NotSame => e
93
+ flunk [message, e.message].join("\n")
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'linebyline'
15
+
@@ -0,0 +1,34 @@
1
+ require 'helper'
2
+ require 'stringio'
3
+
4
+ class TestAssertions < Test::Unit::TestCase
5
+ include LineByLine::Assertions
6
+
7
+ def test_nothing_raises
8
+ assert_same_buffer "foo", "foo"
9
+ end
10
+
11
+ class Refuter
12
+ include LineByLine::Assertions
13
+
14
+ attr_reader :m
15
+ def flunk(m)
16
+ @m = m
17
+ end
18
+
19
+ def perform
20
+ assert_same_buffer "foo\nbar\nbaz", "foo\nbar", "Total fail"
21
+ end
22
+ end
23
+
24
+ def test_not_same
25
+ r = Refuter.new
26
+ message = 'Total fail
27
+ Lines have different lengths (4 expected, but was 3) at line 2
28
+ + "bar\n"
29
+ - "bar"'
30
+
31
+ r.perform
32
+ assert_equal message, r.m
33
+ end
34
+ end
@@ -0,0 +1,53 @@
1
+ require 'helper'
2
+ require 'stringio'
3
+
4
+ class TestLinebyline < Test::Unit::TestCase
5
+ include LineByLine
6
+
7
+ def test_nothing_raises
8
+ a = "foo"
9
+ ref = StringIO.new(a)
10
+ another = StringIO.new(a)
11
+
12
+ compare_buffers! ref, another
13
+ end
14
+
15
+ def test_works_with_string_and_io
16
+ assert_mismatch 'foo', 'foobar' do | msg |
17
+ assert_match /Lines have different lengths \(3 expected, but was 6\)/, msg
18
+ end
19
+ end
20
+
21
+ def test_raises_on_mismatch
22
+ same = StringIO.new('dude')
23
+ assert_mismatch same, same do | msg |
24
+ assert_match /The passed IO objects were the same thing/, msg
25
+ end
26
+
27
+ assert_mismatch StringIO.new("foo"), StringIO.new("bar") do | msg |
28
+ assert_match /Line mismatch at column 1 at line 1/, msg
29
+ end
30
+
31
+ assert_mismatch StringIO.new("foobar"), StringIO.new("foo") do | msg |
32
+ assert_match /Lines have different lengths \(6 expected, but was 3\) at line 1/, msg
33
+ end
34
+
35
+ assert_mismatch StringIO.new("foo"), StringIO.new("foobar") do | msg |
36
+ assert_match /Lines have different lengths \(3 expected, but was 6\) at line 1/, msg
37
+ end
38
+
39
+ assert_mismatch StringIO.new("foo\nbar\n"), StringIO.new("foo\nbar\nbaz") do | msg |
40
+ assert_match /Reference buffer ended, but the output still has data at line 3/, msg
41
+ end
42
+
43
+ end
44
+
45
+ def assert_mismatch(ref, output)
46
+ begin
47
+ compare_buffers! ref, output
48
+ flunk "These buffers are not the same and LineByLine should have raise"
49
+ rescue LineByLine::NotSame => e
50
+ yield e.message
51
+ end
52
+ end
53
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: linebyline
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Julik Tarkhanov
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: jeweler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.8.4
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.8.4
46
+ description: ! ' Can be used for comparing long outputs to references '
47
+ email: me@julik.nl
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files:
51
+ - LICENSE.txt
52
+ - README.rdoc
53
+ files:
54
+ - .document
55
+ - .travis.yml
56
+ - Gemfile
57
+ - LICENSE.txt
58
+ - README.rdoc
59
+ - Rakefile
60
+ - lib/linebyline.rb
61
+ - test/helper.rb
62
+ - test/test_assertions.rb
63
+ - test/test_linebyline.rb
64
+ homepage: http://github.com/julik/linebyline
65
+ licenses:
66
+ - MIT
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ segments:
78
+ - 0
79
+ hash: 2945154336957707059
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 1.8.24
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Comparse two passed IO objects line by line (useful for tests)
92
+ test_files: []