mvcli 0.0.9 → 0.0.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 508c2c185acef69a64bb0adc1c39831523ff8f21
4
- data.tar.gz: d6c2e35724efe351ae7be2a333e7cf0c75d17c30
3
+ metadata.gz: b724357af63c1eccdda3de7f4c73d1f4d8dc2355
4
+ data.tar.gz: 9a0e068f92f544c184bd2fb72fe4cbdf908c9583
5
5
  SHA512:
6
- metadata.gz: b6918dc61af99ae091bbdd811e62f25798798c6a9b8b3557efc968f8a6af07cb4a9378bc0d4e8b5537c6253bd4d0f55f5bf0f8577d313d6158b7a562a5304a5d
7
- data.tar.gz: 6741eca2aba70f1db5fca77285856583a82257c513260848b8cdbc620a74c240fc2fa636905e4553903685582f041d6519a1368cf71633669c74ab7eb3f93993
6
+ metadata.gz: 83bbc6c3c668363569cf81c3de98b219212ab96bd9e4b25b609c403aa28e2fd200170df986ce7dcc29d0731a2bc50730af9432d3c39eed3ea3efd4ca20b4bc39
7
+ data.tar.gz: 833e8aa8e762de423b8bf8287667040c245481cbd5d02995d1def13b57c13e027578d30176715b89ed70407e8c3092cb18f062ad608533df154f67595425e39f
data/Gemfile CHANGED
@@ -4,6 +4,7 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  gem "rake"
7
- gem "rspec"
7
+ gem "rspec", "~> 2.13.0"
8
8
  gem "rspec-given"
9
9
  gem "rspec-spies"
10
+ gem "pry"
@@ -9,11 +9,11 @@ class MVCLI::Form::Input
9
9
 
10
10
  def decode(&block)
11
11
  @handler.decode &block
12
- return self
13
12
  end
14
13
 
15
- def value(source, context = nil)
16
- @handler.value source, context
14
+ def value(source, context = nil, &transform)
15
+ transform ||= ->(v) { v }
16
+ @handler.value source, context, &transform
17
17
  end
18
18
 
19
19
  def handler(target)
@@ -33,7 +33,12 @@ class MVCLI::Form::Input
33
33
  @decoders << block
34
34
  end
35
35
 
36
- def value(source, context = nil)
36
+
37
+ def value(source, context = nil, &transform)
38
+ transform.call decoded source, context
39
+ end
40
+
41
+ def decoded(source, context)
37
42
  if value = [source[@name]].flatten.first
38
43
  @decoders.reduce(value) do |value, decoder|
39
44
  decoder.call value
@@ -60,12 +65,12 @@ class MVCLI::Form::Input
60
65
  class ListTarget < Target
61
66
  include ActiveSupport::Inflector
62
67
 
63
- def value(source, context = nil)
68
+ def value(source, context = nil, &transform)
64
69
  source = Map(source)
65
70
  list = [source[singularize @name]].compact.flatten.map do |value|
66
- super({@name => value}, context)
71
+ super({@name => value}, context, &transform)
67
72
  end.compact
68
- list.empty? ? [default(context)].compact.flatten : list
73
+ list.empty? ? [transform.call(default(context))].compact.flatten : list
69
74
  end
70
75
  end
71
76
 
data/lib/mvcli/form.rb CHANGED
@@ -18,7 +18,9 @@ module MVCLI
18
18
  self.class.inputs.reduce(Map.new) do |map, pair|
19
19
  name, input = *pair
20
20
  map.tap do
21
- map[name] = input.value @source, self
21
+ map[name] = input.value(@source, self) do |value|
22
+ value.is_a?(Form) ? value.attributes : value
23
+ end
22
24
  end
23
25
  end
24
26
  end
@@ -71,7 +73,7 @@ module MVCLI
71
73
  @inputs[name] = input
72
74
  if options[:required]
73
75
  if target.is_a?(Array)
74
- validates(name, "cannot be empty", nil: true) {|value| value && !value.empty?}
76
+ validates(name, "cannot be empty", nil: true, each: false) {|value| value && !value.empty?}
75
77
  else
76
78
  validates(name, "is required", nil: true) {|value| !value.nil?}
77
79
  end
@@ -0,0 +1,23 @@
1
+ module MVCLI
2
+ class Middleware
3
+ class ExceptionLogger
4
+ class ValidationSummary
5
+ def initialize(validation)
6
+ @validation = validation
7
+ end
8
+
9
+ def keys
10
+ @validation.violations.keys
11
+ end
12
+
13
+ def values
14
+ @validation.violations.values
15
+ end
16
+
17
+ def write
18
+ #Write object to a stream
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,8 +1,13 @@
1
+ require "mvcli/erb"
2
+ require "mvcli/middleware/exception_logger/validation_summary"
3
+
1
4
  module MVCLI
