milan 0.0.1.pre
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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE +14 -0
- data/README.md +3 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/milan.rb +5 -0
- data/lib/milan/form_builder.rb +45 -0
- data/lib/milan/term_aggregator.rb +38 -0
- data/lib/milan/version.rb +3 -0
- data/milan.gemspec +27 -0
- data/spec/features/form_builder_feature_spec.rb +53 -0
- data/spec/lib/milan/form_builder_spec.rb +17 -0
- data/spec/lib/milan/term_aggregator_spec.rb +44 -0
- data/spec/spec_helper.rb +1 -0
- metadata +136 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e495557a7c841ae2b80f98130286565076a40365
|
4
|
+
data.tar.gz: 2dd216aa489c491d2920bb633bf5c8c73fa5d09d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d1bbf28e1321b43db4cb79f03b3c71d1d600d4962dcb0676019aa9f557f5a8fba8c6058f4b79b356ff83b99a2f8808d48df05867ad6d8a05bae7b7279b7252ea
|
7
|
+
data.tar.gz: 2ad7f09d29fb91554fd7f05be5dde3313b4a8f82ef8a4d6432a09ffe928fe2229638c28bd078c30fbb385a3412866c423c308930eccdac37f3b6780149d9538e
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
##########################################################################
|
2
|
+
# Copyright 2016 University of Notre Dame
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "milan"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/lib/milan.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'hanami/utils/string'
|
2
|
+
require 'milan/term_aggregator'
|
3
|
+
|
4
|
+
module Milan
|
5
|
+
class FormBuilder
|
6
|
+
def initialize(config:, term_aggregate_builder: default_term_aggregate_builder, &configuration_block)
|
7
|
+
self.config = config
|
8
|
+
self.name = config.fetch(:form)
|
9
|
+
self.partial_suffix = config.fetch(:partial_suffix, name)
|
10
|
+
self.term_aggregator = default_term_aggregate_builder.call(terms: config.fetch(:terms))
|
11
|
+
instance_exec(&configuration_block) if block_given?
|
12
|
+
end
|
13
|
+
attr_reader :name, :partial_suffix
|
14
|
+
|
15
|
+
extend Forwardable
|
16
|
+
def_delegator :term_aggregator, :append_additional_terms_configurations
|
17
|
+
|
18
|
+
def contracts
|
19
|
+
config.fetch(:contracts)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_writer :name
|
25
|
+
attr_accessor :config, :term_aggregator
|
26
|
+
|
27
|
+
def partial_suffix=(input)
|
28
|
+
@partial_suffix = Hanami::Utils::String.new(input).underscore
|
29
|
+
end
|
30
|
+
|
31
|
+
def default_term_aggregate_builder
|
32
|
+
Milan::TermAggregator.method(:new)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.form_for(work_type:, form:, config:)
|
37
|
+
work_types = config.fetch(:work_types)
|
38
|
+
work_type_config = work_types.find { |types| types.fetch(:work_type) }
|
39
|
+
form_config = work_type_config.fetch(:forms).find { |obj| obj.fetch(:form) == form }
|
40
|
+
FormBuilder.new(config: form_config) do
|
41
|
+
append_additional_terms_configurations(terms: work_type_config.fetch(:terms)) if form_config.key?(:terms)
|
42
|
+
append_additional_terms_configurations(terms: config.fetch(:terms)) if config.key?(:terms)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Milan
|
2
|
+
# Responsible for aggregating the configuration information for the given terms
|
3
|
+
class TermAggregator
|
4
|
+
def initialize(terms:)
|
5
|
+
self.terms = terms
|
6
|
+
self.additional_terms_configurations = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def append_additional_terms_configurations(terms:)
|
10
|
+
additional_terms_configurations << terms
|
11
|
+
end
|
12
|
+
|
13
|
+
def finalize
|
14
|
+
terms.each_with_object({}) do |term, obj|
|
15
|
+
obj[term.fetch(:term)] = build_configuration_for(term: term)
|
16
|
+
obj
|
17
|
+
end.freeze
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_accessor :terms, :additional_terms_configurations
|
23
|
+
|
24
|
+
def build_configuration_for(term:)
|
25
|
+
key = term.fetch(:term)
|
26
|
+
aggregate_config = [term]
|
27
|
+
additional_terms_configurations.each do |terms_config|
|
28
|
+
additional_config = terms_config.find { |term_config| term_config.fetch(:term) == key }
|
29
|
+
next unless additional_config
|
30
|
+
aggregate_config.unshift(additional_config)
|
31
|
+
end
|
32
|
+
aggregate_config.each_with_object({}) do |element, hash|
|
33
|
+
hash.merge!(element)
|
34
|
+
hash
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/milan.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'milan/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "milan"
|
8
|
+
spec.version = Milan::VERSION
|
9
|
+
spec.authors = ["Jeremy Friesen"]
|
10
|
+
spec.email = ["jeremy.n.friesen@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{A library for building models via a configuration.}
|
13
|
+
spec.description = %q{A library for building models via a configuration.}
|
14
|
+
spec.homepage = "https://github.com/jeremyf/milan"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "hanami-utils", "~> 0.6"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.1"
|
26
|
+
spec.add_development_dependency "rspec-its"
|
27
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'milan/form_builder'
|
3
|
+
|
4
|
+
RSpec.describe 'Form feature spec' do
|
5
|
+
context '.form_for' do
|
6
|
+
let(:context) { double('The Context for the Form') }
|
7
|
+
let(:requested_by) { double('Requester')}
|
8
|
+
|
9
|
+
subject { Milan.form_for(work_type: "ULRA Application", form: 'Plan of Study', config: config) }
|
10
|
+
|
11
|
+
its(:partial_suffix) { should eq('plan_of_study') }
|
12
|
+
it { should be_a(Milan::FormBuilder) }
|
13
|
+
its(:contracts) { should eq(config.fetch(:work_types)[0].fetch(:forms)[0].fetch(:contracts)) }
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:config) do
|
17
|
+
{
|
18
|
+
work_types: [{
|
19
|
+
work_type: "ULRA Application",
|
20
|
+
contracts: [{
|
21
|
+
contexts: "ingest",
|
22
|
+
validations: [{ validator: 'Sipity::Contracts::IngestContract' }]
|
23
|
+
}],
|
24
|
+
forms: [{
|
25
|
+
form: "Plan of Study",
|
26
|
+
contracts: [{
|
27
|
+
contexts: ['submit'],
|
28
|
+
validations: [
|
29
|
+
{ validates: 'ND.expected_graduation_term', presence: true, inclusion: "ND.expected_graduation_term/options" },
|
30
|
+
{ validates: 'ND.underclass_level', presence: true, inclusion: "ND.underclass_level/options" },
|
31
|
+
{ validates: 'ND.major', presence: true },
|
32
|
+
{ validates: 'ND.primary_college', presence: true, cardinality: 1 }
|
33
|
+
]
|
34
|
+
}],
|
35
|
+
terms: [
|
36
|
+
{ term: 'ND.expected_graduation_term', cardinality: 1 },
|
37
|
+
{ term: 'ND.underclass_level' },
|
38
|
+
{ term: 'ND.major', cardinality: 'many' },
|
39
|
+
{ term: 'ND.minor', cardinality: 'many' },
|
40
|
+
{ term: 'ND.primary_college', cardinality: 1 }
|
41
|
+
]
|
42
|
+
}],
|
43
|
+
terms: [{
|
44
|
+
term: 'ND.primary_college', cardinality: 1,
|
45
|
+
label: 'Primary College'
|
46
|
+
}]
|
47
|
+
}],
|
48
|
+
terms: [{
|
49
|
+
term: 'ND.underclass_level', options: ['First Year', 'Sophomore', 'Junior', 'Senior', '5th Year'], cardinality: 1
|
50
|
+
}]
|
51
|
+
}
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'milan/form_builder'
|
3
|
+
|
4
|
+
module Milan
|
5
|
+
RSpec.describe FormBuilder do
|
6
|
+
let(:config) { { form: 'hello', terms: { term: 'ND.another_term' } } }
|
7
|
+
let(:additional_terms) { { term: 'ND.expected_graduation_term', cardinality: 1 } }
|
8
|
+
subject { described_class.new(config: config) }
|
9
|
+
it 'will append terms to the term aggregator during initialization' do
|
10
|
+
expect_any_instance_of(TermAggregator).to receive(:append_additional_terms_configurations).with(additional_terms)
|
11
|
+
additional_terms_scoped = additional_terms # establishing lexical scope
|
12
|
+
described_class.new(config: config) do
|
13
|
+
append_additional_terms_configurations(additional_terms_scoped)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'milan/term_aggregator'
|
3
|
+
|
4
|
+
module Milan
|
5
|
+
RSpec.describe TermAggregator do
|
6
|
+
subject { described_class.new(terms: [{ term: 'DC.title' }, { term: 'DC.abstract' }]) }
|
7
|
+
|
8
|
+
context '#finalize' do
|
9
|
+
subject { described_class.new(terms: [{ term: 'DC.title' }, { term: 'DC.abstract' }]).finalize }
|
10
|
+
context 'without additional term configuration' do
|
11
|
+
it { should be_a(Enumerable) }
|
12
|
+
its(:size) { should eq(2) }
|
13
|
+
|
14
|
+
it 'will expose retrieval method for term' do
|
15
|
+
expect(subject.fetch('DC.title')).to eq(term: 'DC.title')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
context 'with additional configuration' do
|
19
|
+
subject do
|
20
|
+
described_class.new(terms: [{ term: 'DC.title' }, { term: 'DC.abstract', cardinality: 'many' }]).tap do |obj|
|
21
|
+
obj.append_additional_terms_configurations(
|
22
|
+
terms: [{ term: 'DC.title', cardinality: 1 }, { term: 'DC.hello' }, { term: 'DC.abstract', cardinality: 1}]
|
23
|
+
)
|
24
|
+
end.finalize
|
25
|
+
end
|
26
|
+
|
27
|
+
it { should be_a(Enumerable) }
|
28
|
+
its(:size) { should eq(2) }
|
29
|
+
|
30
|
+
it 'will expose retrieval method for term' do
|
31
|
+
expect(subject.fetch('DC.title')).to eq(term: 'DC.title', cardinality: 1)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'will prefer direct definitions of additional term configurations' do
|
35
|
+
expect(subject.fetch('DC.abstract')).to eq(term: 'DC.abstract', cardinality: 'many')
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'will only register terms that were part of the initialization' do
|
39
|
+
expect { subject.fetch('DC.hello') }.to raise_error(KeyError)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rspec/its'
|
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: milan
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.pre
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeremy Friesen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hanami-utils
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.9'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.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.1'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-its
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: A library for building models via a configuration.
|
84
|
+
email:
|
85
|
+
- jeremy.n.friesen@gmail.com
|
86
|
+
executables:
|
87
|
+
- console
|
88
|
+
- setup
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- ".gitignore"
|
93
|
+
- ".travis.yml"
|
94
|
+
- Gemfile
|
95
|
+
- LICENSE
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- bin/console
|
99
|
+
- bin/setup
|
100
|
+
- lib/milan.rb
|
101
|
+
- lib/milan/form_builder.rb
|
102
|
+
- lib/milan/term_aggregator.rb
|
103
|
+
- lib/milan/version.rb
|
104
|
+
- milan.gemspec
|
105
|
+
- spec/features/form_builder_feature_spec.rb
|
106
|
+
- spec/lib/milan/form_builder_spec.rb
|
107
|
+
- spec/lib/milan/term_aggregator_spec.rb
|
108
|
+
- spec/spec_helper.rb
|
109
|
+
homepage: https://github.com/jeremyf/milan
|
110
|
+
licenses: []
|
111
|
+
metadata: {}
|
112
|
+
post_install_message:
|
113
|
+
rdoc_options: []
|
114
|
+
require_paths:
|
115
|
+
- lib
|
116
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 1.3.1
|
126
|
+
requirements: []
|
127
|
+
rubyforge_project:
|
128
|
+
rubygems_version: 2.4.7
|
129
|
+
signing_key:
|
130
|
+
specification_version: 4
|
131
|
+
summary: A library for building models via a configuration.
|
132
|
+
test_files:
|
133
|
+
- spec/features/form_builder_feature_spec.rb
|
134
|
+
- spec/lib/milan/form_builder_spec.rb
|
135
|
+
- spec/lib/milan/term_aggregator_spec.rb
|
136
|
+
- spec/spec_helper.rb
|