proforma 1.0.0.pre.alpha

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 (59) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +8 -0
  3. data/.gitignore +4 -0
  4. data/.rubocop.yml +11 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +20 -0
  7. data/CHANGELOG.md +7 -0
  8. data/Gemfile +5 -0
  9. data/Gemfile.lock +105 -0
  10. data/Guardfile +16 -0
  11. data/LICENSE +7 -0
  12. data/README.md +328 -0
  13. data/bin/console +11 -0
  14. data/bin/render +68 -0
  15. data/lib/proforma.rb +38 -0
  16. data/lib/proforma/compiling.rb +12 -0
  17. data/lib/proforma/compiling/aggregation.rb +62 -0
  18. data/lib/proforma/compiling/compilable.rb +21 -0
  19. data/lib/proforma/compiling/counter.rb +35 -0
  20. data/lib/proforma/core_ext/hash.rb +21 -0
  21. data/lib/proforma/document.rb +38 -0
  22. data/lib/proforma/hash_evaluator.rb +40 -0
  23. data/lib/proforma/model_factory.rb +38 -0
  24. data/lib/proforma/modeling.rb +21 -0
  25. data/lib/proforma/modeling/banner.rb +64 -0
  26. data/lib/proforma/modeling/collection.rb +34 -0
  27. data/lib/proforma/modeling/data_table.rb +117 -0
  28. data/lib/proforma/modeling/data_table/aggregator.rb +43 -0
  29. data/lib/proforma/modeling/data_table/column.rb +94 -0
  30. data/lib/proforma/modeling/generic_container.rb +57 -0
  31. data/lib/proforma/modeling/grouping.rb +40 -0
  32. data/lib/proforma/modeling/header.rb +18 -0
  33. data/lib/proforma/modeling/pane.rb +40 -0
  34. data/lib/proforma/modeling/pane/column.rb +68 -0
  35. data/lib/proforma/modeling/pane/line.rb +42 -0
  36. data/lib/proforma/modeling/separator.rb +19 -0
  37. data/lib/proforma/modeling/spacer.rb +19 -0
  38. data/lib/proforma/modeling/table.rb +52 -0
  39. data/lib/proforma/modeling/table/cell.rb +49 -0
  40. data/lib/proforma/modeling/table/row.rb +24 -0
  41. data/lib/proforma/modeling/table/section.rb +23 -0
  42. data/lib/proforma/modeling/text.rb +37 -0
  43. data/lib/proforma/modeling/types.rb +10 -0
  44. data/lib/proforma/modeling/types/align.rb +22 -0
  45. data/lib/proforma/plain_text_renderer.rb +106 -0
  46. data/lib/proforma/prototype.rb +28 -0
  47. data/lib/proforma/template.rb +65 -0
  48. data/lib/proforma/type_factory.rb +44 -0
  49. data/lib/proforma/version.rb +12 -0
  50. data/proforma.gemspec +34 -0
  51. data/spec/fixtures/snapshots/custom_table.yml +55 -0
  52. data/spec/fixtures/snapshots/user_details.yml +101 -0
  53. data/spec/fixtures/snapshots/user_list.yml +143 -0
  54. data/spec/proforma/hash_evaluator_spec.rb +26 -0
  55. data/spec/proforma/modeling/table/cell_spec.rb +26 -0
  56. data/spec/proforma/modeling/table/row_spec.rb +42 -0
  57. data/spec/proforma_spec.rb +230 -0
  58. data/spec/spec_helper.rb +25 -0
  59. metadata +211 -0
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+
12
+ describe Proforma::HashEvaluator do
13
+ let(:hash) { { id: 1, 'first' => 'Matt' } }
14
+
15
+ describe '#value' do
16
+ it 'should work with string keys' do
17
+ expect(subject.value(hash, 'first')).to eq(hash['first'])
18
+ expect(subject.value(hash, :first)).to eq(hash['first'])
19
+ end
20
+
21
+ it 'should work with symbol keys' do
22
+ expect(subject.value(hash, 'id')).to eq(hash[:id])
23
+ expect(subject.value(hash, :id)).to eq(hash[:id])
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+
12
+ describe Proforma::Modeling::Table::Cell do
13
+ it 'should use defaults for all null attributes' do
14
+ cell = described_class.new
15
+
16
+ expect(cell.align).to eq(Proforma::Modeling::Types::Align::LEFT)
17
+ expect(cell.text).to eq('')
18
+ expect(cell.width).to be nil
19
+ end
20
+
21
+ it 'should parse width to float if value is not null' do
22
+ expect(described_class.new(width: '34').width).to eq(34.0)
23
+ expect(described_class.new(width: '').width).to eq(0)
24
+ expect(described_class.new(width: '3a4').width).to eq(3.0)
25
+ end
26
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+
12
+ describe Proforma::Modeling::Table::Row do
13
+ it 'should respond_to cells' do
14
+ expect(subject.respond_to?(:cells)).to be true
15
+ end
16
+
17
+ it 'should respond_to cells=' do
18
+ expect(subject.respond_to?('cells=')).to be true
19
+ end
20
+
21
+ it 'should not respond_to doesnt_exist' do
22
+ expect(subject.respond_to?(:doesnt_exist)).to be false
23
+ end
24
+
25
+ describe '#method_missing' do
26
+ it 'should get cells' do
27
+ expect(subject.cells).to eq([])
28
+ end
29
+
30
+ it 'should set cells' do
31
+ cell = Proforma::Modeling::Table::Cell.new
32
+
33
+ subject.cells = cell
34
+
35
+ expect(subject.cells).to eq([cell])
36
+ end
37
+
38
+ it 'should default to super' do
39
+ expect { subject.doesnt_exist }.to raise_error(NoMethodError)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,230 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+
12
+ describe ::Proforma do
13
+ let(:snapshot_dir) { File.join('spec', 'fixtures', 'snapshots', '*.yml') }
14
+
15
+ let(:snapshot_filenames) { Dir[snapshot_dir] }
16
+
17
+ it 'should process each snapshot successfully' do
18
+ snapshot_filenames.each do |file|
19
+ contents = yaml_read(file)
20
+
21
+ expected_documents = Proforma::Document.array(contents['documents'])
22
+
23
+ actual_documents = described_class.render(
24
+ contents['data'],
25
+ contents['template'],
26
+ evaluator: contents['evaluator'] || Proforma::HashEvaluator.new,
27
+ renderer: contents['renderer'] || Proforma::PlainTextRenderer.new
28
+ )
29
+
30
+ expect(actual_documents).to eq(expected_documents)
31
+ end
32
+ end
33
+
34
+ describe 'README examples' do
35
+ specify 'Getting Started: Rendering a List' do
36
+ data = [
37
+ { id: 1, first: 'Matt', last: 'Smith' },
38
+ { id: 2, first: 'Katie', last: 'Rizzo' },
39
+ { id: 3, first: 'Nathan', last: 'Nathanson' }
40
+ ]
41
+
42
+ template = {
43
+ title: 'User List',
44
+ children: [
45
+ {
46
+ type: 'DataTable',
47
+ columns: [
48
+ { header: 'ID Number', body: '$:id' },
49
+ { header: 'First Name', body: '$:first' },
50
+ { header: 'Last Name', body: '$:last' }
51
+ ]
52
+ }
53
+ ]
54
+ }
55
+
56
+ actual_documents = described_class.render(data, template)
57
+
58
+ expected_documents = [
59
+ Proforma::Document.new(
60
+ contents: "ID Number, First Name, Last Name\n1, Matt, Smith"\
61
+ "\n2, Katie, Rizzo\n3, Nathan, Nathanson\n",
62
+ extension: '.txt',
63
+ title: 'User List'
64
+ )
65
+ ]
66
+
67
+ expect(actual_documents).to eq(expected_documents)
68
+ end
69
+
70
+ specify 'Rendering Records' do
71
+ data = [
72
+ { id: 1, first: 'Matt', last: 'Smith' },
73
+ { id: 2, first: 'Katie', last: 'Rizzo' },
74
+ { id: 3, first: 'Nathan', last: 'Nathanson' }
75
+ ]
76
+
77
+ template = {
78
+ title: 'User Details',
79
+ split: true, # notice the split directive here.
80
+ children: [
81
+ {
82
+ type: 'Pane',
83
+ columns: [
84
+ {
85
+ lines: [
86
+ { label: 'ID Number', value: '$:id' },
87
+ { label: 'First Name', value: '$:first' }
88
+ ]
89
+ },
90
+ {
91
+ lines: [
92
+ { label: 'Last Name', value: '$:last' }
93
+ ]
94
+ }
95
+ ]
96
+ }
97
+ ]
98
+ }
99
+
100
+ actual_documents = Proforma.render(data, template)
101
+
102
+ expected_documents = [
103
+ Proforma::Document.new(
104
+ contents: "ID Number: 1\nFirst Name: Matt\nLast Name: Smith\n",
105
+ extension: '.txt',
106
+ title: 'User Details'
107
+ ),
108
+ Proforma::Document.new(
109
+ contents: "ID Number: 2\nFirst Name: Katie\nLast Name: Rizzo\n",
110
+ extension: '.txt',
111
+ title: 'User Details'
112
+ ),
113
+ Proforma::Document.new(
114
+ contents: "ID Number: 3\nFirst Name: Nathan\nLast Name: Nathanson\n",
115
+ extension: '.txt',
116
+ title: 'User Details'
117
+ )
118
+ ]
119
+
120
+ expect(actual_documents).to eq(expected_documents)
121
+ end
122
+
123
+ specify 'Bringing It All Together' do
124
+ data = [
125
+ {
126
+ id: 1,
127
+ first: 'Matt',
128
+ last: 'Smith',
129
+ phone_numbers: [
130
+ { type: 'Mobile', number: '444-333-2222' },
131
+ { type: 'Home', number: '444-333-2222' }
132
+ ]
133
+ },
134
+ {
135
+ id: 2,
136
+ first: 'Katie',
137
+ last: 'Rizzo',
138
+ phone_numbers: [
139
+ { type: 'Fax', number: '888-777-6666' }
140
+ ]
141
+ },
142
+ {
143
+ id: 3,
144
+ first: 'Nathan',
145
+ last: 'Nathanson',
146
+ phone_numbers: []
147
+ }
148
+ ]
149
+
150
+ template = {
151
+ title: 'User Report',
152
+ children: [
153
+ {
154
+ type: 'Banner',
155
+ title: 'System A',
156
+ details: "555 N. Michigan Ave.\nChicago, IL 55555\n555-555-5555 ext. 5132"
157
+ },
158
+ { type: 'Header', value: 'User List' },
159
+ { type: 'Separator' },
160
+ { type: 'Spacer' },
161
+ {
162
+ type: 'DataTable',
163
+ columns: [
164
+ { header: 'ID Number', body: '$:id' },
165
+ { header: 'First Name', body: '$:first' },
166
+ { header: 'Last Name', body: '$:last' }
167
+ ]
168
+ },
169
+ { type: 'Spacer' },
170
+ {
171
+ type: 'Grouping',
172
+ children: [
173
+ { type: 'Header', value: 'User Details' },
174
+ { type: 'Separator' },
175
+ { type: 'Spacer' },
176
+ {
177
+ type: 'Pane',
178
+ columns: [
179
+ {
180
+ lines: [
181
+ { label: 'ID Number', value: '$:id' },
182
+ { label: 'First Name', value: '$:first' }
183
+ ]
184
+ },
185
+ {
186
+ lines: [
187
+ { label: 'Last Name', value: '$:last' }
188
+ ]
189
+ }
190
+ ]
191
+ },
192
+ {
193
+ type: 'DataTable',
194
+ property: 'phone_numbers',
195
+ columns: [
196
+ { header: 'Type', body: '$:type' },
197
+ { header: 'Number', body: '$:number' }
198
+ ]
199
+ },
200
+ { type: 'Spacer' }
201
+ ]
202
+ }
203
+ ]
204
+ }
205
+
206
+ actual_documents = Proforma.render(data, template)
207
+
208
+ expected_documents = [
209
+ Proforma::Document.new(
210
+ contents: "========================================\nSystem A\n=================="\
211
+ "======================\n555 N. Michigan Ave.\nChicago, IL 55555\n"\
212
+ "555-555-5555 ext. 5132\n========================================\nUSER"\
213
+ " LIST\n----------------------------------------\n\nID Number, First Name,"\
214
+ " Last Name\n1, Matt, Smith\n2, Katie, Rizzo\n3, Nathan, Nathanson\n\nUSER"\
215
+ " DETAILS\n----------------------------------------\n\nID Number: "\
216
+ "1\nFirst Name: Matt\nLast Name: Smith\nType, Number\nMobile, 444-333-2222"\
217
+ "\nHome, 444-333-2222\n\nUSER DETAILS\n-----------------------------------"\
218
+ "-----\n\nID Number: 2\nFirst Name: Katie\nLast Name: Rizzo\nType, Number\n"\
219
+ "Fax, 888-777-6666\n\nUSER DETAILS\n----------------------------------"\
220
+ "------\n\nID Number: 3\nFirst Name: Nathan\nLast Name: "\
221
+ "Nathanson\nType, Number\n\n",
222
+ extension: '.txt',
223
+ title: 'User Report'
224
+ )
225
+ ]
226
+
227
+ expect(actual_documents).to eq(expected_documents)
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2018-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'yaml'
11
+
12
+ require 'pry'
13
+
14
+ require 'simplecov'
15
+ require 'simplecov-console'
16
+ SimpleCov.formatter = SimpleCov::Formatter::Console
17
+ SimpleCov.start
18
+
19
+ require './lib/proforma'
20
+
21
+ def yaml_read(file)
22
+ # rubocop:disable Security/YAMLLoad
23
+ YAML.load(File.open(file))
24
+ # rubocop:enable Security/YAMLLoad
25
+ end
metadata ADDED
@@ -0,0 +1,211 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: proforma
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.pre.alpha
5
+ platform: ruby
6
+ authors:
7
+ - Matthew Ruggio
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-04-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: acts_as_hashable
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: guard-rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.8'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.63.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.63.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.16.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.16.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov-console
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.4.2
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.4.2
111
+ description: |2
112
+ Provide a simple, configurable, and standardized document generation object model.
113
+ The basic premise is to pass in a dataset and configuration and this library will return rendered documents.
114
+ The rendering engines can be plugged in so it leaves this as an extendable/open framework.
115
+ email:
116
+ - mruggio@bluemarblepayroll.com
117
+ executables:
118
+ - console
119
+ - render
120
+ extensions: []
121
+ extra_rdoc_files: []
122
+ files:
123
+ - ".editorconfig"
124
+ - ".gitignore"
125
+ - ".rubocop.yml"
126
+ - ".ruby-version"
127
+ - ".travis.yml"
128
+ - CHANGELOG.md
129
+ - Gemfile
130
+ - Gemfile.lock
131
+ - Guardfile
132
+ - LICENSE
133
+ - README.md
134
+ - bin/console
135
+ - bin/render
136
+ - lib/proforma.rb
137
+ - lib/proforma/compiling.rb
138
+ - lib/proforma/compiling/aggregation.rb
139
+ - lib/proforma/compiling/compilable.rb
140
+ - lib/proforma/compiling/counter.rb
141
+ - lib/proforma/core_ext/hash.rb
142
+ - lib/proforma/document.rb
143
+ - lib/proforma/hash_evaluator.rb
144
+ - lib/proforma/model_factory.rb
145
+ - lib/proforma/modeling.rb
146
+ - lib/proforma/modeling/banner.rb
147
+ - lib/proforma/modeling/collection.rb
148
+ - lib/proforma/modeling/data_table.rb
149
+ - lib/proforma/modeling/data_table/aggregator.rb
150
+ - lib/proforma/modeling/data_table/column.rb
151
+ - lib/proforma/modeling/generic_container.rb
152
+ - lib/proforma/modeling/grouping.rb
153
+ - lib/proforma/modeling/header.rb
154
+ - lib/proforma/modeling/pane.rb
155
+ - lib/proforma/modeling/pane/column.rb
156
+ - lib/proforma/modeling/pane/line.rb
157
+ - lib/proforma/modeling/separator.rb
158
+ - lib/proforma/modeling/spacer.rb
159
+ - lib/proforma/modeling/table.rb
160
+ - lib/proforma/modeling/table/cell.rb
161
+ - lib/proforma/modeling/table/row.rb
162
+ - lib/proforma/modeling/table/section.rb
163
+ - lib/proforma/modeling/text.rb
164
+ - lib/proforma/modeling/types.rb
165
+ - lib/proforma/modeling/types/align.rb
166
+ - lib/proforma/plain_text_renderer.rb
167
+ - lib/proforma/prototype.rb
168
+ - lib/proforma/template.rb
169
+ - lib/proforma/type_factory.rb
170
+ - lib/proforma/version.rb
171
+ - proforma.gemspec
172
+ - spec/fixtures/snapshots/custom_table.yml
173
+ - spec/fixtures/snapshots/user_details.yml
174
+ - spec/fixtures/snapshots/user_list.yml
175
+ - spec/proforma/hash_evaluator_spec.rb
176
+ - spec/proforma/modeling/table/cell_spec.rb
177
+ - spec/proforma/modeling/table/row_spec.rb
178
+ - spec/proforma_spec.rb
179
+ - spec/spec_helper.rb
180
+ homepage: https://github.com/bluemarblepayroll/proforma
181
+ licenses:
182
+ - MIT
183
+ metadata: {}
184
+ post_install_message:
185
+ rdoc_options: []
186
+ require_paths:
187
+ - lib
188
+ required_ruby_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: 2.3.8
193
+ required_rubygems_version: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - ">"
196
+ - !ruby/object:Gem::Version
197
+ version: 1.3.1
198
+ requirements: []
199
+ rubygems_version: 3.0.1
200
+ signing_key:
201
+ specification_version: 4
202
+ summary: Configurable and extendable document rendering engine for datasets
203
+ test_files:
204
+ - spec/fixtures/snapshots/custom_table.yml
205
+ - spec/fixtures/snapshots/user_details.yml
206
+ - spec/fixtures/snapshots/user_list.yml
207
+ - spec/proforma/hash_evaluator_spec.rb
208
+ - spec/proforma/modeling/table/cell_spec.rb
209
+ - spec/proforma/modeling/table/row_spec.rb
210
+ - spec/proforma_spec.rb
211
+ - spec/spec_helper.rb