hot_or_not 0.1.11 → 0.2.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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.11
1
+ 0.2.0
data/bin/hot_or_not CHANGED
@@ -4,9 +4,33 @@ require 'rubygems'
4
4
  require File.dirname(__FILE__) + '/../lib/hot_or_not'
5
5
  require 'optparse'
6
6
 
7
+ def constantize(camel_cased_word)
8
+ names = camel_cased_word.split('::')
9
+ names.shift if names.empty? || names.first.empty?
10
+
11
+ constant = Object
12
+ names.each do |name|
13
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
14
+ end
15
+ constant
16
+ end
17
+
18
+ def get_announcer(announcer)
19
+ klass = constantize(announcer) rescue nil
20
+ return klass unless klass.nil?
21
+ begin
22
+ constantize("HotOrNot::#{announcer}Announcer")
23
+ rescue NameError
24
+ puts "Announcer #{announcer} cannot be found"
25
+ exit 1
26
+ end
27
+ end
28
+
7
29
  defaults = {
8
30
  :output_directory => 'test_results',
9
- :test_names => :all
31
+ :test_names => :all,
32
+ :announcer => 'TestUnit',
33
+ :requires => []
10
34
  }
11
35
 
12
36
  options = {}
@@ -16,6 +40,15 @@ parser = ::OptionParser.new do |opts|
16
40
  options[:output_directory] = d
17
41
  end
18
42
 
43
+ opts.on("--announcer [ANNOUNCER]", "Announcer to use for output results (full constant if not in HotOrNot). DEFAULT: #{defaults[:announcer]}") do |a|
44
+ options[:announcer] = a
45
+ end
46
+
47
+ opts.on("-r", "--require [FILE]", "Require an additional file.") do |file|
48
+ options[:requires] ||= []
49
+ options[:requires] << file
50
+ end
51
+
19
52
  opts.on('-n', '--name [NAMES]', "Test names to run. DEFAULT: all") do |test_names|
20
53
  options[:test_names] = test_names.split(',')
21
54
  end
@@ -51,5 +84,7 @@ end
51
84
  suite_name = File.basename(yaml_file).gsub('.yml', '').gsub('.erb', '')
52
85
  output_dir = File.join options[:output_directory], suite_name
53
86
 
54
- announcer = HotOrNot::ConsoleAnnouncer.new output_dir
87
+ options[:requires].each { |file| require file }
88
+
89
+ announcer = get_announcer(options[:announcer]).new output_dir
55
90
  HotOrNot::Runner.run_from(yaml_file, announcer).run! options[:test_names]
@@ -0,0 +1,56 @@
1
+ module HotOrNot
2
+ class InlineAnnouncer
3
+ include Announcer
4
+
5
+ def initialize(output_dir)
6
+ @output_dir = output_dir
7
+ @counts = Hash.new(0)
8
+ @start = nil
9
+ end
10
+
11
+ def starting
12
+ puts "Starting to compare the bodies"
13
+ @start = Time.now
14
+ end
15
+
16
+ def ending
17
+ completion_time = Time.now - @start
18
+ total = @counts.values.reduce(:+)
19
+ puts
20
+ puts "Finished in %.6f seconds." % [completion_time]
21
+ puts
22
+ puts "#{total} body comparisons, #{@counts[:success]} hot bodies, #{@counts[:failure]} not-hot bodies, #{@counts[:error]} errored bodies"
23
+ end
24
+
25
+ def announce_success(result)
26
+ @counts[:success] += 1
27
+ say 'Hot', result
28
+ end
29
+
30
+ def announce_failure(result)
31
+ @counts[:failure] += 1
32
+ say 'Not Hot', result
33
+ result.output_to_files_in results_dir
34
+ end
35
+
36
+ def announce_error(result)
37
+ @counts[:error] += 1
38
+ say 'Error', result
39
+ result.output_to_files_in results_dir
40
+ end
41
+
42
+ private
43
+ def say(what, result)
44
+ what += ':'
45
+ puts "%-10s #{result.full_name}" % [what]
46
+ end
47
+
48
+ def results_dir
49
+ @results_dir ||= @output_dir.tap do |dir|
50
+ FileUtils.rm_rf dir
51
+ FileUtils.mkdir_p dir
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -1,5 +1,5 @@
1
1
  module HotOrNot
2
- class ConsoleAnnouncer
2
+ class TestUnitAnnouncer
3
3
  include Announcer
4
4
 
5
5
  def initialize(output_dir)
@@ -23,7 +23,7 @@ module HotOrNot
23
23
  counts[status] += 1
