proforma 1.0.0.pre.alpha

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