adamh-html_render 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest CHANGED
@@ -5,4 +5,6 @@ lib/html_render.rb
5
5
  lib/html_render/render_batches.rb
6
6
  lib/html_render/renderers.rb
7
7
  lib/html_render/images.rb
8
+ lib/html_render/render_test.rb
9
+ lib/html_render/render_test/rails.rb
8
10
  Manifest
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('html_render', '0.0.1') do |p|
5
+ Echoe.new('html_render', '0.0.2') do |p|
6
6
  p.description = 'Make images from HTML strings'
7
7
  p.url = 'http://adamhooper.com/eng'
8
8
  p.author = 'Adam Hooper'
data/html_render.gemspec CHANGED
@@ -1,27 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  Gem::Specification.new do |s|
2
4
  s.name = %q{html_render}
3
- s.version = "0.0.1"
5
+ s.version = "0.0.2"
4
6
 
5
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
6
8
  s.authors = ["Adam Hooper"]
7
- s.date = %q{2009-03-06}
9
+ s.date = %q{2009-04-01}
8
10
  s.description = %q{Make images from HTML strings}
9
11
  s.email = %q{adam@adamhooper.com}
10
- s.extra_rdoc_files = ["README.rdoc", "lib/html_render.rb", "lib/html_render/render_batches.rb", "lib/html_render/renderers.rb", "lib/html_render/images.rb"]
11
- s.files = ["README.rdoc", "Rakefile", "html_render.gemspec", "lib/html_render.rb", "lib/html_render/render_batches.rb", "lib/html_render/renderers.rb", "lib/html_render/images.rb", "Manifest"]
12
+ s.extra_rdoc_files = ["README.rdoc", "lib/html_render.rb", "lib/html_render/render_batches.rb", "lib/html_render/renderers.rb", "lib/html_render/images.rb", "lib/html_render/render_test.rb", "lib/html_render/render_test/rails.rb"]
13
+ s.files = ["README.rdoc", "Rakefile", "html_render.gemspec", "lib/html_render.rb", "lib/html_render/render_batches.rb", "lib/html_render/renderers.rb", "lib/html_render/images.rb", "lib/html_render/render_test.rb", "lib/html_render/render_test/rails.rb", "Manifest"]
12
14
  s.has_rdoc = true