2
5
  class Middleware
3
6
  class ExceptionLogger
4
7
  def call(command)
5
8
  yield command
9
+ rescue MVCLI::Validatable::ValidationError => e
10
+ ValidationSummary.new(e).write command.log
6
11
  rescue Exception => e
7
12
  command.log << e.message + "\n"
8
13
  raise e
@@ -50,6 +50,7 @@ module MVCLI::Validatable
50
50
  class Validator
51
51
  def initialize
52
52
  @rules = []
53
+ @all = []
53
54
  @children = []
54
55
  end
55
56
 
@@ -88,13 +89,13 @@ module MVCLI::Validatable
88
89
  def initialize(object)
89
90
  @object = object
90
91
  @children = Map.new do |h,k|
91
- h[k] = []
92
+ h[k] = [] unless k.nil?
92
93
  end
93
94
  @violations = Map.new do |h,k|
94
- h[k] = []
95
+ h[k] = [] unless k.nil?
95
96
  end
96
97
  @errors = Map.new do |h,k|
97
- h[k] = []
98
+ h[k] = [] unless k.nil?
98
99
  end
99
100
  end
100
101
 
@@ -166,20 +167,32 @@ module MVCLI::Validatable
166
167
 
167
168
  class Rule
168
169
  def initialize(field, message, options, predicate)
169
- @field, @message, @options, @predicate = field, message, options, predicate
170
+ @field, @message, @predicate = field, message, predicate
171
+ @options = options.reverse_merge each: true
170
172
  end
173
+
171
174
  def call(validatable, violations, errors)
172
175
  value, error = read validatable
173
176
  if error
174
177
  errors[@field] << error
175
178
  else
176
- return if value.nil? && !@options[:nil]
177
- violations[@field] << @message unless @predicate.call value
179
+ check value, violations
180
+ end
181
+ end
182
+
183
+ def check(object, violations)
184
+ if object.is_a?(Enumerable) && @options[:each]
185
+ object.each_with_index do |item, i|
186
+ violations["#{@field}[#{i}]"] << @message unless @predicate.call item
187
+ end
188
+ else
189
+ return if object.nil? && !@options[:nil]
190
+ violations[@field] << @message unless @predicate.call object
178
191
  end
179
192
  end
180
193
 
181
194
  def read(validatable)
182
- return validatable.send(@field), nil
195
+ return validatable.instance_eval(@field.to_s), nil
183
196
  rescue StandardError => e
184
197
  return nil, e
185
198
  end
data/lib/mvcli/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module MVCLI
2
- VERSION = "0.0.9"
2
+ VERSION = "0.0.10"
3
3
  end
@@ -91,5 +91,9 @@ describe "Form Inputs" do
91
91
  When(:value) { input.value field: 10 }
92
92
  Then {value == [10]}
93
93
  end
94
+ context "when the value is retrieved with a transform" do
95
+ When(:value) { input.value(field: 10) {|v| v * 2} }
96
+ Then { value == [20] }
97
+ end
94
98
  end
95
99
  end
@@ -25,6 +25,7 @@ describe "A form for creating a load balancer" do
25
25
  validates(:type, "invalid type") {|type| ['PRIMARY', 'SECONDARY'].member? type}
26
26
  validates(:condition, "invalid condition") {|c| ['ENABLED', 'DISABLED'].member? c}
27
27
  end
28
+ validates(:virtual_ips, "invalid virtual IP") {|ip| ['PUBLIC', 'SERVICENET'].member? ip}
28
29
  end
29
30
  end
30
31
  Given(:form) do
@@ -33,6 +34,12 @@ describe "A form for creating a load balancer" do
33
34
  f.stub(:naming) {mock(:NameGenerator, generate: 'random-name')}
34
35
  end
35
36
  end
37
+ context "with invalid array properties" do
38
+ Given(:params) { ({virtual_ip: ['PERBLIC'], node: ['10.0.0.1']}) }
39
+ Then { not form.valid? }
40
+ And {form.violations["virtual_ips[0]"] == ["invalid virtual IP"]}
41
+
42
+ end
36
43
  context "with no nodes provided" do
37
44
  Given(:params) {({node: []})}
38
45
  Then {!form.valid?}
@@ -91,6 +98,9 @@ describe "A form for creating a load balancer" do
91
98
  Given(:attributes) {form.value.to_hash.reject {|k,v| k == "nodes"}}
92
99
  Then {attributes == {"name" => "foo", "port" => 80, "protocol" => "HTTP", "virtual_ips" => ["PUBLIC", "SERVICENET"]}}
93
100
 
101
+ Given (:nodeattrs) { form.attributes[:nodes]}
102
+ Then { nodeattrs.first == {"address" => IPAddr.new('10.0.0.1'), "port" => 80, "condition" => "ENABLED", "type" => "PRIMARY"} }
103
+
94
104
  context ". On the first node" do
