pdf_tempura 0.0.2

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.
Files changed (80) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +342 -0
  8. data/Rakefile +1 -0
  9. data/example/my_pdf.rb +37 -0
  10. data/lib/pdf_tempura.rb +8 -0
  11. data/lib/pdf_tempura/document.rb +121 -0
  12. data/lib/pdf_tempura/document/boxed_characters.rb +70 -0
  13. data/lib/pdf_tempura/document/boxed_characters/groups.rb +53 -0
  14. data/lib/pdf_tempura/document/character_field.rb +37 -0
  15. data/lib/pdf_tempura/document/checkbox_field.rb +15 -0
  16. data/lib/pdf_tempura/document/default_commands.rb +40 -0
  17. data/lib/pdf_tempura/document/field/base.rb +55 -0
  18. data/lib/pdf_tempura/document/field_set.rb +51 -0
  19. data/lib/pdf_tempura/document/page.rb +33 -0
  20. data/lib/pdf_tempura/document/table.rb +95 -0
  21. data/lib/pdf_tempura/document/table/boxed_character_column.rb +20 -0
  22. data/lib/pdf_tempura/document/table/checkbox_column.rb +9 -0
  23. data/lib/pdf_tempura/document/table/column.rb +18 -0
  24. data/lib/pdf_tempura/document/table/spacer.rb +13 -0
  25. data/lib/pdf_tempura/document/table/text_column.rb +9 -0
  26. data/lib/pdf_tempura/document/text_field.rb +18 -0
  27. data/lib/pdf_tempura/document/validation.rb +79 -0
  28. data/lib/pdf_tempura/extensions/hash/stringify_keys.rb +35 -0
  29. data/lib/pdf_tempura/render.rb +18 -0
  30. data/lib/pdf_tempura/render/boxed_characters.rb +42 -0
  31. data/lib/pdf_tempura/render/character_field.rb +49 -0
  32. data/lib/pdf_tempura/render/checkbox_field.rb +35 -0
  33. data/lib/pdf_tempura/render/debug.rb +16 -0
  34. data/lib/pdf_tempura/render/debug/annotation/base.rb +83 -0
  35. data/lib/pdf_tempura/render/debug/character_field_annotation.rb +13 -0
  36. data/lib/pdf_tempura/render/debug/checkbox_field_annotation.rb +24 -0
  37. data/lib/pdf_tempura/render/debug/field_set_annotation.rb +23 -0
  38. data/lib/pdf_tempura/render/debug/grid.rb +59 -0
  39. data/lib/pdf_tempura/render/debug/outside_annotation.rb +42 -0
  40. data/lib/pdf_tempura/render/debug/table_annotation.rb +19 -0
  41. data/lib/pdf_tempura/render/debug/text_field_annotation.rb +42 -0
  42. data/lib/pdf_tempura/render/field.rb +40 -0
  43. data/lib/pdf_tempura/render/field_bounds.rb +26 -0
  44. data/lib/pdf_tempura/render/field_data_mapper.rb +15 -0
  45. data/lib/pdf_tempura/render/field_set.rb +31 -0
  46. data/lib/pdf_tempura/render/option_access.rb +21 -0
  47. data/lib/pdf_tempura/render/page.rb +23 -0
  48. data/lib/pdf_tempura/render/table.rb +35 -0
  49. data/lib/pdf_tempura/render/text_field.rb +13 -0
  50. data/lib/pdf_tempura/renderer.rb +39 -0
  51. data/lib/pdf_tempura/version.rb +3 -0
  52. data/pdf_tempura.gemspec +27 -0
  53. data/spec/assets/sample_pdf_form.odg +0 -0
  54. data/spec/assets/sample_pdf_form.pdf +0 -0
  55. data/spec/integration_spec.rb +88 -0
  56. data/spec/lib/pdf_tempura/document/boxed_characters_spec.rb +125 -0
  57. data/spec/lib/pdf_tempura/document/checkbox_field_spec.rb +54 -0
  58. data/spec/lib/pdf_tempura/document/field_common.rb +12 -0
  59. data/spec/lib/pdf_tempura/document/field_set_spec.rb +38 -0
  60. data/spec/lib/pdf_tempura/document/page_spec.rb +57 -0
  61. data/spec/lib/pdf_tempura/document/table_spec.rb +161 -0
  62. data/spec/lib/pdf_tempura/document/text_field_spec.rb +195 -0
  63. data/spec/lib/pdf_tempura/document_spec.rb +131 -0
  64. data/spec/lib/pdf_tempura/extensions/hash/stringify_keys_spec.rb +42 -0
  65. data/spec/lib/pdf_tempura/render/boxed_characters_spec.rb +68 -0
  66. data/spec/lib/pdf_tempura/render/checkbox_field_spec.rb +39 -0
  67. data/spec/lib/pdf_tempura/render/debug/annotation_renderer/base_spec.rb +45 -0
  68. data/spec/lib/pdf_tempura/render/debug/checkbox_field_annotation_spec.rb +45 -0
  69. data/spec/lib/pdf_tempura/render/debug/grid_spec.rb +15 -0
  70. data/spec/lib/pdf_tempura/render/debug/text_field_annotation_spec.rb +46 -0
  71. data/spec/lib/pdf_tempura/render/field_data_mapper_spec.rb +31 -0
  72. data/spec/lib/pdf_tempura/render/field_set_spec.rb +41 -0
  73. data/spec/lib/pdf_tempura/render/field_spec.rb +37 -0
  74. data/spec/lib/pdf_tempura/render/page_spec.rb +77 -0
  75. data/spec/lib/pdf_tempura/render/table_spec.rb +44 -0
  76. data/spec/lib/pdf_tempura/render/text_field_spec.rb +39 -0
  77. data/spec/lib/pdf_tempura/renderer_spec.rb +79 -0
  78. data/spec/spec_helper.rb +29 -0
  79. data/spec/support/shared_examples/field_examples.rb +265 -0
  80. metadata +219 -0
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe PdfTempura::Document do
4
+
5
+ let(:dummy_class) do
6
+ Class.new(described_class)
7
+ end
8
+
9
+ describe "#new" do
10
+ let(:data) do
11
+ {
12
+ 1 => {
13
+ first_name: "Stan",
14
+ surname: "Smith",
15
+ company: "CIA",
16
+ address: "The Pentagon, Washington, DC"
17
+ },
18
+ 2 => {
19
+ emergency_contact: "Francine Smith",
20
+ phone_number: "123-456-7890"
21
+ },
22
+ "3" => {
23
+ pin: "123456"
24
+ }
25
+ }
26
+ end
27
+
28
+ before :each do
29
+ dummy_class.page(1){}
30
+ dummy_class.page(2){}
31
+ dummy_class.page(3){}
32
+ end
33
+
34
+ it "loads the data into each correct page" do
35
+ document = dummy_class.new(data)
36
+
37
+ document.pages.first.data.should == {
38
+ "first_name" => "Stan",
39
+ "surname" => "Smith",
40
+ "company" => "CIA",
41
+ "address" => "The Pentagon, Washington, DC"
42
+ }
43
+
44
+ document.pages[1].data.should == {
45
+ "emergency_contact" => "Francine Smith",
46
+ "phone_number" => "123-456-7890"
47
+ }
48
+
49
+ document.pages[2].data.should == {
50
+ "pin" => "123456"
51
+ }
52
+ end
53
+
54
+ it "doesn't modify the class level pages" do
55
+ dummy_class.new(data)
56
+ dummy_class.pages.first.data.should == {}
57
+ dummy_class.pages.last.data.should == {}
58
+ end
59
+
60
+ context "too many pages" do
61
+ let(:data) do
62
+ {
63
+ 1 => {},
64
+ 2 => {},
65
+ 3 => {},
66
+ 4 => {}
67
+ }
68
+ end
69
+ it "complains" do
70
+ expect { dummy_class.new(data)}.to raise_exception("There are more pages in the data than pages defined. Use 'repeatable' to repeat template pages in the document class.")
71
+ end
72
+ end
73
+ end
74
+
75
+ describe ".template" do
76
+ it "sets the template file path" do
77
+ dummy_class.template "/some/path/to/template.pdf"
78
+ dummy_class.template_file_path.should == "/some/path/to/template.pdf"
79
+ end
80
+
81
+ it "raises an argument error if you send it something that's not a string" do
82
+ expect{
83
+ dummy_class.template [123]
84
+ }.to raise_error ArgumentError, "Template path must be a string."
85
+ end
86
+ end
87
+
88
+ describe ".page" do
89
+ let(:page){ PdfTempura::Document::Page.new(200) }
90
+
91
+ it "yield a page object" do
92
+ expect{ |block|
93
+ dummy_class.page(200, &block)
94
+ }.to yield_with_args(page)
95
+ end
96
+
97
+ it "passed method calls on to the new page object" do
98
+ PdfTempura::Document::Page.any_instance.should_receive(:fields)
99
+
100
+ dummy_class.page(200) do
101
+ fields
102
+ end
103
+ end
104
+
105
+ it "adds the page object to the pages list" do
106
+ expect{
107
+ dummy_class.page(200){}
108
+ }.to change(dummy_class.pages, :count).by(1)
109
+ end
110
+ end
111
+
112
+ describe ".pages" do
113
+ it "returns an array" do
114
+ dummy_class.pages.should be_a(Array)
115
+ end
116
+ end
117
+
118
+ describe ".debug" do
119
+ it "stores the debug options" do
120
+ dummy_class.debug :grid, :outlines
121
+ dummy_class.debug_options.should == [:grid, :outlines]
122
+ end
123
+ end
124
+
125
+ describe ".debug_options" do
126
+ it "returns an array" do
127
+ dummy_class.pages.should be_a(Array)
128
+ end
129
+ end
130
+
131
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe PdfTempura::Extensions::Hash::StringifyKeys do
4
+
5
+ subject do
6
+ {
7
+ foo: true,
8
+ bar: {
9
+ blah: "abc"
10
+ },
11
+ woo: [
12
+ 1,
13
+ {
14
+ blorgh: false
15
+ }
16
+ ]
17
+ }.extend(described_class)
18
+ end
19
+
20
+ describe "#stringify_keys" do
21
+ example do
22
+ result = subject.stringify_keys
23
+ result["foo"].should be_true
24
+ result["bar"].should == { "blah" => "abc" }
25
+ result["woo"].should == [1, { "blorgh" => false }]
26
+
27
+ subject["foo"].should be_nil
28
+ subject["bar"].should be_nil
29
+ subject["woo"].should be_nil
30
+ end
31
+ end
32
+
33
+ describe "#stringify_keys!" do
34
+ example do
35
+ subject.stringify_keys!
36
+ subject["foo"].should be_true
37
+ subject["bar"].should == { "blah" => "abc" }
38
+ subject["woo"].should == [1, { "blorgh" => false }]
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe PdfTempura::Render::BoxedCharacters do
4
+
5
+ let(:field_options) {{box_width: 10, box_spacing: 2}}
6
+ let(:field) {
7
+ PdfTempura::Document::BoxedCharacters.new(:pin,[0,0],20,field_options) do
8
+ characters 2
9
+ space 2
10
+ characters 8
11
+ space 2
12
+ characters 2
13
+ end
14
+ }
15
+ let(:data) { "228888888822" }
16
+ let(:pdf) { Prawn::Document.new }
17
+ let(:options) { {} }
18
+
19
+ describe "init" do
20
+ example do
21
+
22
+ expect {
23
+ described_class.new(field, data, options)
24
+ }.not_to raise_exception
25
+ end
26
+ end
27
+
28
+ describe "render" do
29
+
30
+ context "with appropriate data" do
31
+ it "renders each field with the appropriate data" do
32
+ expect {
33
+ described_class.new(field,data,options).render(pdf)
34
+ }.not_to raise_exception
35
+ end
36
+ end
37
+
38
+ context "with nil data" do
39
+ let(:data) {nil}
40
+ it "assumes an empty string and still renders without error" do
41
+ expect {
42
+ described_class.new(field,data,options).render(pdf)
43
+ }.not_to raise_exception
44
+ end
45
+ end
46
+
47
+ context "with inappropriate data" do
48
+ let(:data) {"123456789101112"}
49
+ it "throws an argument error if truncate not specified" do
50
+ expect {
51
+ described_class.new(field,data,options).render(pdf)
52
+ }.to raise_error ArgumentError, "Data for pin must be exactly 12 characters or use the truncate option."
53
+ end
54
+
55
+ context "when truncate is specified" do
56
+ let(:field_options) {{box_width: 10, box_spacing: 2, truncate: true}}
57
+ it "renders without error" do
58
+ expect {
59
+ described_class.new(field,data,options).render(pdf)
60
+ }.not_to raise_exception
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+
67
+ end
68
+
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe PdfTempura::Render::CheckboxField do
4
+
5
+ let(:field) { PdfTempura::Document::CheckboxField.new("foo", [0,0], [100,100]) }
6
+ let(:options) { {} }
7
+ let(:pdf) { Prawn::Document.new }
8
+
9
+ describe "initialize" do
10
+ example do
11
+ expect {
12
+ described_class.new(field, "foo", options)
13
+ }.not_to raise_exception
14
+ end
15
+ end
16
+
17
+ describe "#render" do
18
+
19
+ subject { described_class.new(field, "foo", options) }
20
+
21
+ describe "calling the annotation drawing code when enabled" do
22
+ let(:options) do
23
+ {
24
+ :debug => [:outlines]
25
+ }
26
+ end
27
+
28
+ let(:annotation_renderer) { double(:annotation_renderer) }
29
+
30
+ example do
31
+ PdfTempura::Render::Debug::CheckboxFieldAnnotation.should_receive(:new).with(field).and_return(annotation_renderer)
32
+ annotation_renderer.should_receive(:render).with(pdf)
33
+ subject.render(pdf)
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe PdfTempura::Render::Debug::Annotation::Base do
4
+
5
+ let(:pdf) { Prawn::Document.new }
6
+ let(:field) { PdfTempura::Document::TextField.new("foo", [0,0], [100,100]) }
7
+
8
+ subject { described_class.new(field) }
9
+
10
+ describe "#render" do
11
+ context "if field_options is not defined" do
12
+ example do
13
+ expect{
14
+ subject.render(pdf)
15
+ }.to raise_error NotImplementedError, "Implement field_options in your subclass."
16
+ end
17
+ end
18
+
19
+ context "if label_options is not defined" do
20
+ before :each do
21
+ subject.stub(:field_options){ {} }
22
+ end
23
+
24
+ example do
25
+ expect{
26
+ subject.render(pdf)
27
+ }.to raise_error NotImplementedError, "Implement label_options in your subclass."
28
+ end
29
+ end
30
+
31
+ context "if both are defined" do
32
+ before :each do
33
+ subject.stub(:field_options){ {} }
34
+ subject.stub(:label_options){ {} }
35
+ end
36
+
37
+ example do
38
+ expect{
39
+ subject.render(pdf)
40
+ }.to_not raise_error
41
+ end
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe PdfTempura::Render::Debug::CheckboxFieldAnnotation do
4
+
5
+ let(:pdf) { Prawn::Document.new }
6
+ let(:field) { PdfTempura::Document::CheckboxField.new("foo", [0,0], [100,100]) }
7
+
8
+ let(:field_options) do
9
+ {
10
+ at: [1, 116],
11
+ width: 400,
12
+ height: 98,
13
+ valign: :top
14
+ }
15
+ end
16
+
17
+ let(:label_options) do
18
+ {
19
+ at: [1, 91],
20
+ width: 98,
21
+ height: 98,
22
+ valign: :bottom,
23
+ align: :left,
24
+ single_line: true
25
+ }
26
+ end
27
+
28
+ subject { described_class.new(field) }
29
+
30
+ describe "#render" do
31
+ example do
32
+ expect{
33
+ subject.render(pdf)
34
+ }.to_not raise_error
35
+ end
36
+
37
+ example do
38
+ pdf.should_receive(:text_box).once.with("x: 0 y: 0 w: 100 h: 100", field_options)
39
+ pdf.should_receive(:text_box).once.with("foo", label_options)
40
+ subject.render(pdf)
41
+ end
42
+ end
43
+
44
+ end
45
+
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe PdfTempura::Render::Debug::Grid do
4
+
5
+ let(:pdf) { Prawn::Document.new }
6
+
7
+ describe "render" do
8
+
9
+ it "takes a pdf document as a param" do
10
+ subject.render(pdf)
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe PdfTempura::Render::Debug::TextFieldAnnotation do
4
+
5
+ let(:pdf) { Prawn::Document.new }
6
+ let(:field) { PdfTempura::Document::TextField.new("foo", [0,0], [100,100]) }
7
+
8
+ let(:field_options) do
9
+ {
10
+ at: [1, 99],
11
+ width: 98,
12
+ height: 98,
13
+ valign: :top,
14
+ single_line: true
15
+ }
16
+ end
17
+
18
+ let(:label_options) do
19
+ {
20
+ at: [1, 99],
21
+ width: 98,
22
+ height: 98,
23
+ valign: :bottom,
24
+ align: :right,
25
+ single_line: true
26
+ }
27
+ end
28
+
29
+ subject { described_class.new(field) }
30
+
31
+ describe "#render" do
32
+ example do
33
+ expect{
34
+ subject.render(pdf)
35
+ }.to_not raise_error
36
+ end
37
+
38
+ example do
39
+ pdf.should_receive(:text_box).once.with("x: 0 y: 0 w: 100 h: 100", field_options)
40
+ pdf.should_receive(:text_box).once.with("foo", label_options)
41
+ subject.render(pdf)
42
+ end
43
+ end
44
+
45
+ end
46
+
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe PdfTempura::Render::FieldDataMapper do
4
+
5
+ let(:fields) do
6
+ [
7
+ PdfTempura::Document::TextField.new("one", [0,0], [0,0]),
8
+ PdfTempura::Document::TextField.new("bar", [0,0], [0,0]),
9
+ PdfTempura::Document::TextField.new("baz", [0,0], [0,0]),
10
+ ]
11
+ end
12
+
13
+ let(:data) do
14
+ {
15
+ "one" => "a1",
16
+ "bar" => "a2",
17
+ "bla" => "a4",
18
+ }
19
+ end
20
+
21
+ describe ".map" do
22
+ example do
23
+ described_class.map(fields, data).should == {
24
+ fields[0] => "a1",
25
+ fields[1] => "a2",
26
+ fields[2] => nil,
27
+ }
28
+ end
29
+ end
30
+
31
+ end