24
24
  end
25
25
 
26
- puts "Finsihed in %.6f seconds." % [completion_time]
26
+ puts "Finished in %.6f seconds." % [completion_time]
27
27
  puts
28
28
  puts "#{@results.count} body comparisons, #{counts[:success]} hot bodies, #{counts[:failure]} not-hot bodies, #{counts[:error]} errored bodies"
29
29
  end
@@ -27,7 +27,7 @@ module HotOrNot
27
27
  def self.load_from(filename)
28
28
  contents = YAML.load(run_erb(filename)).symbolize_keys!
29
29
  side_a, side_b, comparisons = contents.delete(:side_a), contents.delete(:side_b), contents.delete(:comparisons)
30
- raise "You're file is not of the proper format" unless side_a && side_b && comparisons
30
+ raise "Your file is not in the proper format" unless side_a && side_b && comparisons
31
31
  comparisons.map do |h|
32
32
  h.symbolize_keys!
33
33
  name = h.delete :name
@@ -11,7 +11,7 @@ module HotOrNot
11
11
  end
12
12
 
13
13
  attr_reader :message
14
- def_delegators :@compare_url, :short_name
14
+ def_delegators :@compare_url, :short_name, :full_name
15
15
 
16
16
  def initialize(compare_url, side_a_results, side_b_results)
17
17
  @compare_url, @side_a_results, @side_b_results = compare_url, side_a_results, side_b_results
@@ -47,9 +47,14 @@ module HotOrNot
47
47
  end
48
48
 
49
49
  def output_to_files_in(directory)
50
- write_to directory, "side_a", side_a_body
51
- write_to directory, "side_b", side_b_body
52
- write_to directory, "diff", diff
50
+ return if success?
51
+ if error?
52
+ write_to directory, "error", message
53
+ else
54
+ write_to directory, "side_a", side_a_body
55
+ write_to directory, "side_b", side_b_body
56
+ write_to directory, "diff", diff
57
+ end
53
58
  end
54
59
 
55
60
  private
@@ -0,0 +1,42 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/../test_helper'
2
+
3
+ module HotOrNot
4
+ class InlineAnnouncerTest < AnnouncerTestCase
5
+ context "run" do
6
+ setup do
7
+ intercept_io
8
+ output_dir = 'test_results'
9
+ @announcer = InlineAnnouncer.new output_dir
10
+ end
11
+
12
+ teardown do
13
+ reset_io
14
+ end
15
+
16
+ context "the inline console output" do
17
+ should "print Hot and testname for passing test" do
18
+ urls = [mock_compare_url('Passing Test', '/api/foo', 'foo', 'foo')]
19
+ Runner.new(urls, @announcer).run!
20
+
21
+ expected_output = /^Hot:\s+Passing Test$/
22
+ assert_match expected_output, test_output[1].chomp
23
+ end
24
+
25
+ should "print Not Hot and testname for failing test" do
26
+ urls = [mock_compare_url('Failing Test', '/api/foo', 'foo', 'bar')]
27
+ Runner.new(urls, @announcer).run!
28
+
29
+ expected_output = /^Not Hot:\s+Failing Test$/
30
+ assert_match expected_output, test_output[1].chomp
31
+ end
32
+
33
+ should "print Error and testname for test that causes error" do
34
+ urls = [mock_compare_url('Error test', '/api/foo', 'foo', 'bar', 404)]
35
+ Runner.new(urls, @announcer).run!
36
+
37
+ assert_match /^Error:\s+Error test$/, test_output[1].chomp
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/../test_helper'
2
+
3
+ module HotOrNot
4
+ class TestUnitAnnouncerTest < AnnouncerTestCase
5
+ context "run" do
6
+ setup do
7
+ intercept_io
8
+ output_dir = 'test_results'
9
+ @announcer = TestUnitAnnouncer.new output_dir
10
+ end
11
+
12
+ teardown do
13
+ reset_io
14
+ end
15
+
16
+ context "the console output" do
17
+ should "print '.' for passing test" do
18
+ urls = [mock_compare_url('Foo', '/api/foo', 'foo', 'foo')]
19
+ Runner.new(urls, @announcer).run!
20
+
21
+ assert_equal '.', test_output[1].chomp
22
+ end
23
+
24
+ should "print 'N' for a failing test" do
25
+ urls = [mock_compare_url('Foo', '/api/foo', 'foo', 'bar')]
26
+ Runner.new(urls, @announcer).run!
27
+
28
+ assert_equal 'N', test_output[1].chomp
29
+ assert_equal ' 1) Not Hot:', test_output[2].chomp
30
+ end
31
+
32
+ should "print 'E' for a test that errors out" do
33
+ urls = [mock_compare_url('Foo', '/api/foo', 'foo', 'bar', 404)]
34
+ Runner.new(urls, @announcer).run!
35
+
36
+ assert_equal 'E', test_output[1].chomp
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
data/test/test_helper.rb CHANGED
@@ -58,3 +58,32 @@ class Test::Unit::TestCase
58
58
  [response, error]