13
15
  s.homepage = %q{http://adamhooper.com/eng}
14
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Html_render", "--main", "README.rdoc"]
15
17
  s.require_paths = ["lib"]
16
18
  s.rubyforge_project = %q{html_render}
17
- s.rubygems_version = %q{1.2.0}
19
+ s.rubygems_version = %q{1.3.1}
18
20
  s.summary = %q{Make images from HTML strings}
19
21
 
20
22
  if s.respond_to? :specification_version then
21
23
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
22
24
  s.specification_version = 2
23
25
 
24
- if current_version >= 3 then
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
25
27
  s.add_runtime_dependency(%q<httpclient>, [">= 2.1.4"])
26
28
  s.add_runtime_dependency(%q<rmagick>, [">= 2.9.1"])
27
29
  s.add_development_dependency(%q<echoe>, [">= 0"])
@@ -23,7 +23,8 @@ module HTMLRender::Images
23
23
  end
24
24
 
25
25
  def <=>(other)
26
- (png <=> other.png) == 0
26
+ self.class.name <=> other.class.name unless PNGImage === other
27
+ png <=> other.png
27
28
  end
28
29
 
29
30
  def difference(other)
@@ -0,0 +1,99 @@
1
+ require 'action_controller/test_process'
2
+ require 'action_view/test_case'
3
+
4
+ require 'html_render/render_test'
5
+
6
+ module HTMLRender; end
7
+ module HTMLRender::RenderTest; end
8
+
9
+ module HTMLRender::RenderTest::Rails
10
+ class RenderTest < HTMLRender::RenderTest::DirectoryRenderTest
11
+ def initialize(*args, &block)
12
+ super(*args, &block)
13
+ end
14
+
15
+ def run(*args, &block)
16
+ write_html_to_run_directory
17
+ super(*args, &block)
18
+ end
19
+
20
+ def html
21
+ @html ||= wrap_html { view.render(render_options) }
22
+ end
23
+
24
+ def render_options
25
+ {
26
+ template_type => template_path,
27
+ :locals => locals
28
+ }
29
+ end
30
+
31
+ def template_type
32
+ :partial
33
+ end
34
+
35
+ def assigns
36
+ {}
37
+ end
38
+
39
+ def locals
40
+ {}
41
+ end
42
+
43
+ # Wraps the rendered HTML to create a fully-valid XHTML 1.0 page which
44
+ # may be rendered.
45
+ #
46
+ # Override the +css+ or +javascript+ methods to include CSS or
47
+ # JavaScript in the output. (Most Rails project testing frameworks will
48
+ # rely upon a subclass of this RenderTest with css returning the
49
+ # project's entire CSS library.)
50
+ def wrap_html
51
+ <<-EOT
52
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
53
+ <html xmlns='http://www.w3.org/1999/xhtml'>
54
+ <head>
55
+ <title>Test</title>
56
+ <style type="text/css">
57
+ #{css}
58
+ </style>
59
+ <script type="text/javascript">
60
+ #{javascript}
61
+ </script>
62
+ </head>
63
+ <body>
64
+ #{yield}
65
+ </body>
66
+ </html>
67
+ EOT
68
+ end
69
+
70
+ def css
71
+ ""
72
+ end
73
+
74
+ def javascript
75
+ ""
76
+ end
77
+
78
+ private
79
+
80
+ def controller
81
+ returning(ActionView::TestCase::TestController.new) do |controller|
82
+ # Set @url so url_for() doesn't crash
83
+ request = controller.instance_variable_get(:@request)
84
+ controller.instance_variable_set(:@url, ActionController::UrlRewriter.new(request, {}))
85
+ end
86
+ end
87
+
88
+ def view
89
+ ActionView::Base.new(ActionController::Base.view_paths, assigns, controller)
90
+ end
91
+
92
+ def write_html_to_run_directory
93
+ last_run_html_file = File.join(run_path, 'html.html')
94
+ File.open(last_run_html_file, 'w') do |f|
95
+ f.write(html)
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,194 @@
1
+ require 'html_render/images'
2
+ require 'html_render/render_batches'
3
+
4
+ module HTMLRender; end
5
+ module HTMLRender::RenderTest
6
+ # Result of a RenderTest::run() call
7
+ class Result
8
+ # The portion of a result specific to an individual server
9
+ class ServerResult
10
+ attr_reader :server, :expected, :actual
11
+
12
+ # Initializes the ServerResult.
13
+ #
14
+ # Params:
15
+ # server: name of the server
16
+ # expected: Image we expected
17
+ # actual: Image we got
18
+ def initialize(server, expected, actual)
19
+ @server = server
20
+ @expected = expected
21
+ @actual = actual
22
+ end
23
+
24
+ def pass?
25
+ actual == expected
26
+ end
27
+
28
+ def difference
29
+ expected.difference(actual)
30
+ end
31
+ end
32
+
33
+ def servers
34
+ raise NotImplementedError
35
+ end
36
+
37
+ def details
38
+ returning({}) do |h|
39
+ servers.each do |server|
40
+ h[server] = details_for(server)
41
+ end
42
+ end
43
+ end
44
+
45
+ # Returns the ServerResult corresponding to the given Server
46
+ def details_for(server)
47
+ raise NotImplementedError
48
+ end
49
+
50
+ def pass?
51
+ @pass ||= servers.select{|s| !details_for(s).pass?}.empty?
52
+ end
53
+ end
54
+
55
+ class DirectoryResult < Result
56
+ attr_reader :path
57
+ attr_reader :valid_path
58
+ attr_reader :canonical_path
59
+
60
+ def initialize(path, valid_path, canonical_path)
61
+ @path = path
62
+ @valid_path = valid_path
63
+ @canonical_path = canonical_path
64
+ end
65
+
66
+ def servers
67
+ @servers ||= Dir.glob(File.join(path, '*.png')).collect{ |s| s.split(/\//).last[0..-5] }.sort
68
+ end
69
+
70
+ def details_for(server)
71
+ @details_for ||= {}
72
+ @details_for[server] ||= ServerResult.new(
73
+ server,
74
+ expected_png_for(server),
75
+ actual_png_for(server)
76
+ )
77
+ end
78
+
79
+ private
80
+
81
+ # Returns the PNG we actually got for the given server name
82
+ def actual_png_for(server)
83
+ @actual_png_for ||= {}
84
+ @actual_png_for[server] ||= begin
85
+ filename = filename_of_actual_png_for(server)
86
+ File.open(filename) do |f|
87
+ HTMLRender::Images::PNGImage.new(f.read)
88
+ end
89
+ end
90
+ end
91
+
92
+ # Returns the PNG expected of the given server name, or nil
93
+ def expected_png_for(server)
94
+ @expected_png_for ||= {}
95
+ @expected_png_for[server] ||= begin
96
+ filename = filename_of_expected_png_for(server)
97
+ if filename
98
+ File.open(filename) do |f|
99
+ HTMLRender::Images::PNGImage.new(f.read)
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ def filename_of_actual_png_for(server)
106
+ # Assume it exists--otherwise, "servers" wouldn't return it
107
+ File.join(path, "#{server}.png")
108
+ end
109
+
110
+ # Returns the path to the expected PNG for the given server name, or nil
111
+ def filename_of_expected_png_for(server)
112
+ specific = File.join(valid_path, "#{server}.png")
113
+
114
+ @filename_of_expected_png_for ||= {}
115
+ @filename_of_expected_png_for[server] ||= case
116
+ when File.exist?(specific) then specific
117
+ when File.exist?(canonical_path) then canonical_path
118
+ else nil
119
+ end
120
+ end
121
+ end
122
+
123
+ # Tests, across browsers, that some HTML renders correctly.
124
+ #
125
+ # A DirectoryRenderTest works within a particular directory in the
126
+ # filesystem, and it expects the following files:
127
+ #
128
+ # - html.html
129
+ # - canonical.png (what we want it to look like)
130
+ # - valid/SERVER.png for each SYSTEM (i.e., "ff3", "winxp-ie6", etc.)
131
+ # - runs/20080331014523/SERVER.png (at the time "run" was called)
132
+ #
133
+ # Calling run() with a hash of servers (see
134
+ # HtmlRender::RenderBatches::HTTPRenderBatch) will batch-render for each
135
+ # server, potentially throwing a
136
+ # HtmlRender::Renderers::HTTPRenderer::ServerError if the render fails.
137
+ # It will return an HtmlRender::RenderTest::Result.
138
+ class DirectoryRenderTest
139
+ attr_reader :test_path, :run_path
140
+
141
+ def initialize(test_path, run_path, &block)
142
+ @test_path = test_path
143
+ @run_path = run_path
144
+
145
+ yield(self) if block_given?
146
+ end
147
+
148
+ def html
149
+ @html ||= File.open(html_path) do |f|
150
+ f.read
151
+ end
152
+ end
153
+
154
+ def run(servers_hash)
155
+ clear_run_directory
156
+
157
+ begin
158
+ batch = HTMLRender::RenderBatches::HTTPRenderBatch.new(servers_hash)
159
+ batch.render_html_to_directory(html, run_path)
160
+ rescue Exception => e
161
+ clear_run_directory
162
+ raise e
163
+ end
164
+
165
+ last_result
166
+ end
167
+
168
+ # Returns the results of the last test. If the "valid" results changed
169
+ # since the last time run() was called, then last_result.pass? may
170
+ # return a different value than before (since it will compare the
171
+ # previously-generated actual .png's with the newer expected .png's).
172
+ def last_result
173
+ DirectoryResult.new(run_path, valid_path, canonical_path)
174
+ end
175
+
176
+ private
177
+
178
+ def clear_run_directory
179
+ FileUtils.rm(Dir.glob(File.join(run_path, '*.png')))
180
+ end
181
+
182
+ def html_path
183
+ File.join(test_path, 'html.html')
184
+ end
185
+
186
+ def canonical_path
187
+ File.join(test_path, 'canonical.png')
188
+ end
189
+
190
+ def valid_path
191
+ File.join(test_path, 'valid')
192
+ end
193
+ end
194
+ end
@@ -15,6 +15,8 @@ module HTMLRender::Renderers
15
15
  # One should POST the HTML to the given URL, and the server should
16
16
  # respond with a PNG image.
17
17
  class HTTPRenderer < Base
18
+ class ServerError < Exception; end
19
+
18
20
  attr_accessor :url
19
21
 
20
22
  def initialize(url)
@@ -24,9 +26,12 @@ module HTMLRender::Renderers
24
26
  def render(html)
25
27
  client = HTTPClient.new
26
28
 
27
- response = client.post(url, html)
29
+ begin
30
+ response = client.post(url, html)
31
+ end
32
+
28
33
  if response.status != 200
29
- raise Exception.new("Unexpected HTTP server response from #{url}: #{response.inspect}")
34
+ raise ServerError.new("Unexpected HTTP server response from #{url}: #{response.inspect}")
30
35
  end
31
36
 
32
37
  HTMLRender::Images::PNGImage.new(response.content)
data/lib/html_render.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  require 'html_render/images'
2
2
  require 'html_render/renderers'
3
3
  require 'html_render/render_batches'
4
+ require 'html_render/render_test'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adamh-html_render
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Hooper
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-06 00:00:00 -08:00
12
+ date: 2009-04-01 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -34,7 +34,7 @@ dependencies:
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: echoe
37
- type: :runtime
37
+ type: :development
38
38
  version_requirement:
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
@@ -54,6 +54,8 @@ extra_rdoc_files:
54
54
  - lib/html_render/render_batches.rb
55
55
  - lib/html_render/renderers.rb
56
56
  - lib/html_render/images.rb
57
+ - lib/html_render/render_test.rb
58
+ - lib/html_render/render_test/rails.rb
57
59
  files:
58
60
  - README.rdoc
59
61
  - Rakefile
@@ -62,6 +64,8 @@ files:
62
64
  - lib/html_render/render_batches.rb
63
65
  - lib/html_render/renderers.rb
64
66
  - lib/html_render/images.rb
67
+ - lib/html_render/render_test.rb
68
+ - lib/html_render/render_test/rails.rb
65
69
  - Manifest
66
70
  has_rdoc: true
67
71
  homepage: http://adamhooper.com/eng