hot_or_not 0.1.11 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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