95
105
  Given(:node) {form.nodes.first}
96
106
  Then {node.address == IPAddr.new('10.0.0.1')}
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+ require "mvcli/validatable"
3
+ require "mvcli/middleware/exception_logger/validation_summary"
4
+
5
+ describe "ValidationSummary" do
6
+ use_natural_assertions
7
+ Given(:validator) { MVCLI::Validatable::Validator.new }
8
+ Given(:object) { Object.new }
9
+ Given(:validation) { validator.validate object }
10
+ Given(:summary) { MVCLI::Middleware::ExceptionLogger::ValidationSummary.new validation }
11
+ context "With a simple validation" do
12
+ Given do
13
+ validator.validates(:foo, "You dun goofed", nil: true) {|foo| foo != nil}
14
+ validator.validate object
15
+ end
16
+
17
+ context "When validation fails" do
18
+ When { object.stub(:foo) }
19
+ Then { summary.keys.first == "foo" }
20
+ And { summary.values.first == ["You dun goofed"] }
21
+ end
22
+ end
23
+ end
@@ -6,6 +6,8 @@ describe "a validator" do
6
6
  Given(:object) {Object.new}
7
7
  Given(:validator) {MVCLI::Validatable::Validator.new}
8
8
  Given(:validation) { validator.validate object }
9
+ Given(:violations) { validation.violations }
10
+
9
11
  context "when it validates a field that does not exist on the object" do
10
12
  Given {validator.validates(:does_not_exist, "invalid") {}}
11
13
  When(:validation) {validator.validate object}
@@ -37,4 +39,28 @@ describe "a validator" do
37
39
  Then { validation.valid? }
38
40
  end
39
41
  end
42
+
43
+ describe "validating each element in an enumerable" do
44
+ Given { validator.validates(:foodles, "invalid", nil: true) {|foodle| not foodle.nil? } }
45
+ context "when there are invalid elements in the enumerable" do
46
+ When { object.stub(:foodles) {["not nil", nil, "not nil"]} }
47
+ Then { not validation.valid? }
48
+ Then { violations.has_key? "foodles[1]" }
49
+ And { not violations.has_key? "foodles"}
50
+ end
51
+ end
52
+
53
+ describe "validating an enumerable itself" do
54
+ Given { object.stub(:array) {array} }
55
+ Given { validator.validates(:array, "invalid", each: false) {|a| a.length < 3} }
56
+ context "when it is valid" do
57
+ When(:array) { [1,2] }
58
+ Then { validation.valid? }
59
+ end
60
+ context "when it is invalid" do
61
+ When(:array) { [1,2,3] }
62
+ Then { not validation.valid? }
63
+ And {not violations["array"].empty?}
64
+ end
65
+ end
40
66
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mvcli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Lowell
@@ -29,7 +29,7 @@ cert_chain:
29
29
  UgImJlChAzCoDP9zi9tdm6jAr7ttF25R9PPYr11ILb7dYe3qUzlNlM6zJx/nb31b
30
30
  IhdyRVup4qLcqYSTPsm6u7VA
31
31
  -----END CERTIFICATE-----
32
- date: 2013-07-01 00:00:00.000000000 Z
32
+ date: 2013-07-10 00:00:00.000000000 Z
33
33
  dependencies:
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: map
@@ -85,6 +85,7 @@ files:
85
85
  - lib/mvcli/loader.rb
86
86
  - lib/mvcli/middleware.rb
87
87
  - lib/mvcli/middleware/exception_logger.rb
88
+ - lib/mvcli/middleware/exception_logger/validation_summary.rb
88
89
  - lib/mvcli/middleware/exit_status.rb
89
90
  - lib/mvcli/provisioning.rb
90
91
  - lib/mvcli/renderer.rb
@@ -100,6 +101,7 @@ files:
100
101
  - spec/mvcli/form/input_spec.rb
101
102
  - spec/mvcli/form_spec.rb
102
103
  - spec/mvcli/loader_spec.rb
104
+ - spec/mvcli/middleware/exception_logger/validation_summary_spec.rb
103
105
  - spec/mvcli/middleware/exception_logger_spec.rb
104
106
  - spec/mvcli/middleware/exit_status_spec.rb
105
107
  - spec/mvcli/middleware_spec.rb
@@ -140,6 +142,7 @@ test_files:
140
142
  - spec/mvcli/form/input_spec.rb
141
143
  - spec/mvcli/form_spec.rb
142
144
  - spec/mvcli/loader_spec.rb
145
+ - spec/mvcli/middleware/exception_logger/validation_summary_spec.rb
143
146
  - spec/mvcli/middleware/exception_logger_spec.rb
144
147
  - spec/mvcli/middleware/exit_status_spec.rb
145
148
  - spec/mvcli/middleware_spec.rb