59
59
  end
60
60
  end
61
+
62
+ module HotOrNot
63
+ class AnnouncerTestCase < Test::Unit::TestCase
64
+ private
65
+ def intercept_io
66
+ @output_filename = 'test_runner_tests.txt'
67
+ @output_file = File.open(@output_filename, 'w+')
68
+ @orig_stdout = STDOUT.dup
69
+ STDOUT.reopen(@output_file)
70
+ end
71
+
72
+ def reset_io
73
+ @output_file.close
74
+ @test_output = nil
75
+ FileUtils.rm_f @output_filename if leave_last_ouput?
76
+ STDOUT.reopen @orig_stdout
77
+ end
78
+
79
+ def leave_last_ouput?
80
+ ENV['HORN_io'].to_s.downcase != 'false'
81
+ end
82
+
83
+ def test_output
84
+ @test_output ||= (
85
+ STDOUT.flush
86
+ File.readlines(@output_file) )
87
+ end
88
+ end
89
+ end
metadata CHANGED
@@ -1,187 +1,136 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: hot_or_not
3
- version: !ruby/object:Gem::Version
4
- hash: 13
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 1
9
- - 11
10
- version: 0.1.11
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Joel Friedman
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-07-26 00:00:00 -05:00
19
- default_executable: hot_or_not
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2011-09-19 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: rest-client
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70199395090880 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
18
+ requirements:
26
19
  - - ~>
27
- - !ruby/object:Gem::Version
28
- hash: 13
29
- segments:
30
- - 1
31
- - 6
32
- - 1
20
+ - !ruby/object:Gem::Version
33
21
  version: 1.6.1
34
22
  type: :runtime
35
23
  prerelease: false
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
24
+ version_requirements: *70199395090880
25
+ - !ruby/object:Gem::Dependency
38
26
  name: diffy
39
- requirement: &id002 !ruby/object:Gem::Requirement
27
+ requirement: &70199395089640 !ruby/object:Gem::Requirement
40
28
  none: false
41
- requirements:
29
+ requirements:
42
30
  - - ~>
43
- - !ruby/object:Gem::Version
44
- hash: 9
45
- segments:
46
- - 2
47
- - 0
48
- - 3
31
+ - !ruby/object:Gem::Version
49
32
  version: 2.0.3
50
33
  type: :runtime
51
34
  prerelease: false
52
- version_requirements: *id002
53
- - !ruby/object:Gem::Dependency
35
+ version_requirements: *70199395089640
36
+ - !ruby/object:Gem::Dependency
54
37
  name: facets
55
- requirement: &id003 !ruby/object:Gem::Requirement
38
+ requirement: &70199395088200 !ruby/object:Gem::Requirement
56
39
  none: false
57
- requirements:
40
+ requirements:
58
41
  - - ~>
59
- - !ruby/object:Gem::Version
60
- hash: 41
61
- segments:
62
- - 2
63
- - 9
64
- - 1
42
+ - !ruby/object:Gem::Version
65
43
  version: 2.9.1
66
44
  type: :runtime
67
45
  prerelease: false
68
- version_requirements: *id003
69
- - !ruby/object:Gem::Dependency
46
+ version_requirements: *70199395088200
47
+ - !ruby/object:Gem::Dependency
70
48
  name: json
71
- requirement: &id004 !ruby/object:Gem::Requirement
49
+ requirement: &70199395085280 !ruby/object:Gem::Requirement
72
50
  none: false
73
- requirements:
51
+ requirements:
74
52
  - - ~>
75
- - !ruby/object:Gem::Version
76
- hash: 7
77
- segments:
78
- - 1
79
- - 5
80
- - 2
53
+ - !ruby/object:Gem::Version
81
54
  version: 1.5.2
82
55
  type: :runtime
83
56
  prerelease: false
84
- version_requirements: *id004
85
- - !ruby/object:Gem::Dependency
57
+ version_requirements: *70199395085280
58
+ - !ruby/object:Gem::Dependency
86
59
  name: hpricot
