proforma-extended-evaluator 1.0.0.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +8 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +11 -0
- data/.ruby-version +1 -0
- data/.travis.yml +20 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +109 -0
- data/Guardfile +16 -0
- data/LICENSE +7 -0
- data/README.md +180 -0
- data/bin/console +11 -0
- data/lib/proforma/extended_evaluator/formatter.rb +129 -0
- data/lib/proforma/extended_evaluator/resolver.rb +51 -0
- data/lib/proforma/extended_evaluator/version.rb +14 -0
- data/lib/proforma/extended_evaluator.rb +49 -0
- data/proforma-extended-evaluator.gemspec +34 -0
- data/spec/proforma/extended_evaluator/formatter_spec.rb +157 -0
- data/spec/proforma/extended_evaluator/resolver_spec.rb +43 -0
- data/spec/proforma/extended_evaluator_spec.rb +130 -0
- data/spec/spec_helper.rb +19 -0
- metadata +183 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 39f0512316231d5d6072f4a26afa88b956d2ae6f1a4b8cf2aa9d45fed2beaba0
|
4
|
+
data.tar.gz: f960a2c8956402fd065466c06468d8e8a3b8103a2f5274c72d35c7f8cbf62eec
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7de610f73e925ab605818eb5db4472d2aa5c93f95772c8a4f90040301c6ba80929734a5196d19a6766991c3fdf42e78d0e991d4304fccb3d9f19705f5c820f9b
|
7
|
+
data.tar.gz: 98ad38935c497f6c3742d944a5084c6161ea8033a52095ea68d45a491553da3deba260da85b8b306fc8856fe085734c4c60b4b9ae27acf66b01c0fbbbab754d7
|
data/.editorconfig
ADDED
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.6.0
|
data/.travis.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
env:
|
2
|
+
global:
|
3
|
+
- CC_TEST_REPORTER_ID=404bf43b14c0d46bf70b7ccfe096d5ad43d9278d965e4a740c0220ce5a2daa00
|
4
|
+
language: ruby
|
5
|
+
rvm:
|
6
|
+
# Build on the latest stable of all supported Rubies (https://www.ruby-lang.org/en/downloads/):
|
7
|
+
- 2.3.8
|
8
|
+
- 2.4.5
|
9
|
+
- 2.5.3
|
10
|
+
- 2.6.0
|
11
|
+
cache: bundler
|
12
|
+
before_script:
|
13
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
14
|
+
- chmod +x ./cc-test-reporter
|
15
|
+
- ./cc-test-reporter before-build
|
16
|
+
script:
|
17
|
+
- bundle exec rubocop
|
18
|
+
- bundle exec rspec spec --format documentation
|
19
|
+
after_script:
|
20
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
proforma-extended-evaluator (1.0.0.pre.alpha)
|
5
|
+
stringento (~> 2)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
acts_as_hashable (1.0.5)
|
11
|
+
ansi (1.5.0)
|
12
|
+
ast (2.4.0)
|
13
|
+
coderay (1.1.2)
|
14
|
+
diff-lcs (1.3)
|
15
|
+
docile (1.3.1)
|
16
|
+
ffi (1.9.25)
|
17
|
+
formatador (0.2.5)
|
18
|
+
guard (2.15.0)
|
19
|
+
formatador (>= 0.2.4)
|
20
|
+
listen (>= 2.7, < 4.0)
|
21
|
+
lumberjack (>= 1.0.12, < 2.0)
|
22
|
+
nenv (~> 0.1)
|
23
|
+
notiffany (~> 0.0)
|
24
|
+
pry (>= 0.9.12)
|
25
|
+
shellany (~> 0.0)
|
26
|
+
thor (>= 0.18.1)
|
27
|
+
guard-compat (1.2.1)
|
28
|
+
guard-rspec (4.7.3)
|
29
|
+
guard (~> 2.1)
|
30
|
+
guard-compat (~> 1.1)
|
31
|
+
rspec (>= 2.99.0, < 4.0)
|
32
|
+
hirb (0.7.3)
|
33
|
+
jaro_winkler (1.5.2)
|
34
|
+
json (2.1.0)
|
35
|
+
listen (3.1.5)
|
36
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
37
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
38
|
+
ruby_dep (~> 1.2)
|
39
|
+
lumberjack (1.0.13)
|
40
|
+
method_source (0.9.2)
|
41
|
+
nenv (0.3.0)
|
42
|
+
notiffany (0.1.1)
|
43
|
+
nenv (~> 0.1)
|
44
|
+
shellany (~> 0.0)
|
45
|
+
parallel (1.13.0)
|
46
|
+
parser (2.6.0.0)
|
47
|
+
ast (~> 2.4.0)
|
48
|
+
powerpack (0.1.2)
|
49
|
+
proforma (1.0.0.pre.alpha)
|
50
|
+
acts_as_hashable (~> 1)
|
51
|
+
pry (0.12.2)
|
52
|
+
coderay (~> 1.1.0)
|
53
|
+
method_source (~> 0.9.0)
|
54
|
+
rainbow (3.0.0)
|
55
|
+
rb-fsevent (0.10.3)
|
56
|
+
rb-inotify (0.9.10)
|
57
|
+
ffi (>= 0.5.0, < 2)
|
58
|
+
rspec (3.8.0)
|
59
|
+
rspec-core (~> 3.8.0)
|
60
|
+
rspec-expectations (~> 3.8.0)
|
61
|
+
rspec-mocks (~> 3.8.0)
|
62
|
+
rspec-core (3.8.0)
|
63
|
+
rspec-support (~> 3.8.0)
|
64
|
+
rspec-expectations (3.8.2)
|
65
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
66
|
+
rspec-support (~> 3.8.0)
|
67
|
+
rspec-mocks (3.8.0)
|
68
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
69
|
+
rspec-support (~> 3.8.0)
|
70
|
+
rspec-support (3.8.0)
|
71
|
+
rubocop (0.63.1)
|
72
|
+
jaro_winkler (~> 1.5.1)
|
73
|
+
parallel (~> 1.10)
|
74
|
+
parser (>= 2.5, != 2.5.1.1)
|
75
|
+
powerpack (~> 0.1)
|
76
|
+
rainbow (>= 2.2.2, < 4.0)
|
77
|
+
ruby-progressbar (~> 1.7)
|
78
|
+
unicode-display_width (~> 1.4.0)
|
79
|
+
ruby-progressbar (1.10.0)
|
80
|
+
ruby_dep (1.5.0)
|
81
|
+
shellany (0.0.1)
|
82
|
+
simplecov (0.16.1)
|
83
|
+
docile (~> 1.1)
|
84
|
+
json (>= 1.8, < 3)
|
85
|
+
simplecov-html (~> 0.10.0)
|
86
|
+
simplecov-console (0.4.2)
|
87
|
+
ansi
|
88
|
+
hirb
|
89
|
+
simplecov
|
90
|
+
simplecov-html (0.10.2)
|
91
|
+
stringento (2.0.0)
|
92
|
+
thor (0.20.3)
|
93
|
+
unicode-display_width (1.4.1)
|
94
|
+
|
95
|
+
PLATFORMS
|
96
|
+
ruby
|
97
|
+
|
98
|
+
DEPENDENCIES
|
99
|
+
guard-rspec (~> 4.7)
|
100
|
+
proforma (>= 1.0.0.pre.alpha)
|
101
|
+
proforma-extended-evaluator!
|
102
|
+
pry (~> 0)
|
103
|
+
rspec (~> 3.8)
|
104
|
+
rubocop (~> 0.63.1)
|
105
|
+
simplecov (~> 0.16.1)
|
106
|
+
simplecov-console (~> 0.4.2)
|
107
|
+
|
108
|
+
BUNDLED WITH
|
109
|
+
1.17.3
|
data/Guardfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
4
|
+
require 'guard/rspec/dsl'
|
5
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
6
|
+
|
7
|
+
# RSpec files
|
8
|
+
rspec = dsl.rspec
|
9
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
10
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
11
|
+
watch(rspec.spec_files)
|
12
|
+
|
13
|
+
# Ruby files
|
14
|
+
ruby = dsl.ruby
|
15
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
16
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright 2019 Blue Marble Payroll, LLC
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
# Proforma Extended Evaluator
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/proforma-extended-evaluator.svg)](https://badge.fury.io/rb/proforma-extended-evaluator) [![Build Status](https://travis-ci.org/bluemarblepayroll/proforma-extended-evaluator.svg?branch=master)](https://travis-ci.org/bluemarblepayroll/proforma-extended-evaluator) [![Maintainability](https://api.codeclimate.com/v1/badges/79e66b596906f633bc95/maintainability)](https://codeclimate.com/github/bluemarblepayroll/proforma-extended-evaluator/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/79e66b596906f633bc95/test_coverage)](https://codeclimate.com/github/bluemarblepayroll/proforma-extended-evaluator/test_coverage) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
|
4
|
+
|
5
|
+
The core Proforma library intentionally ships with a very weak evaluator. Custom text templating and value resolution is not part of the core library's domain. This library fills that void. The goals of this library are to provide:
|
6
|
+
|
7
|
+
1. Nested value resolution using dot-notation: `demographics.contact.first_name`
|
8
|
+
2. Indifferent object types for value resolution: Hash, OpenStruct, any Object subclass, etc.
|
9
|
+
3. Rich text templating: `{demo.last}, {demo.first} {demo.middle}`
|
10
|
+
4. Customizable formatting:
|
11
|
+
* `{amount::currency}` -> `$12,345.67 USD`
|
12
|
+
* `{dob::date}` -> `2/4/1976`
|
13
|
+
* `{user_count::number::0}` -> `12,400,569`
|
14
|
+
* `{logins_per_day::number::2}` -> `76,004.45`
|
15
|
+
* `{smoker::boolean}` -> `Yes` or `No`
|
16
|
+
* `{smoker::boolean::nullable}` -> `Yes` or `No` or `Unknown`
|
17
|
+
* `{social_security_number::left_mask}` -> `XXXXXXX1234`
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
To install through Rubygems:
|
22
|
+
|
23
|
+
````
|
24
|
+
gem install install proforma-extended-evaluator
|
25
|
+
````
|
26
|
+
|
27
|
+
You can also add this to your Gemfile:
|
28
|
+
|
29
|
+
````
|
30
|
+
bundle add proforma-extended-evaluator
|
31
|
+
````
|
32
|
+
|
33
|
+
## Examples
|
34
|
+
|
35
|
+
### Connecting to Proforma Rendering Pipeline
|
36
|
+
|
37
|
+
To use this plugin within Proforma:
|
38
|
+
|
39
|
+
1. Install Proforma
|
40
|
+
2. Install this library
|
41
|
+
3. Require both libraries
|
42
|
+
4. Pass in an instance of Proforma::ExtendedEvaluator into the Proforma#render method
|
43
|
+
|
44
|
+
````ruby
|
45
|
+
require 'proforma'
|
46
|
+
require 'proforma/extended_evaluator'
|
47
|
+
|
48
|
+
data = [
|
49
|
+
{
|
50
|
+
id: 1,
|
51
|
+
person: {
|
52
|
+
first: 'James',
|
53
|
+
last: 'Bond',
|
54
|
+
dob: '1960-05-14',
|
55
|
+
smoker: false,
|
56
|
+
ssn: '123-45-6789'
|
57
|
+
},
|
58
|
+
balance: '123.445388'
|
59
|
+
}
|
60
|
+
]
|
61
|
+
|
62
|
+
template = {
|
63
|
+
children: [
|
64
|
+
{
|
65
|
+
type: 'Grouping',
|
66
|
+
children: [
|
67
|
+
{
|
68
|
+
type: 'Header',
|
69
|
+
value: 'Details For: {person.last}, {person.first} ({id})'
|
70
|
+
},
|
71
|
+
{
|
72
|
+
type: 'Pane',
|
73
|
+
columns: [
|
74
|
+
{
|
75
|
+
lines: [
|
76
|
+
{ label: 'ID #', value: '{id::number::0}' },
|
77
|
+
{ label: 'First Name', value: '{person.first}' },
|
78
|
+
{ label: 'Last Name', value: '{person.last}' },
|
79
|
+
{ label: 'Social Security #', value: '{person.ssn::left_mask}' }
|
80
|
+
]
|
81
|
+
},
|
82
|
+
{
|
83
|
+
lines: [
|
84
|
+
{ label: 'Birthdate', value: '{person.dob::date}' },
|
85
|
+
{ label: 'Smoker', value: '{person.smoker::boolean}' },
|
86
|
+
{ label: 'Balance', value: '{balance::currency}' }
|
87
|
+
]
|
88
|
+
}
|
89
|
+
]
|
90
|
+
}
|
91
|
+
]
|
92
|
+
}
|
93
|
+
]
|
94
|
+
}
|
95
|
+
|
96
|
+
documents = Proforma.render(data, template, evaluator: Proforma::ExtendedEvaluator.new)
|
97
|
+
````
|
98
|
+
|
99
|
+
The `documents` attribute will now be an array with one object:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
expected_documents = [
|
103
|
+
{
|
104
|
+
contents: "DETAILS FOR: BOND, JAMES (1)\nID #: 1\nFirst Name: James\nLast Name:"\
|
105
|
+
" Bond\nSocial Security #: XXXXXXX6789\nBirthdate: 05/14/1960\nSmoker:"\
|
106
|
+
" No\nBalance: $123.45 USD\n",
|
107
|
+
extension: '.txt',
|
108
|
+
title: ''
|
109
|
+
}
|
110
|
+
]
|
111
|
+
```
|
112
|
+
|
113
|
+
Notice how all strings are properly formatted as prescribed in the template.
|
114
|
+
|
115
|
+
### Advanced Formatting (Customization/Options)
|
116
|
+
|
117
|
+
Formatter options are biased towards USA localization. You can override any of the options of the Formatter class, here are the options and their defaults:
|
118
|
+
|
119
|
+
Option | Default
|
120
|
+
---------------- | -------
|
121
|
+
currency_code | 'USD'
|
122
|
+
currency_round | 2
|
123
|
+
currency_symbol | '$'
|
124
|
+
date_format | '%m/%d/%Y'
|
125
|
+
mask_char | 'X'
|
126
|
+
false_value | 'No'
|
127
|
+
null_value | 'Unknown'
|
128
|
+
true_value | 'Yes'
|
129
|
+
|
130
|
+
## Contributing
|
131
|
+
|
132
|
+
### Development Environment Configuration
|
133
|
+
|
134
|
+
Basic steps to take to get this repository compiling:
|
135
|
+
|
136
|
+
1. Install [Ruby](https://www.ruby-lang.org/en/documentation/installation/) (check proforma-extended-evaluator.gemspec for versions supported)
|
137
|
+
2. Install bundler (gem install bundler)
|
138
|
+
3. Clone the repository (git clone git@github.com:bluemarblepayroll/proforma-extended-evaluator.git)
|
139
|
+
4. Navigate to the root folder (cd proforma)
|
140
|
+
5. Install dependencies (bundle)
|
141
|
+
|
142
|
+
### Running Tests
|
143
|
+
|
144
|
+
To execute the test suite run:
|
145
|
+
|
146
|
+
````
|
147
|
+
bundle exec rspec spec --format documentation
|
148
|
+
````
|
149
|
+
|
150
|
+
Alternatively, you can have Guard watch for changes:
|
151
|
+
|
152
|
+
````
|
153
|
+
bundle exec guard
|
154
|
+
````
|
155
|
+
|
156
|
+
Also, do not forget to run Rubocop:
|
157
|
+
|
158
|
+
````
|
159
|
+
bundle exec rubocop
|
160
|
+
````
|
161
|
+
|
162
|
+
### Publishing
|
163
|
+
|
164
|
+
Note: ensure you have proper authorization before trying to publish new versions.
|
165
|
+
|
166
|
+
After code changes have successfully gone through the Pull Request review process then the following steps should be followed for publishing new versions:
|
167
|
+
|
168
|
+
1. Merge Pull Request into master
|
169
|
+
2. Update `lib/proforma/extended_evaluator/version.rb` using [semantic versioning](https://semver.org/)
|
170
|
+
3. Install dependencies: `bundle`
|
171
|
+
4. Update `CHANGELOG.md` with release notes
|
172
|
+
5. Commit & push master to remote and ensure CI builds master successfully
|
173
|
+
6. Build the project locally: `gem build proforma-extended-evaluator`
|
174
|
+
7. Publish package to RubyGems: `gem push proforma-extended-evaluator-X.gem` where X is the version to push
|
175
|
+
8. Tag master with new version: `git tag <version>`
|
176
|
+
9. Push tags remotely: `git push origin --tags`
|
177
|
+
|
178
|
+
## License
|
179
|
+
|
180
|
+
This project is MIT Licensed.
|
data/bin/console
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'proforma/extended_evaluator'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
require 'pry'
|
11
|
+
Pry.start
|
@@ -0,0 +1,129 @@
|
|
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
|
+
module Proforma
|
11
|
+
class ExtendedEvaluator
|
12
|
+
# This library uses Stringento for its string-based formatting. This class is meant to be
|
13
|
+
# plugged into Stringento to provide formatting for data types, such as: strings, dates,
|
14
|
+
# currency, numbers, etc.
|
15
|
+
class Formatter < Stringento::Formatter
|
16
|
+
DEFAULTS = {
|
17
|
+
currency_code: 'USD',
|
18
|
+
currency_round: 2,
|
19
|
+
currency_symbol: '$',
|
20
|
+
date_format: '%m/%d/%Y',
|
21
|
+
mask_char: 'X',
|
22
|
+
false_value: 'No',
|
23
|
+
null_value: 'Unknown',
|
24
|
+
true_value: 'Yes'
|
25
|
+
}.freeze
|
26
|
+
|
27
|
+
ISO_DATE_FORMAT = '%Y-%m-%d'
|
28
|
+
NULLISH = /(nil|null)$/i.freeze
|
29
|
+
THOUSANDS_WITH_DECIMAL = /(\d)(?=\d{3}+\.)/.freeze
|
30
|
+
THOUSANDS_WITHOUT_DECIMAL = /(\d)(?=\d{3}+$)/.freeze
|
31
|
+
TRUTHY = /(true|t|yes|y|1)$/i.freeze
|
32
|
+
|
33
|
+
attr_reader :currency_code,
|
34
|
+
:currency_round,
|
35
|
+
:currency_symbol,
|
36
|
+
:date_format,
|
37
|
+
:false_value,
|
38
|
+
:mask_char,
|
39
|
+
:null_value,
|
40
|
+
:true_value
|
41
|
+
|
42
|
+
def initialize(opts = {})
|
43
|
+
opts = DEFAULTS.merge(opts)
|
44
|
+
|
45
|
+
@currency_code = opts[:currency_code]
|
46
|
+
@currency_round = opts[:currency_round]
|
47
|
+
@currency_symbol = opts[:currency_symbol]
|
48
|
+
@date_format = opts[:date_format]
|
49
|
+
@false_value = opts[:false_value]
|
50
|
+
@mask_char = opts[:mask_char]
|
51
|
+
@null_value = opts[:null_value]
|
52
|
+
@true_value = opts[:true_value]
|
53
|
+
end
|
54
|
+
|
55
|
+
def left_mask_formatter(value, arg)
|
56
|
+
keep_last = arg.to_s.empty? ? 4 : arg.to_s.to_i
|
57
|
+
|
58
|
+
string_value = value.to_s
|
59
|
+
|
60
|
+
return '' if null_or_empty?(string_value)
|
61
|
+
return value if string_value.length <= keep_last
|
62
|
+
|
63
|
+
mask(string_value, keep_last)
|
64
|
+
end
|
65
|
+
|
66
|
+
def date_formatter(value, _arg)
|
67
|
+
return '' if null_or_empty?(value)
|
68
|
+
|
69
|
+
date = Date.strptime(value.to_s, ISO_DATE_FORMAT)
|
70
|
+
|
71
|
+
date.strftime(date_format)
|
72
|
+
end
|
73
|
+
|
74
|
+
def currency_formatter(value, _arg)
|
75
|
+
return '' if null_or_empty?(value)
|
76
|
+
|
77
|
+
prefix = null_or_empty?(currency_symbol) ? '' : currency_symbol
|
78
|
+
suffix = null_or_empty?(currency_code) ? '' : " #{currency_code}"
|
79
|
+
|
80
|
+
formatted_value = number_formatter(value, currency_round)
|
81
|
+
|
82
|
+
"#{prefix}#{formatted_value}#{suffix}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def number_formatter(value, arg)
|
86
|
+
decimal_places = arg.to_s.empty? ? 6 : arg.to_s.to_i
|
87
|
+
|
88
|
+
regex = decimal_places.positive? ? THOUSANDS_WITH_DECIMAL : THOUSANDS_WITHOUT_DECIMAL
|
89
|
+
|
90
|
+
format("%0.#{decimal_places}f", value || 0).gsub(regex, '\1,')
|
91
|
+
end
|
92
|
+
|
93
|
+
def boolean_formatter(value, arg)
|
94
|
+
nullable = arg.to_s == 'nullable'
|
95
|
+
|
96
|
+
if nullable && nully?(value)
|
97
|
+
null_value
|
98
|
+
elsif truthy?(value)
|
99
|
+
true_value
|
100
|
+
else
|
101
|
+
false_value
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def mask(string, keep_last)
|
108
|
+
unmasked_part = string[-keep_last..-1]
|
109
|
+
masked_char_count = string.size - keep_last
|
110
|
+
|
111
|
+
(mask_char * masked_char_count) + unmasked_part
|
112
|
+
end
|
113
|
+
|
114
|
+
def null_or_empty?(val)
|
115
|
+
val.nil? || val.to_s.empty?
|
116
|
+
end
|
117
|
+
|
118
|
+
# rubocop:disable Style/DoubleNegation
|
119
|
+
def nully?(val)
|
120
|
+
null_or_empty?(val) || !!(val.to_s =~ NULLISH)
|
121
|
+
end
|
122
|
+
|
123
|
+
def truthy?(val)
|
124
|
+
!!(val.to_s =~ TRUTHY)
|
125
|
+
end
|
126
|
+
# rubocop:enable Style/DoubleNegation
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,51 @@
|
|
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
|
+
module Proforma
|
11
|
+
class ExtendedEvaluator
|
12
|
+
# This class is also meant to be plugged into Stringento to provide value resolution.
|
13
|
+
class Resolver
|
14
|
+
DOT_NOTATION_SEPARATOR = '.'
|
15
|
+
|
16
|
+
def resolve(value, input)
|
17
|
+
traverse(input, value.to_s.split(DOT_NOTATION_SEPARATOR))
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def traverse(object, through)
|
23
|
+
pointer = object
|
24
|
+
|
25
|
+
through.each do |t|
|
26
|
+
next unless pointer
|
27
|
+
|
28
|
+
pointer = get(pointer, t)
|
29
|
+
end
|
30
|
+
|
31
|
+
pointer
|
32
|
+
end
|
33
|
+
|
34
|
+
def get(object, key)
|
35
|
+
if object.is_a?(Hash)
|
36
|
+
indifferent_hash_get(object, key)
|
37
|
+
elsif object.respond_to?(key)
|
38
|
+
object.send(key)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def indifferent_hash_get(hash, key)
|
43
|
+
if hash.key?(key.to_s)
|
44
|
+
hash[key.to_s]
|
45
|
+
elsif hash.key?(key.to_s.to_sym)
|
46
|
+
hash[key.to_s.to_sym]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,14 @@
|
|
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
|
+
module Proforma
|
11
|
+
class ExtendedEvaluator
|
12
|
+
VERSION = '1.0.0-alpha'
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,49 @@
|
|
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 'bigdecimal'
|
11
|
+
require 'stringento'
|
12
|
+
|
13
|
+
require_relative 'extended_evaluator/formatter'
|
14
|
+
require_relative 'extended_evaluator/resolver'
|
15
|
+
|
16
|
+
module Proforma
|
17
|
+
# This class provides robust functionality for value resolution and text templating.
|
18
|
+
# For value resolution it uses its own dot-notation and
|
19
|
+
# message-based object traversal algorithm.
|
20
|
+
# For text templating it uses the Stringento library.
|
21
|
+
class ExtendedEvaluator
|
22
|
+
attr_reader :formatter, :resolver
|
23
|
+
|
24
|
+
def initialize(formatter: Formatter.new, resolver: Resolver.new)
|
25
|
+
raise ArgumentError, 'formatter is required' unless formatter
|
26
|
+
raise ArgumentError, 'resolver is required' unless resolver
|
27
|
+
|
28
|
+
@formatter = formatter
|
29
|
+
@resolver = resolver
|
30
|
+
|
31
|
+
freeze
|
32
|
+
end
|
33
|
+
|
34
|
+
def value(object, expression)
|
35
|
+
resolver.resolve(expression, object)
|
36
|
+
end
|
37
|
+
|
38
|
+
def text(object, expression)
|
39
|
+
record = object.is_a?(Array) || object.nil? ? {} : object
|
40
|
+
|
41
|
+
Stringento.evaluate(
|
42
|
+
expression.to_s,
|
43
|
+
record,
|
44
|
+
resolver: resolver,
|
45
|
+
formatter: formatter
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require './lib/proforma/extended_evaluator/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'proforma-extended-evaluator'
|
7
|
+
s.version = Proforma::ExtendedEvaluator::VERSION
|
8
|
+
s.summary = 'Proforma evaluator plugin for nested object value resolution and text templating'
|
9
|
+
|
10
|
+
s.description = <<-DESCRIPTION
|
11
|
+
Proforma comes with basic object value resolution and no text templating.
|
12
|
+
This library fills these necessities that any reasonably robust document rendering framework should have.
|
13
|
+
DESCRIPTION
|
14
|
+
|
15
|
+
s.authors = ['Matthew Ruggio']
|
16
|
+
s.email = ['mruggio@bluemarblepayroll.com']
|
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) }
|
20
|
+
s.homepage = 'https://github.com/bluemarblepayroll/proforma-extended-evaluator'
|
21
|
+
s.license = 'MIT'
|
22
|
+
|
23
|
+
s.required_ruby_version = '>= 2.3.8'
|
24
|
+
|
25
|
+
s.add_dependency('stringento', '~>2')
|
26
|
+
|
27
|
+
s.add_development_dependency('guard-rspec', '~>4.7')
|
28
|
+
s.add_development_dependency('proforma', '>=1.0.0-alpha')
|
29
|
+
s.add_development_dependency('pry', '~>0')
|
30
|
+
s.add_development_dependency('rspec', '~> 3.8')
|
31
|
+
s.add_development_dependency('rubocop', '~>0.63.1')
|
32
|
+
s.add_development_dependency('simplecov', '~>0.16.1')
|
33
|
+
s.add_development_dependency('simplecov-console', '~>0.4.2')
|
34
|
+
end
|
@@ -0,0 +1,157 @@
|
|
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::ExtendedEvaluator::Formatter do
|
13
|
+
describe '#left_mask_formatter' do
|
14
|
+
specify 'returns empty string if value is null' do
|
15
|
+
expect(subject.left_mask_formatter(nil, '')).to eq('')
|
16
|
+
end
|
17
|
+
|
18
|
+
specify 'returns empty string if value is empty string' do
|
19
|
+
expect(subject.left_mask_formatter('', '')).to eq('')
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when arg is blank' do
|
23
|
+
let(:arg) { '' }
|
24
|
+
|
25
|
+
specify 'returns value if length is less than or equal to mask length' do
|
26
|
+
expect(subject.left_mask_formatter('a', arg)).to eq('a')
|
27
|
+
expect(subject.left_mask_formatter('ab', arg)).to eq('ab')
|
28
|
+
expect(subject.left_mask_formatter('abc', arg)).to eq('abc')
|
29
|
+
expect(subject.left_mask_formatter('abcd', arg)).to eq('abcd')
|
30
|
+
expect(subject.left_mask_formatter('abcde', arg)).to eq('Xbcde')
|
31
|
+
expect(subject.left_mask_formatter('abcdef', arg)).to eq('XXcdef')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when arg is populated' do
|
36
|
+
let(:arg) { '2' }
|
37
|
+
|
38
|
+
specify 'returns value if length is less than or equal to mask length (arg)' do
|
39
|
+
expect(subject.left_mask_formatter('a', arg)).to eq('a')
|
40
|
+
expect(subject.left_mask_formatter('ab', arg)).to eq('ab')
|
41
|
+
expect(subject.left_mask_formatter('abc', arg)).to eq('Xbc')
|
42
|
+
expect(subject.left_mask_formatter('abcd', arg)).to eq('XXcd')
|
43
|
+
expect(subject.left_mask_formatter('abcde', arg)).to eq('XXXde')
|
44
|
+
expect(subject.left_mask_formatter('abcdef', arg)).to eq('XXXXef')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#date_formatter' do
|
50
|
+
subject do
|
51
|
+
described_class.new(
|
52
|
+
date_format: '%m/%d/%Y'
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
let(:arg) { '' }
|
57
|
+
|
58
|
+
specify 'returns empty string if value is null' do
|
59
|
+
expect(subject.date_formatter(nil, '')).to eq('')
|
60
|
+
end
|
61
|
+
|
62
|
+
specify 'returns empty string if value is empty string' do
|
63
|
+
expect(subject.date_formatter('', '')).to eq('')
|
64
|
+
end
|
65
|
+
|
66
|
+
specify 'returns formatted date' do
|
67
|
+
expect(subject.date_formatter('2018-01-02', arg)).to eq('01/02/2018')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#currency_formatter' do
|
72
|
+
subject do
|
73
|
+
described_class.new(
|
74
|
+
currency_code: 'USD',
|
75
|
+
currency_round: 2,
|
76
|
+
currency_symbol: '$'
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
let(:arg) { '' }
|
81
|
+
|
82
|
+
specify 'returns empty string if value is null' do
|
83
|
+
expect(subject.currency_formatter(nil, '')).to eq('')
|
84
|
+
end
|
85
|
+
|
86
|
+
specify 'returns empty string if value is empty string' do
|
87
|
+
expect(subject.currency_formatter('', '')).to eq('')
|
88
|
+
end
|
89
|
+
|
90
|
+
specify 'returns formatted currency' do
|
91
|
+
expect(subject.currency_formatter('12345.67', arg)).to eq('$12,345.67 USD')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#number_formatter' do
|
96
|
+
subject do
|
97
|
+
described_class.new(
|
98
|
+
currency_code: 'USD',
|
99
|
+
currency_round: 2,
|
100
|
+
currency_symbol: '$'
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
let(:arg) { '3' }
|
105
|
+
|
106
|
+
specify 'returns empty string if value is null' do
|
107
|
+
expect(subject.currency_formatter(nil, '')).to eq('')
|
108
|
+
end
|
109
|
+
|
110
|
+
specify 'returns empty string if value is empty string' do
|
111
|
+
expect(subject.currency_formatter('', '')).to eq('')
|
112
|
+
end
|
113
|
+
|
114
|
+
specify 'returns formatted number' do
|
115
|
+
expect(subject.number_formatter('12345.67899', arg)).to eq('12,345.679')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '#boolean_formatter' do
|
120
|
+
context 'non-nullable' do
|
121
|
+
let(:arg) { '' }
|
122
|
+
|
123
|
+
it 'should format truthy' do
|
124
|
+
expect(subject.boolean_formatter(true, arg)).to eq('Yes')
|
125
|
+
expect(subject.boolean_formatter('true', arg)).to eq('Yes')
|
126
|
+
expect(subject.boolean_formatter('True', arg)).to eq('Yes')
|
127
|
+
expect(subject.boolean_formatter('t', arg)).to eq('Yes')
|
128
|
+
expect(subject.boolean_formatter('1', arg)).to eq('Yes')
|
129
|
+
expect(subject.boolean_formatter(1, arg)).to eq('Yes')
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should format falsy' do
|
133
|
+
expect(subject.boolean_formatter(false, arg)).to eq('No')
|
134
|
+
expect(subject.boolean_formatter('false', arg)).to eq('No')
|
135
|
+
expect(subject.boolean_formatter('False', arg)).to eq('No')
|
136
|
+
expect(subject.boolean_formatter(0, arg)).to eq('No')
|
137
|
+
expect(subject.boolean_formatter('f', arg)).to eq('No')
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'should format nully' do
|
141
|
+
expect(subject.boolean_formatter(nil, arg)).to eq('No')
|
142
|
+
expect(subject.boolean_formatter('nil', arg)).to eq('No')
|
143
|
+
expect(subject.boolean_formatter('null', arg)).to eq('No')
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'nullable' do
|
148
|
+
let(:arg) { 'nullable' }
|
149
|
+
|
150
|
+
it 'should format nully' do
|
151
|
+
expect(subject.boolean_formatter(nil, arg)).to eq('Unknown')
|
152
|
+
expect(subject.boolean_formatter('nil', arg)).to eq('Unknown')
|
153
|
+
expect(subject.boolean_formatter('null', arg)).to eq('Unknown')
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,43 @@
|
|
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::ExtendedEvaluator::Resolver do
|
13
|
+
subject { described_class.new }
|
14
|
+
|
15
|
+
context 'when input is a hash' do
|
16
|
+
let(:input) { { 'id' => 1, demographics: { 'first' => 'Matt' } } }
|
17
|
+
|
18
|
+
specify '#resolve gets correct value' do
|
19
|
+
expect(subject.resolve(:id, input)).to eq(input['id'])
|
20
|
+
expect(subject.resolve('id', input)).to eq(input['id'])
|
21
|
+
|
22
|
+
expect(subject.resolve('demographics.first', input)).to eq(input.dig(:demographics, 'first'))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when input is an OpenStruct' do
|
27
|
+
let(:input) do
|
28
|
+
OpenStruct.new(
|
29
|
+
id: 1,
|
30
|
+
demographics: OpenStruct.new(
|
31
|
+
first: 'Matt'
|
32
|
+
)
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
specify '#resolve gets correct value' do
|
37
|
+
expect(subject.resolve(:id, input)).to eq(input.id)
|
38
|
+
expect(subject.resolve('id', input)).to eq(input.id)
|
39
|
+
|
40
|
+
expect(subject.resolve('demographics.first', input)).to eq(input.demographics.first)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,130 @@
|
|
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::ExtendedEvaluator do
|
13
|
+
describe '#initialize' do
|
14
|
+
it 'should raise ArgumentError if formatter is null' do
|
15
|
+
expect { described_class.new(formatter: nil) }.to raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should raise ArgumentError if resolver is null' do
|
19
|
+
expect { described_class.new(resolver: nil) }.to raise_error(ArgumentError)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should assign formatter and resolver' do
|
23
|
+
formatter = Proforma::ExtendedEvaluator::Formatter.new
|
24
|
+
resolver = Proforma::ExtendedEvaluator::Resolver.new
|
25
|
+
|
26
|
+
instance = described_class.new(formatter: formatter, resolver: resolver)
|
27
|
+
|
28
|
+
expect(instance.formatter).to equal(formatter)
|
29
|
+
expect(instance.resolver).to equal(resolver)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
specify '#value is delegated to resolver#resolve' do
|
34
|
+
resolver = Proforma::ExtendedEvaluator::Resolver.new
|
35
|
+
object = { id: 1 }
|
36
|
+
expression = 'id'
|
37
|
+
|
38
|
+
instance = described_class.new(resolver: resolver)
|
39
|
+
|
40
|
+
expect(resolver).to receive(:resolve).with(expression, object)
|
41
|
+
|
42
|
+
instance.value(object, expression)
|
43
|
+
end
|
44
|
+
|
45
|
+
specify '#text will use blank object if an array is passed in' do
|
46
|
+
object = [{ id: 1 }]
|
47
|
+
expression = '{id}'
|
48
|
+
|
49
|
+
instance = described_class.new
|
50
|
+
|
51
|
+
actual_text = instance.text(object, expression)
|
52
|
+
|
53
|
+
expect(actual_text).to eq('')
|
54
|
+
end
|
55
|
+
|
56
|
+
specify '#text will use object if an object is passed in' do
|
57
|
+
object = { id: 1 }
|
58
|
+
expression = '{id}'
|
59
|
+
|
60
|
+
instance = described_class.new
|
61
|
+
|
62
|
+
actual_text = instance.text(object, expression)
|
63
|
+
|
64
|
+
expect(actual_text).to eq('1')
|
65
|
+
end
|
66
|
+
|
67
|
+
specify 'Proforma Rendering Example' do
|
68
|
+
data = [
|
69
|
+
{
|
70
|
+
id: 1,
|
71
|
+
person: {
|
72
|
+
first: 'James',
|
73
|
+
last: 'Bond',
|
74
|
+
dob: '1960-05-14',
|
75
|
+
smoker: false,
|
76
|
+
ssn: '123-45-6789'
|
77
|
+
},
|
78
|
+
balance: '123.445388'
|
79
|
+
}
|
80
|
+
]
|
81
|
+
|
82
|
+
template = {
|
83
|
+
children: [
|
84
|
+
{
|
85
|
+
type: 'Grouping',
|
86
|
+
children: [
|
87
|
+
{
|
88
|
+
type: 'Header',
|
89
|
+
value: 'Details For: {person.last}, {person.first} ({id})'
|
90
|
+
},
|
91
|
+
{
|
92
|
+
type: 'Pane',
|
93
|
+
columns: [
|
94
|
+
{
|
95
|
+
lines: [
|
96
|
+
{ label: 'ID #', value: '{id::number::0}' },
|
97
|
+
{ label: 'First Name', value: '{person.first}' },
|
98
|
+
{ label: 'Last Name', value: '{person.last}' },
|
99
|
+
{ label: 'Social Security #', value: '{person.ssn::left_mask}' }
|
100
|
+
]
|
101
|
+
},
|
102
|
+
{
|
103
|
+
lines: [
|
104
|
+
{ label: 'Birthdate', value: '{person.dob::date}' },
|
105
|
+
{ label: 'Smoker', value: '{person.smoker::boolean}' },
|
106
|
+
{ label: 'Balance', value: '{balance::currency}' }
|
107
|
+
]
|
108
|
+
}
|
109
|
+
]
|
110
|
+
}
|
111
|
+
]
|
112
|
+
}
|
113
|
+
]
|
114
|
+
}
|
115
|
+
|
116
|
+
actual_documents = Proforma.render(data, template, evaluator: Proforma::ExtendedEvaluator.new)
|
117
|
+
|
118
|
+
expected_documents = [
|
119
|
+
Proforma::Document.new(
|
120
|
+
contents: "DETAILS FOR: BOND, JAMES (1)\nID #: 1\nFirst Name: James\nLast Name:"\
|
121
|
+
" Bond\nSocial Security #: XXXXXXX6789\nBirthdate: 05/14/1960\nSmoker:"\
|
122
|
+
" No\nBalance: $123.45 USD\n",
|
123
|
+
extension: '.txt',
|
124
|
+
title: ''
|
125
|
+
)
|
126
|
+
]
|
127
|
+
|
128
|
+
expect(actual_documents).to eq(expected_documents)
|
129
|
+
end
|
130
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
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
|
+
require 'pry'
|
12
|
+
require 'proforma'
|
13
|
+
|
14
|
+
require 'simplecov'
|
15
|
+
require 'simplecov-console'
|
16
|
+
SimpleCov.formatter = SimpleCov::Formatter::Console
|
17
|
+
SimpleCov.start
|
18
|
+
|
19
|
+
require './lib/proforma/extended_evaluator'
|
metadata
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: proforma-extended-evaluator
|
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: stringento
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2'
|
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: proforma
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.0.0.pre.alpha
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.0.pre.alpha
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.8'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.8'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.63.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.63.1
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.16.1
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.16.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov-console
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.4.2
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.4.2
|
125
|
+
description: |2
|
126
|
+
Proforma comes with basic object value resolution and no text templating.
|
127
|
+
This library fills these necessities that any reasonably robust document rendering framework should have.
|
128
|
+
email:
|
129
|
+
- mruggio@bluemarblepayroll.com
|
130
|
+
executables:
|
131
|
+
- console
|
132
|
+
extensions: []
|
133
|
+
extra_rdoc_files: []
|
134
|
+
files:
|
135
|
+
- ".editorconfig"
|
136
|
+
- ".gitignore"
|
137
|
+
- ".rubocop.yml"
|
138
|
+
- ".ruby-version"
|
139
|
+
- ".travis.yml"
|
140
|
+
- CHANGELOG.md
|
141
|
+
- Gemfile
|
142
|
+
- Gemfile.lock
|
143
|
+
- Guardfile
|
144
|
+
- LICENSE
|
145
|
+
- README.md
|
146
|
+
- bin/console
|
147
|
+
- lib/proforma/extended_evaluator.rb
|
148
|
+
- lib/proforma/extended_evaluator/formatter.rb
|
149
|
+
- lib/proforma/extended_evaluator/resolver.rb
|
150
|
+
- lib/proforma/extended_evaluator/version.rb
|
151
|
+
- proforma-extended-evaluator.gemspec
|
152
|
+
- spec/proforma/extended_evaluator/formatter_spec.rb
|
153
|
+
- spec/proforma/extended_evaluator/resolver_spec.rb
|
154
|
+
- spec/proforma/extended_evaluator_spec.rb
|
155
|
+
- spec/spec_helper.rb
|
156
|
+
homepage: https://github.com/bluemarblepayroll/proforma-extended-evaluator
|
157
|
+
licenses:
|
158
|
+
- MIT
|
159
|
+
metadata: {}
|
160
|
+
post_install_message:
|
161
|
+
rdoc_options: []
|
162
|
+
require_paths:
|
163
|
+
- lib
|
164
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - ">="
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: 2.3.8
|
169
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 1.3.1
|
174
|
+
requirements: []
|
175
|
+
rubygems_version: 3.0.1
|
176
|
+
signing_key:
|
177
|
+
specification_version: 4
|
178
|
+
summary: Proforma evaluator plugin for nested object value resolution and text templating
|
179
|
+
test_files:
|
180
|
+
- spec/proforma/extended_evaluator/formatter_spec.rb
|
181
|
+
- spec/proforma/extended_evaluator/resolver_spec.rb
|
182
|
+
- spec/proforma/extended_evaluator_spec.rb
|
183
|
+
- spec/spec_helper.rb
|