pdf_tempura 0.0.2

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