87
- requirement: &id005 !ruby/object:Gem::Requirement
60
+ requirement: &70199395083640 !ruby/object:Gem::Requirement
88
61
  none: false
89
- requirements:
62
+ requirements:
90
63
  - - ~>
91
- - !ruby/object:Gem::Version
92
- hash: 55
93
- segments:
94
- - 0
95
- - 8
96
- - 4
64
+ - !ruby/object:Gem::Version
97
65
  version: 0.8.4
98
66
  type: :runtime
99
67
  prerelease: false
100
- version_requirements: *id005
101
- - !ruby/object:Gem::Dependency
68
+ version_requirements: *70199395083640
69
+ - !ruby/object:Gem::Dependency
102
70
  name: shoulda
103
- requirement: &id006 !ruby/object:Gem::Requirement
71
+ requirement: &70199395082420 !ruby/object:Gem::Requirement
104
72
  none: false
105
- requirements:
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- hash: 3
109
- segments:
110
- - 0
111
- version: "0"
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
112
77
  type: :development
113
78
  prerelease: false
114
- version_requirements: *id006
115
- - !ruby/object:Gem::Dependency
79
+ version_requirements: *70199395082420
80
+ - !ruby/object:Gem::Dependency
116
81
  name: bundler
117
- requirement: &id007 !ruby/object:Gem::Requirement
82
+ requirement: &70199395080480 !ruby/object:Gem::Requirement
118
83
  none: false
119
- requirements:
84
+ requirements:
120
85
  - - ~>
121
- - !ruby/object:Gem::Version
122
- hash: 23
123
- segments:
124
- - 1
125
- - 0
126
- - 0
86
+ - !ruby/object:Gem::Version
127
87
  version: 1.0.0
128
88
  type: :development
129
89
  prerelease: false
130
- version_requirements: *id007
131
- - !ruby/object:Gem::Dependency
90
+ version_requirements: *70199395080480
91
+ - !ruby/object:Gem::Dependency
132
92
  name: jeweler
133
- requirement: &id008 !ruby/object:Gem::Requirement
93
+ requirement: &70199395078960 !ruby/object:Gem::Requirement
134
94
  none: false
135
- requirements:
95
+ requirements:
136
96
  - - ~>
137
- - !ruby/object:Gem::Version
138
- hash: 15
139
- segments:
140
- - 1
141
- - 6
142
- - 0
97
+ - !ruby/object:Gem::Version
143
98
  version: 1.6.0
144
99
  type: :development
145
100
  prerelease: false
146
- version_requirements: *id008
147
- - !ruby/object:Gem::Dependency
101
+ version_requirements: *70199395078960
102
+ - !ruby/object:Gem::Dependency
148
103
  name: rcov
149
- requirement: &id009 !ruby/object:Gem::Requirement
104
+ requirement: &70199395077620 !ruby/object:Gem::Requirement
150
105
  none: false
151
- requirements:
152
- - - ">="
153
- - !ruby/object:Gem::Version
154
- hash: 3
155
- segments:
156
- - 0
157
- version: "0"
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
158
110
  type: :development
159
111
  prerelease: false
160
- version_requirements: *id009
161
- - !ruby/object:Gem::Dependency
112
+ version_requirements: *70199395077620
113
+ - !ruby/object:Gem::Dependency
162
114
  name: mocha
163
- requirement: &id010 !ruby/object:Gem::Requirement
115
+ requirement: &70199395074400 !ruby/object:Gem::Requirement
164
116
  none: false
165
- requirements:
166
- - - ">="
167
- - !ruby/object:Gem::Version
168
- hash: 3
169
- segments:
170
- - 0
171
- version: "0"
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
172
121
  type: :development
173
122
  prerelease: false
174
- version_requirements: *id010
175
- description: Run this with a new version of your site comparing to current version to verify no break changes are made to your api's
123
+ version_requirements: *70199395074400
124
+ description: Run this with a new version of your site comparing to current version
125
+ to verify no break changes are made to your api's
176
126
  email: asher.friedman@gmail.com
177
- executables:
127
+ executables:
178
128
  - hot_or_not
179
129
  extensions: []
180
-
181
- extra_rdoc_files:
130
+ extra_rdoc_files:
182
131
  - LICENSE.txt
183
132
  - README.rdoc
184
- files:
133
+ files:
185
134
  - .document
186
135
  - Gemfile
187
136
  - Gemfile.lock
@@ -192,53 +141,48 @@ files:
192
141
  - bin/hot_or_not
193
142
  - lib/hot_or_not.rb
194
143
  - lib/hot_or_not/announcer.rb
