pdfkit 0.4.2 → 0.5.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/pdfkit.gemspec CHANGED
@@ -1,83 +1,27 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
1
  # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "pdfkit/version"
5
4
 
6
5
  Gem::Specification.new do |s|
7
- s.name = %q{pdfkit}
8
- s.version = "0.4.2"
6
+ s.name = "pdfkit"
7
+ s.version = PDFKit::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Jared Pace", "Relevance"]
10
+ s.email = ["jared@codewordstudios.com"]
11
+ s.homepage = "http://github.com/jdpace/PDFKit"
12
+ s.summary = "HTML+CSS -> PDF"
13
+ s.description = "Uses wkhtmltopdf to create PDFs using HTML"
9
14
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["jdpace"]
12
- s.date = %q{2010-07-23}
13
- s.default_executable = %q{pdfkit}
14
- s.description = %q{Uses wkhtmltopdf to create PDFs using HTML}
15
- s.email = %q{jared@codewordstudios.com}
16
- s.executables = ["pdfkit"]
17
- s.extra_rdoc_files = [
18
- "LICENSE",
19
- "README.md"
20
- ]
21
- s.files = [
22
- ".document",
23
- ".gitignore",
24
- ".rspec",
25
- "LICENSE",
26
- "POST_INSTALL",
27
- "README.md",
28
- "Rakefile",
29
- "VERSION",
30
- "bin/pdfkit",
31
- "lib/pdfkit.rb",
32
- "lib/pdfkit/configuration.rb",
33
- "lib/pdfkit/middleware.rb",
34
- "lib/pdfkit/pdfkit.rb",
35
- "lib/pdfkit/source.rb",
36
- "pdfkit.gemspec",
37
- "spec/fixtures/example.css",
38
- "spec/fixtures/example.html",
39
- "spec/middleware_spec.rb",
40
- "spec/pdfkit_spec.rb",
41
- "spec/source_spec.rb",
42
- "spec/spec_helper.rb"
43
- ]
44
- s.homepage = %q{http://github.com/jdpace/PDFKit}
45
- s.post_install_message = %q{******************************************************************
15
+ s.rubyforge_project = "pdfkit"
46
16
 
47
- Now install wkhtmltopdf binaries:
48
- Global: sudo `which pdfkit` --install-wkhtmltopdf
49
- or inside RVM folder: export TO=`which pdfkit | sed 's:/pdfkit:/wkhtmltopdf:'` && pdfkit --install-wkhtmltopdf
50
- (run pdfkit --help to see more options)
51
-
52
- ******************************************************************}
53
- s.rdoc_options = ["--charset=UTF-8"]
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
54
20
  s.require_paths = ["lib"]
55
- s.rubygems_version = %q{1.3.7}
56
- s.summary = %q{HTML+CSS -> PDF}
57
- s.test_files = [
58
- "spec/middleware_spec.rb",
59
- "spec/pdfkit_spec.rb",
60
- "spec/source_spec.rb",
61
- "spec/spec_helper.rb"
62
- ]
63
-
64
- if s.respond_to? :specification_version then
65
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
66
- s.specification_version = 3
67
21
 
68
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
69
- s.add_development_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
70
- s.add_development_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
71
- s.add_development_dependency(%q<mocha>, [">= 0"])
72
- else
73
- s.add_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
74
- s.add_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
75
- s.add_dependency(%q<mocha>, [">= 0"])
76
- end
77
- else
78
- s.add_dependency(%q<rspec>, ["~> 2.0.0.beta.8"])
79
- s.add_dependency(%q<rspec-core>, ["~> 2.0.0.beta.8"])
80
- s.add_dependency(%q<mocha>, [">= 0"])
81
- end
22
+ # Developmnet Dependencies
23
+ s.add_development_dependency(%q<rspec>, ["~> 2.2.0"])
24
+ s.add_development_dependency(%q<mocha>, [">= 0.9.10"])
25
+ s.add_development_dependency(%q<rack-test>, [">= 0.5.6"])
82
26
  end
83
27
 
@@ -1,17 +1,142 @@
1
1
  require 'spec_helper'
2
2
 
3
+ def app; Rack::Lint.new(@app); end
4
+
5
+ def mock_app(options = {}, conditions = {})
6
+ main_app = lambda { |env|
7
+ @env = env
8
+ headers = {'Content-Type' => "text/html"}
9
+ [200, headers, @body || ['Hello world!']]
10
+ }
11
+
12
+ builder = Rack::Builder.new
13
+ builder.use PDFKit::Middleware, options, conditions
14
+ builder.run main_app
15
+ @app = builder.to_app
16
+ end
17
+
3
18
  describe PDFKit::Middleware do
19
+
20
+ describe "#call" do
21
+ describe "conditions" do
22
+ describe ":only" do
23
+
24
+ describe "regex" do
25
+ describe "one" do
26
+ before { mock_app({}, :only => %r[^/public]) }
27
+
28
+ context "matching" do
29
+ specify do
30
+ get 'http://www.example.org/public/test.pdf'
31
+ last_response.headers["Content-Type"].should == "application/pdf"
32
+ last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
33
+ end
34
+ end
35
+
36
+ context "not matching" do
37
+ specify do
38
+ get 'http://www.example.org/secret/test.pdf'
39
+ last_response.headers["Content-Type"].should == "text/html"
40
+ last_response.body.should == "Hello world!"
41
+ end
42
+ end
43
+ end # one regex
44
+
45
+ describe "multiple" do
46
+ before { mock_app({}, :only => [%r[^/invoice], %r[^/public]]) }
47
+
48
+ context "matching" do
49
+ specify do
50
+ get 'http://www.example.org/public/test.pdf'
51
+ last_response.headers["Content-Type"].should == "application/pdf"
52
+ last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
53
+ end
54
+ end
55
+
56
+ context "not matching" do
57
+ specify do
58
+ get 'http://www.example.org/secret/test.pdf'
59
+ last_response.headers["Content-Type"].should == "text/html"
60
+ last_response.body.should == "Hello world!"
61
+ end
62
+ end
63
+ end # multiple regex
64
+ end # regex
65
+
66
+ describe "string" do
67
+ describe "one" do
68
+ before { mock_app({}, :only => '/public') }
69
+
70
+ context "matching" do
71
+ specify do
72
+ get 'http://www.example.org/public/test.pdf'
73
+ last_response.headers["Content-Type"].should == "application/pdf"
74
+ last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
75
+ end
76
+ end
77
+
78
+ context "not matching" do
79
+ specify do
80
+ get 'http://www.example.org/secret/test.pdf'
81
+ last_response.headers["Content-Type"].should == "text/html"
82
+ last_response.body.should == "Hello world!"
83
+ end
84
+ end
85
+ end # one string
86
+
87
+ describe "multiple" do
88
+ before { mock_app({}, :only => ['/invoice', '/public']) }
89
+
90
+ context "matching" do
91
+ specify do
92
+ get 'http://www.example.org/public/test.pdf'
93
+ last_response.headers["Content-Type"].should == "application/pdf"
94
+ last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
95
+ end
96
+ end
97
+
98
+ context "not matching" do
99
+ specify do
100
+ get 'http://www.example.org/secret/test.pdf'
101
+ last_response.headers["Content-Type"].should == "text/html"
102
+ last_response.body.should == "Hello world!"
103
+ end
104
+ end
105
+ end # multiple string
106
+ end # string
107
+
108
+ end
109
+ end
110
+
111
+ describe "remove .pdf from PATH_INFO and REQUEST_URI" do
112
+ before { mock_app }
113
+
114
+ context "matching" do
115
+ specify do
116
+ get 'http://www.example.org/public/file.pdf'
117
+ @env["PATH_INFO"].should == "/public/file"
118
+ @env["REQUEST_URI"].should == "/public/file"
119
+ end
120
+ specify do
121
+ get 'http://www.example.org/public/file.txt'
122
+ @env["PATH_INFO"].should == "/public/file.txt"
123
+ @env["REQUEST_URI"].should be_nil
124
+ end
125
+ end
126
+
127
+ end
128
+ end
129
+
4
130
  describe "#translate_paths" do
5
-
6
131
  before do
7
132
  @pdf = PDFKit::Middleware.new({})
8
- @env = {'REQUEST_URI' => 'http://example.com/document.pdf', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.com'}
133
+ @env = { 'REQUEST_URI' => 'http://example.com/document.pdf', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.com' }
9
134
  end
10
135
 
11
136
  it "should correctly parse relative url with single quotes" do
12
- @body = %{<html><head><link href='/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src='/test.png' /></body></html>}
137
+ @body = %{<html><head><link href='/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src="/test.png" /></body></html>}
13
138
  body = @pdf.send :translate_paths, @body, @env
14
- body.should == "<html><head><link href=\"http://example.com/stylesheets/application.css\" media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src=\"http://example.com/test.png\" /></body></html>"
139
+ body.should == "<html><head><link href='http://example.com/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src=\"http://example.com/test.png\" /></body></html>"
15
140
  end
16
141
 
17
142
  it "should correctly parse relative url with double quotes" do
@@ -26,24 +151,5 @@ describe PDFKit::Middleware do
26
151
  body.should == "NO MATCH"
27
152
  end
28
153
  end
29
-
30
- describe "#set_request_to_render_as_pdf" do
31
-
32
- before do
33
- @pdf = PDFKit::Middleware.new({})
34
154
 
35
- @pdf_env = {'PATH_INFO' => Pathname.new("file.pdf"), 'REQUEST_URI' => Pathname.new("file.pdf")}
36
- @non_pdf_env = {'PATH_INFO' => Pathname.new("file.txt"), 'REQUEST_URI' => Pathname.new("file.txt")}
37
- end
38
-
39
- it "should replace .pdf in PATH_INFO when the extname is .pdf" do
40
- @pdf.send :set_request_to_render_as_pdf, @pdf_env
41
- @pdf_env['PATH_INFO'].should == "file"
42
- end
43
-
44
- it "should replace .pdf in REQUEST_URI when the extname is .pdf" do
45
- @pdf.send :set_request_to_render_as_pdf, @pdf_env
46
- @pdf_env['REQUEST_URI'].should == "file"
47
- end
48
- end
49
155
  end
data/spec/pdfkit_spec.rb CHANGED
@@ -1,79 +1,95 @@
1
+ #encoding: UTF-8
1
2
  require 'spec_helper'
2
3
 
3
4
  describe PDFKit do
4
-
5
+
5
6
  context "initialization" do
6
7
  it "should accept HTML as the source" do
7
8
  pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
8
9
  pdfkit.source.should be_html
9
10
  pdfkit.source.to_s.should == '<h1>Oh Hai</h1>'
10
11
  end
11
-
12
+
12
13
  it "should accept a URL as the source" do
13
14
  pdfkit = PDFKit.new('http://google.com')
14
15
  pdfkit.source.should be_url
15
16
  pdfkit.source.to_s.should == 'http://google.com'
16
17
  end
17
-
18
+
18
19
  it "should accept a File as the source" do
19
20
  file_path = File.join(SPEC_ROOT,'fixtures','example.html')
20
21
  pdfkit = PDFKit.new(File.new(file_path))
21
22
  pdfkit.source.should be_file
22
23
  pdfkit.source.to_s.should == file_path
23
24
  end
24
-
25
+
25
26
  it "should parse the options into a cmd line friedly format" do
26
27
  pdfkit = PDFKit.new('html', :page_size => 'Letter')
27
28
  pdfkit.options.should have_key('--page-size')
28
29
  end
29
-
30
+
30
31
  it "should provide default options" do
31
32
  pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
32
- ['--disable-smart-shrinking', '--margin-top', '--margin-right', '--margin-bottom', '--margin-left'].each do |option|
33
+ ['--margin-top', '--margin-right', '--margin-bottom', '--margin-left'].each do |option|
33
34
  pdfkit.options.should have_key(option)
34
35
  end
35
36
  end
36
-
37
+
38
+ it "should default to 'UTF-8' encoding" do
39
+ pdfkit = PDFKit.new('Captación')
40
+ pdfkit.options['--encoding'].should == 'UTF-8'
41
+ end
42
+
37
43
  it "should not have any stylesheedt by default" do
38
44
  pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
39
45
  pdfkit.stylesheets.should be_empty
40
46
  end
41
47
  end
42
-
48
+
43
49
  context "command" do
44
50
  it "should contstruct the correct command" do
45
51
  pdfkit = PDFKit.new('html', :page_size => 'Letter', :toc_l1_font_size => 12)
46
52
  pdfkit.command[0].should include('wkhtmltopdf')
47
- pdfkit.command[pdfkit.command.index('--page-size') + 1].should == 'Letter'
48
- pdfkit.command[pdfkit.command.index('--toc-l1-font-size') + 1].should == '12'
53
+ pdfkit.command[pdfkit.command.index('"--page-size"') + 1].should == '"Letter"'
54
+ pdfkit.command[pdfkit.command.index('"--toc-l1-font-size"') + 1].should == '"12"'
49
55
  end
50
-
56
+
51
57
  it "will not include default options it is told to omit" do
58
+ PDFKit.configure do |config|
59
+ config.default_options[:disable_smart_shrinking] = true
60
+ end
61
+
52
62
  pdfkit = PDFKit.new('html')
53
- pdfkit.command.should include('--disable-smart-shrinking')
63
+ pdfkit.command.should include('"--disable-smart-shrinking"')
54
64
  pdfkit = PDFKit.new('html', :disable_smart_shrinking => false)
55
- pdfkit.command.should_not include('--disable-smart-shrinking')
65
+ pdfkit.command.should_not include('"--disable-smart-shrinking"')
56
66
  end
57
-
67
+
58
68
  it "should encapsulate string arguments in quotes" do
59
69
  pdfkit = PDFKit.new('html', :header_center => "foo [page]")
60
- pdfkit.command[pdfkit.command.index('--header-center') + 1].should == 'foo [page]'
70
+ pdfkit.command[pdfkit.command.index('"--header-center"') + 1].should == '"foo [page]"'
61
71
  end
62
-
72
+
63
73
  it "read the source from stdin if it is html" do
64
74
  pdfkit = PDFKit.new('html')
65
- pdfkit.command[-2..-1].should == ['-', '-']
75
+ pdfkit.command[-2..-1].should == ['"-"', '"-"']
66
76
  end
67
-
77
+
68
78
  it "specify the URL to the source if it is a url" do
69
79
  pdfkit = PDFKit.new('http://google.com')
70
- pdfkit.command[-2..-1].should == ['http://google.com', '-']
80
+ pdfkit.command[-2..-1].should == ['"http://google.com"', '"-"']
71
81
  end
72
-
82
+
73
83
  it "should specify the path to the source if it is a file" do
74
84
  file_path = File.join(SPEC_ROOT,'fixtures','example.html')
75
85
  pdfkit = PDFKit.new(File.new(file_path))
76
- pdfkit.command[-2..-1].should == [file_path, '-']
86
+ pdfkit.command[-2..-1].should == [%Q{"#{file_path}"}, '"-"']
87
+ end
88
+
89
+ it "should specify the path for the ouput if a apth is given" do
90
+ file_path = "/path/to/output.pdf"
91
+ pdfkit = PDFKit.new("html")
92
+ pdfkit.command(file_path).last.should == %Q{"#{file_path}"}
77
93
  end
78
94
 
79
95
  it "should detect special pdfkit meta tags" do
@@ -86,30 +102,30 @@ describe PDFKit do
86
102
  </html>
87
103
  }
88
104
  pdfkit = PDFKit.new(body)
89
- pdfkit.command[pdfkit.command.index('--page-size') + 1].should == 'Legal'
90
- pdfkit.command[pdfkit.command.index('--orientation') + 1].should == 'Landscape'
105
+ pdfkit.command[pdfkit.command.index('"--page-size"') + 1].should == '"Legal"'
106
+ pdfkit.command[pdfkit.command.index('"--orientation"') + 1].should == '"Landscape"'
91
107
  end
92
108
  end
93
-
109
+
94
110
  context "#to_pdf" do
95
111
  it "should generate a PDF of the HTML" do
96
112
  pdfkit = PDFKit.new('html', :page_size => 'Letter')
97
113
  pdf = pdfkit.to_pdf
98
114
  pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
99
115
  end
100
-
116
+
101
117
  it "should generate a PDF with a numerical parameter" do
102
118
  pdfkit = PDFKit.new('html', :header_spacing => 1)
103
119
  pdf = pdfkit.to_pdf
104
120
  pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
105
121
  end
106
-
122
+
107
123
  it "should generate a PDF with a symbol parameter" do
108
124
  pdfkit = PDFKit.new('html', :page_size => :Letter)
109
125
  pdf = pdfkit.to_pdf
110
126
  pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
111
127
  end
112
-
128
+
113
129
  it "should have the stylesheet added to the head if it has one" do
114
130
  pdfkit = PDFKit.new("<html><head></head><body>Hai!</body></html>")
115
131
  css = File.join(SPEC_ROOT,'fixtures','example.css')
@@ -117,7 +133,7 @@ describe PDFKit do
117
133
  pdfkit.to_pdf
118
134
  pdfkit.source.to_s.should include("<style>#{File.read(css)}</style>")
119
135
  end
120
-
136
+
121
137
  it "should prepend style tags if the HTML doesn't have a head tag" do
122
138
  pdfkit = PDFKit.new("<html><body>Hai!</body></html>")
123
139
  css = File.join(SPEC_ROOT,'fixtures','example.css')
@@ -125,7 +141,7 @@ describe PDFKit do
125
141
  pdfkit.to_pdf
126
142
  pdfkit.source.to_s.should include("<style>#{File.read(css)}</style><html>")
127
143
  end
128
-
144
+
129
145
  it "should throw an error if the source is not html and stylesheets have been added" do
130
146
  pdfkit = PDFKit.new('http://google.com')
131
147
  css = File.join(SPEC_ROOT,'fixtures','example.css')
@@ -133,41 +149,40 @@ describe PDFKit do
133
149
  lambda { pdfkit.to_pdf }.should raise_error(PDFKit::ImproperSourceError)
134
150
  end
135
151
  end
136
-
152
+
137
153
  context "#to_file" do
138
154
  before do
139
155
  @file_path = File.join(SPEC_ROOT,'fixtures','test.pdf')
140
156
  File.delete(@file_path) if File.exist?(@file_path)
141
157
  end
142
-
158
+
143
159
  after do
144
160
  File.delete(@file_path)
145
161
  end
146
-
162
+
147
163
  it "should create a file with the PDF as content" do
148
164
  pdfkit = PDFKit.new('html', :page_size => 'Letter')
149
- pdfkit.expects(:to_pdf).returns('PDF')
150
165
  file = pdfkit.to_file(@file_path)
151
166
  file.should be_instance_of(File)
152
- File.read(file.path).should == 'PDF'
167
+ File.read(file.path)[0...4].should == "%PDF" # PDF Signature at beginning of file
153
168
  end
154
169
  end
155
-
170
+
156
171
  context "security" do
157
172
  before do
158
173
  @test_path = File.join(SPEC_ROOT,'fixtures','security-oops')
159
174
  File.delete(@test_path) if File.exist?(@test_path)
160
175
  end
161
-
176
+
162
177
  after do
163
178
  File.delete(@test_path) if File.exist?(@test_path)
164
179
  end
165
-
180
+
166
181
  it "should not allow shell injection in options" do
167
182
  pdfkit = PDFKit.new('html', :header_center => "a title\"; touch #{@test_path} #")
168
183
  pdfkit.to_pdf
169
184
  File.exist?(@test_path).should be_false
170
185
  end
171
186
  end
172
-
187
+
173
188
  end
data/spec/source_spec.rb CHANGED
@@ -17,6 +17,11 @@ describe PDFKit::Source do
17
17
  source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
18
18
  source.should_not be_url
19
19
  end
20
+
21
+ it "should return false if passed HTML with embedded urls at the beginning of a line" do
22
+ source = PDFKit::Source.new("<blink>Oh Hai!</blink>\nhttp://www.google.com")
23
+ source.should_not be_url
24
+ end
20
25
  end
21
26
 
22
27
  describe "#file?" do
data/spec/spec_helper.rb CHANGED
@@ -6,13 +6,9 @@ require 'rspec'
6
6
  require 'rspec/autorun'
7
7
  require 'mocha'
8
8
  require 'rack'
9
+ require 'rack/test'
10
+ require 'custom_wkhtmltopdf_path' if File.exists?(File.join(SPEC_ROOT, 'custom_wkhtmltopdf_path.rb'))
9
11
 
10
12
  RSpec.configure do |config|
11
-
12
- config.before do
13
- PDFKit.any_instance.stubs(:wkhtmltopdf).returns(
14
- File.join(SPEC_ROOT,'..','bin','wkhtmltopdf-proxy')
15
- )
16
- end
17
-
13
+ include Rack::Test::Methods
18
14
  end