195
- - lib/hot_or_not/announcers/console_announcer.rb
144
+ - lib/hot_or_not/announcers/inline_announcer.rb
145
+ - lib/hot_or_not/announcers/test_unit_announcer.rb
196
146
  - lib/hot_or_not/compare_url.rb
197
147
  - lib/hot_or_not/comparison_result.rb
198
148
  - lib/hot_or_not/ext/hash.rb
199
149
  - lib/hot_or_not/runner.rb
200
150
  - lib/hot_or_not/url_result.rb
151
+ - test/announcers/inline_announcer_test.rb
152
+ - test/announcers/test_unit_announcer_test.rb
201
153
  - test/compare_url_test.rb
202
154
  - test/comparison_result_test.rb
203
- - test/console_announcer_test.rb
204
155
  - test/data/simple_urls.yml
205
156
  - test/data/simple_urls.yml.erb
206
157
  - test/runner_test.rb
207
158
  - test/test_helper.rb
208
159
  - test/url_result_test.rb
209
- has_rdoc: true
210
160
  homepage: https://github.com/joelash/hot_or_not
211
- licenses:
161
+ licenses:
212
162
  - MIT
213
163
  post_install_message:
214
164
  rdoc_options: []
215
-
216
- require_paths:
165
+ require_paths:
217
166
  - lib
218
- required_ruby_version: !ruby/object:Gem::Requirement
167
+ required_ruby_version: !ruby/object:Gem::Requirement
219
168
  none: false
220
- requirements:
221
- - - ">="
222
- - !ruby/object:Gem::Version
223
- hash: 3
224
- segments:
169
+ requirements:
170
+ - - ! '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ segments:
225
174
  - 0
226
- version: "0"
227
- required_rubygems_version: !ruby/object:Gem::Requirement
175
+ hash: -1646296402133696515
176
+ required_rubygems_version: !ruby/object:Gem::Requirement
228
177
  none: false
229
- requirements:
230
- - - ">="
231
- - !ruby/object:Gem::Version
232
- hash: 3
233
- segments:
234
- - 0
235
- version: "0"
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
236
182
  requirements: []
237
-
238
183
  rubyforge_project:
239
- rubygems_version: 1.3.7
184
+ rubygems_version: 1.8.6
240
185
  signing_key:
241
186
  specification_version: 3
242
187
  summary: A tool for side-by-side comparsion of web apis
243
188
  test_files: []
244
-
@@ -1,67 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__)) + '/test_helper'
2
-
3
- module HotOrNot
4
- class ConsoleAnnouncerTest < Test::Unit::TestCase
5
- context "run" do
6
- setup do
7
- intercept_io
8
- output_dir = 'test_results'
9
- @announcer = ConsoleAnnouncer.new output_dir
10
- end
11
-
12
- teardown do
13
- reset_io
14
- end
15
-
16
- context "the console output" do
17
- should "print '.' for passing test" do
18
- urls = [mock_compare_url('Foo', '/api/foo', 'foo', 'foo')]
19
- Runner.new(urls, @announcer).run!
20
-
21
- assert_equal '.', test_output[1].chomp
22
- end
23
-
24
- should "print 'N' for a failing test" do
25
- urls = [mock_compare_url('Foo', '/api/foo', 'foo', 'bar')]
26
- Runner.new(urls, @announcer).run!
27
-
28
- output = test_output
29
- assert_equal 'N', output[1].chomp
30
- assert_equal ' 1) Not Hot:', output[2].chomp
31
- end
32
-
33
- should "print 'E' for a test that errors out" do
34
- urls = [mock_compare_url('Foo', '/api/foo', 'foo', 'bar', 404)]
35
- Runner.new(urls, @announcer).run!
36
-
37
- o = test_output
38
- assert_equal 'E', o[1].chomp
39
- end
40
- end
41
-
42
- end
43
-
44
- private
45
- def intercept_io
46
- @output_filename = 'test_runner_tests.txt'
47
- @output_file = File.open(@output_filename, 'w+')
48
- @orig_stdout = STDOUT.dup
49
- STDOUT.reopen(@output_file)
50
- end
51
-
52
- def reset_io
53
- @output_file.close
54
- FileUtils.rm_f @output_filename if leave_last_ouput?
55
- STDOUT.reopen @orig_stdout
56
- end
57
-
58
- def leave_last_ouput?
59
- ENV['HORN_io'].to_s.downcase != 'false'
60
- end
61
-
62
- def test_output
63
- STDOUT.flush
64
- File.readlines(@output_file)
65
- end
66
- end
67
- end