methodic 1.1 → 1.2

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.
data/COPYRIGHT CHANGED
@@ -1,4 +1,4 @@
1
- methodic Copyright (c) 2012 Ultragreen Software, Romain GEORGES
1
+ methodic Copyright (c) 2012-2013 Ultragreen Software, Romain GEORGES
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
data/ChangeLog CHANGED
@@ -15,3 +15,7 @@ methodic :
15
15
  - patched version
16
16
  - version 1.1 (RC2)
17
17
  Romain GEORGES
18
+ - stable version ( production ready)
19
+ - version 1.2 (stable)
20
+ Romain GEORGES
21
+ - NEW : conditions support see manual
data/Rakefile CHANGED
@@ -15,7 +15,7 @@ require "roodi_task"
15
15
 
16
16
 
17
17
  RoodiTask.new() do | t |
18
- t.patterns = %w(lib/**/*.rb spec/**/*.rb features/**/*.rb)
18
+ t.patterns = %w(lib/**/*.rb)
19
19
  t.config = "ultragreen_roodi_coding_convention.yml"
20
20
  end
21
21
 
data/doc/manual.rdoc CHANGED
@@ -35,6 +35,8 @@ In a valid Ruby environment :
35
35
  myOptions = Methodic::get_options(_options) do |m|
36
36
  m.specify_default_value_of :country => 'France'
37
37
  m.specify_classes_of :name => String, :surname => String, :age => Fixnum, :country => String
38
+ aCond = Proc::new {|option| case options when 'Doe' then true else false end }
39
+ m.specify_condition_for :name => aCond
38
40
  m.specify_presence_of :name
39
41
  m.specify_presence_of :surname
40
42
  m.specify_formats_of :name => /\w+/, :surname => /\w+/, :country => /\w+/
@@ -53,7 +55,9 @@ In a valid Ruby environment :
53
55
  def amethod ( _options = {})
54
56
  myOptions = Methodic::get_options(_options,true) do |m|
55
57
  # all others definitions MUST be included in known options list (explained in Spec), so : m.specify_known_options [:country,:name,:surname, :age]
56
- m.specify_default_value_of :country => 'France'
58
+ m.specify_default_value_of :country => 'France'
59
+ aCond = Proc::new {|option| case options when 'Doe' then true else false end }
60
+ m.specify_condition_for :name => aCond
57
61
  m.specify_classes_of :name => String, :surname => String, :age => Fixnum, :country => String
58
62
  m.specify_presence_of :name
59
63
  m.specify_presence_of :surname
@@ -64,8 +68,30 @@ In a valid Ruby environment :
64
68
  end
65
69
  [...]
66
70
 
71
+ === Remarque about conditions
72
+
73
+
74
+ * Condition MUST :
75
+
76
+ - be ruby code
77
+ - be a Proc Object
78
+ - have an argument |option| who provide the option symbol, like :an_option
79
+ - return true or false
80
+
81
+ * Make your condition like
82
+
83
+
84
+ aCond = Proc::new do |option|
85
+ case options
86
+ when .... then ...
87
+ when .... then ...
88
+ else ...
89
+ end
90
+ end
91
+
92
+
67
93
 
68
94
  == Copyright
69
95
 
70
- <pre>Methodic (c) 2012 Romain GEORGES <romain@ultragreen.net> for Ultragreen Software </pre>
96
+ <pre>Methodic (c) 2012-2013 Romain GEORGES <romain@ultragreen.net> for Ultragreen Software </pre>
71
97
 
data/lib/methodic.rb CHANGED
@@ -1,11 +1,35 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright Ultragreen (c) 2012
2
+ # -*- coding: undecided -*-
3
+ # Copyright Ultragreen (c) 2012-2�013
3
4
  #---
4
5
  # Author : Romain GEORGES
5
6
  # type : gem component library
6
7
  # obj : Methodic Module
7
8
  #---
8
9
 
10
+ # inherited List class from Array to patch push for uniqness carateristique
11
+ class List < Array
12
+
13
+ # override of push for uniqness and flatten return
14
+ def push(*value)
15
+ super(value)
16
+ self.flatten!
17
+ self.uniq!
18
+ return self
19
+ end
20
+
21
+
22
+ # override of << for uniqness and flatten return
23
+ def <<(*value)
24
+ super(value)
25
+ self.flatten!
26
+ self.uniq!
27
+ return self
28
+ end
29
+
30
+ end
31
+
32
+
9
33
  # module Methodic
10
34
  # @author Romain GEORGES <romain@ultragreen.net>
11
35
  # @see http://www.ultragreen.net/projects/methodic
@@ -20,6 +44,8 @@
20
44
  # myOptions = Methodic::get_options(_options,true) do |m|
21
45
  # m.specify_known_options [:country,:name,:surname,:age]
22
46
  # m.specify_default_value :country => 'France'
47
+ # aCond = Proc::new {|option| case options when 'Doe' then true else false end }
48
+ # m.specify_condition_for :name => aCond
23
49
  # m.specify_classes_of :name => String, :surname => String, :age => Fixnum, :country => String
24
50
  # m.specify_presence_of :name
25
51
  # m.specify_presence_of :surname
@@ -43,6 +69,8 @@ module Methodic
43
69
  # myOptions = Methodic::get_options(_options,true) do |m|
44
70
  # m.specify_known_options [:country,:name,:surname,:age]
45
71
  # m.specify_default_value :country => 'France'
72
+ # aCond = Proc::new {|option| case options when 'Doe' then true else false end }
73
+ # m.specify_condition_for :name => aCond
46
74
  # m.specify_classes_of :name => String, :surname => String, :age => Fixnum, :country => String
47
75
  # m.specify_presence_of :name
48
76
  # m.specify_presence_of :surname
@@ -98,12 +126,22 @@ module Methodic
98
126
  # @example writing
99
127
  # myOptions = Methodic::get_options(options)
100
128
  # myOptions.formats = {:name => /\w+/ }
101
- # myOptions.defaults[:surname] = /\w+/
129
+ # myOptions.formats[:surname] = /\w+/
102
130
  # @example reading
103
131
  # p myOptions.defaults
104
132
  # => { :name => /\w+/, :surname => /\w+/ }
105
133
  attr_accessor :formats
106
134
 
135
+ # @attr [Hash] conditions a hash table of some conditions with their corresponding
136
+ # @example writing
137
+ # myOptions = Methodic::get_options(options)
138
+ # myOptions.conditions = {:name => aProcObject }
139
+ # myOptions.conditions[:surname] = aProcObject
140
+ # @example reading
141
+ # p myOptions.defaults
142
+ # => { :name => /\w+/, :surname => /\w+/ }
143
+ attr_accessor :conditions
144
+
107
145
  # initializer for [Options]
108
146
  # @note please do not use standalone, build from module method Methodic::get_options
109
147
  # @param [Hash] _options the options hash (define for the method you would prototype)
@@ -116,11 +154,12 @@ module Methodic
116
154
  raise ArgumentError::new('Argument _options must be a Hash') unless _options.class == Hash or _options.class == Methodic::Options # ;) reintrance and cascading
117
155
  raise ArgumentError::new('keys must be Symbol') unless _options.keys.select{|i| i.class == Symbol }.size == _options.keys.size
118
156
  self.replace _options
157
+ @conditions = Hash::new
119
158
  @defaults = Hash::new
120
159
  @formats = Hash::new
121
160
  @classes = Hash::new
122
- @known = Array::new
123
- @mandatories = Array::new
161
+ @known = List::new
162
+ @mandatories = List::new
124
163
  @validate_known_options = _validate_known_options
125
164
  yield self if block_given?
126
165
  end
@@ -161,13 +200,27 @@ module Methodic
161
200
  # myOptions.specify_class_of :name => String
162
201
  # myOptions.specify_classes_of :name => String, :surname => String
163
202
  def specify_class_of(values)
164
-
165
203
  @classes.merge! values
166
-
167
204
  return @classes
168
-
169
205
  end
170
206
  alias :specify_classes_of :specify_class_of
207
+
208
+ # pretty accessor for specifying conditions for options
209
+ # @param [Hash] values a Conditions Proc definition, keys are symbols
210
+ # @return [hash] @conditions merged with values
211
+ # @note Conditions must be precised in Ruby as a Proc Object returning a boolean
212
+ # @note Convention : Proc MUST return true or false ONLY ( false trigged the exception raising )
213
+ # @example usage
214
+ # myOptions = Methodic::get_options(_options)
215
+ # myOptions.specify_condition_for :name => aProcObject
216
+ # myOptions.specify_conditions_for :name => aProcObject, :surname => aProcObject
217
+ def specify_condition_for(values)
218
+ @conditions.merge! values
219
+ return @conditions
220
+ end
221
+ alias :specify_conditions_for :specify_condition_for
222
+
223
+
171
224
 
172
225
  # pretty accessor for specifying mandatories options
173
226
  # @param [Array] values a Array of symbols or a unique symbol
@@ -176,7 +229,7 @@ module Methodic
176
229
  # myOptions = Methodic::get_options(_options)
177
230
  # myOptions.specify_presence_of :name
178
231
  # myOptions.specify_presences_of [ :name, :surname ]
179
- def specify_presence_of(values)
232
+ def specify_presence_of(*values)
180
233
  @mandatories << values
181
234
  @mandatories.flatten!
182
235
  @mandatories.uniq!
@@ -192,7 +245,7 @@ module Methodic
192
245
  # myOptions = Methodic::get_options(_options)
193
246
  # myOptions.specify_known_option :name
194
247
  # myOptions.specify_known_options [ :name, :surname ]
195
- def specify_known_option(values)
248
+ def specify_known_option(*values)
196
249
  @known << values
197
250
  @known.flatten!
198
251
  @known.uniq!
@@ -214,12 +267,6 @@ module Methodic
214
267
  end
215
268
  alias :specify_formats_of :specify_format_of
216
269
 
217
- # pretty accessor for specifying condition for options
218
- # @todo implementation of conditions
219
- def specify_condition_for
220
- raise NotYetImplemented
221
- end
222
- alias :specify_conditions_for :specify_condition_for
223
270
 
224
271
  # default values merge method
225
272
  # merge @defaults with self
@@ -248,7 +295,7 @@ module Methodic
248
295
  table.push validate_classes unless @classes.empty?
249
296
  table.push validate_presences unless @mandatories.empty?
250
297
  table.push validate_formats unless @formats.empty?
251
-
298
+ table.push validate_conditions unless @conditions.empty?
252
299
  return true unless table.include?(false)
253
300
  end
254
301
  alias :validate! :validate
@@ -289,10 +336,20 @@ module Methodic
289
336
  end
290
337
  return true
291
338
  end
292
-
339
+
340
+ # private method for conditions validation step
341
+ def validate_conditions
342
+ @conditions.each do |option,cond|
343
+ raise ArgumentError::new("Option : #{option} condition failed") and return false unless cond.call(self[option]) == true
344
+ end
345
+ return true
346
+ end
347
+
348
+
293
349
  # private method for classes validation step
294
350
  def validate_classes
295
351
  @classes.each do |option,value|
352
+
296
353
  raise ArgumentError::new("Option : #{option} type mismatch must be a #{value}") and return false unless self[option].class == value
297
354
  end
298
355
  return true
@@ -311,8 +368,5 @@ module Methodic
311
368
  return Methodic::Options::new(_options,_validate_known_options)
312
369
  end
313
370
 
314
- # Exception Class for not yet implemented methods Exceptions
315
- class NotYetImplemented < Exception; end
316
-
317
371
 
318
372
  end
data/methodic.gemspec CHANGED
@@ -1,8 +1,8 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{methodic}
3
3
  s.author = "Romain GEORGES"
4
- s.version = "1.1"
5
- s.date = %q{2013-02-14}
4
+ s.version = "1.2"
5
+ s.date = %q{2013-02-18}
6
6
  s.summary = %q{Methodic : Hash table options specification and validation componant}
7
7
  s.email = %q{romain@ultragreen.net}
8
8
  s.homepage = %q{http://www.ultragreen.net}
@@ -9,7 +9,7 @@ describe Methodic do
9
9
  $test_methodic_options_with_known_options = Methodic::get_options({:name => 'Doe', :surname => 'John'},true)
10
10
  end
11
11
  before :each do
12
- $test_methodic_options.mandatories = []
12
+ $test_methodic_options.mandatories.clear
13
13
  $test_methodic_options.formats = {}
14
14
  $test_methodic_options.defaults = {}
15
15
  $test_methodic_options.classes = {}
@@ -91,33 +91,70 @@ describe Methodic do
91
91
  end
92
92
  end
93
93
 
94
+ context "#conditions R/W" do
95
+ it { $test_methodic_options.should respond_to("conditions") }
96
+ it { $test_methodic_options.should respond_to("conditions=") }
97
+
98
+ it "should be true that #conditions must return a Hash" do
99
+ $test_methodic_options.conditions.class.should eq(Hash)
100
+ end
101
+ it "#formats[] affectation must be possible and #formats must respond this affectation" do
102
+ aCond = Proc::new do |option| case option
103
+ when 'Doe' then true
104
+ else false
105
+ end
106
+ end
107
+ $test_methodic_options.conditions[:name] = aCond
108
+ $test_methodic_options.conditions.should eq({ :name => aCond })
109
+ end
110
+ end
111
+
94
112
  context "#mandatories R/W" do
95
113
  it { $test_methodic_options.should respond_to("mandatories") }
96
114
  it { $test_methodic_options.should respond_to("mandatories=") }
97
115
 
98
- it "should be true that #mandatories must return a Array" do
99
- $test_methodic_options.mandatories.class.should eq(Array)
116
+ it "should be true that #mandatories must return a List < Array" do
117
+ $test_methodic_options.mandatories.class.should eq(List)
100
118
  end
101
119
  it "#mandatories.push affectation must be possible and #mandatories must respond this affectation" do
102
120
  $test_methodic_options.mandatories.push :test
103
121
  $test_methodic_options.mandatories.should eq([:test])
104
122
  end
123
+ context "#mandatories.push" do
124
+ it "should not duplicate entry"do
125
+ $test_methodic_options.mandatories.push :test
126
+ $test_methodic_options.mandatories.push :test
127
+ $test_methodic_options.mandatories.count(:test).should eq 1
128
+ end
129
+ end
105
130
  end
131
+
132
+
106
133
  context "#known R/W" do
107
134
  it { $test_methodic_options.should respond_to("known") }
108
135
  it { $test_methodic_options.should respond_to("known=") }
109
136
 
110
- it "should be true that #known must return a Array" do
111
- $test_methodic_options.known.class.should eq(Array)
137
+ it "should be true that #known must return a List < Array" do
138
+ $test_methodic_options.known.class.should eq(List)
112
139
  end
113
140
  it "#known.push affectation must be possible and #known must respond this affectation" do
114
141
  $test_methodic_options.known.push :test
115
142
  $test_methodic_options.known.should include :test
116
143
  end
144
+ context "#known.push" do
145
+ it "should not duplicate entry" do
146
+ $test_methodic_options.known.push :test
147
+ $test_methodic_options.known.push :test
148
+ $test_methodic_options.known.count(:test).should eq 1
149
+ end
150
+ end
117
151
  end
118
152
  end
119
153
  context "Instance methods" do
120
154
 
155
+
156
+
157
+
121
158
  context "#options" do
122
159
  it { $test_methodic_options.should respond_to("options") }
123
160
  it "should be true that #options must return a Array" do
@@ -172,7 +209,33 @@ describe Methodic do
172
209
  context "#specify_condition_for" do
173
210
  it { $test_methodic_options.should respond_to("specify_condition_for") }
174
211
  it { $test_methodic_options.should respond_to("specify_conditions_for") }
175
- it { lambda{ $test_methodic_options.specify_condition_for}.should raise_error Methodic::NotYetImplemented }
212
+ it "should merge condition hash record in conditions attribut" do
213
+ aCond = Proc::new do |option| case option
214
+ when "Doe" then true
215
+ else false
216
+ end
217
+ end
218
+ $test_methodic_options.specify_condition_for :name => aCond
219
+ $test_methodic_options.conditions[:name].should eq aCond
220
+ $test_methodic_options.conditions.count.should eq 1
221
+ end
222
+ it "should redefine a new class value for a previous key" do
223
+ aCond = Proc::new do |option| case option
224
+ when "Doe" then true
225
+ else false
226
+ end
227
+ end
228
+ newCond = Proc::new do |option| case option
229
+ when "DoeLittle" then true
230
+ else false
231
+ end
232
+ end
233
+ $test_methodic_options.specify_condition_for :name => aCond
234
+ $test_methodic_options.conditions[:name].should eq aCond
235
+ $test_methodic_options.specify_condition_for :name => newCond
236
+ $test_methodic_options.conditions[:name].should eq newCond
237
+ $test_methodic_options.conditions = {}
238
+ end
176
239
  end
177
240
 
178
241
  context "#specify_format_of" do
@@ -203,6 +266,10 @@ describe Methodic do
203
266
  $test_methodic_options.mandatories.should include(:test)
204
267
  $test_methodic_options.mandatories.count.should eq 1
205
268
  end
269
+ it "should be possible to give arguments list of symbols" do
270
+ $test_methodic_options.specify_presences_of :test2, :test3, :test4
271
+ $test_methodic_options.specify_presences_of [ :test5, :test6 ], :test7
272
+ end
206
273
  end
207
274
 
208
275
  context "#specify_known_option" do
@@ -216,6 +283,11 @@ describe Methodic do
216
283
  $test_methodic_options.known.should include(:test)
217
284
  $test_methodic_options.known.count.should eq 1
218
285
  end
286
+ it "should be possible to give arguments list of symbols" do
287
+ $test_methodic_options.specify_known_options :test2, :test3, :test4
288
+ $test_methodic_options.specify_known_options [ :test5, :test6 ], :test7
289
+
290
+ end
219
291
  end
220
292
 
221
293
  context "#validate" do
@@ -337,6 +409,30 @@ describe Methodic do
337
409
  lambda{$test_methodic_options.validate!}.should_not raise_error ArgumentError
338
410
  end
339
411
  end
412
+ context "5/ validate conditions" do
413
+ it "should raise ArgumentError if an option in options list not validate a registered condition" do
414
+ $test_methodic_options.conditions = {}
415
+ aCond = Proc::new do |option| case option
416
+ when 'DoeLittle' then true
417
+ else false
418
+ end
419
+ end
420
+ $test_methodic_options.specify_condition_for :name => aCond
421
+ lambda{$test_methodic_options.validate!}.should raise_error ArgumentError
422
+
423
+ end
424
+ it "should not raise if all options in options list match formats definitions " do
425
+ $test_methodic_options.conditions = {}
426
+ aCond = Proc::new do |option| case option
427
+ when 'Doe' then true
428
+ else false
429
+ end
430
+ end
431
+ $test_methodic_options.specify_condition_for :name => aCond
432
+ lambda{$test_methodic_options.validate!}.should_not raise_error ArgumentError
433
+ end
434
+ end
435
+
340
436
 
341
437
 
342
438
  end
metadata CHANGED
@@ -1,11 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: methodic
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 11
5
+ prerelease:
5
6
  segments:
6
7
  - 1
7
- - 1
8
- version: "1.1"
8
+ - 2
9
+ version: "1.2"
9
10
  platform: ruby
10
11
  authors:
11
12
  - Romain GEORGES
@@ -13,16 +14,18 @@ autorequire:
13
14
  bindir:
14
15
  cert_chain: []
15
16
 
16
- date: 2013-02-14 00:00:00 +01:00
17
+ date: 2013-02-18 00:00:00 +01:00
17
18
  default_executable:
18
19
  dependencies:
19
20
  - !ruby/object:Gem::Dependency
20
21
  name: rspec
21
22
  prerelease: false
22
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
23
25
  requirements:
24
26
  - - ">="
25
27
  - !ruby/object:Gem::Version
28
+ hash: 15
26
29
  segments:
27
30
  - 2
28
31
  - 0
@@ -67,25 +70,29 @@ rdoc_options:
67
70
  require_paths:
68
71
  - lib
69
72
  required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
70
74
  requirements:
71
75
  - - ">="
72
76
  - !ruby/object:Gem::Version
77
+ hash: 53
73
78
  segments:
74
79
  - 1
75
80
  - 8
76
81
  - 1
77
82
  version: 1.8.1
78
83
  required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
79
85
  requirements:
80
86
  - - ">="
81
87
  - !ruby/object:Gem::Version
88
+ hash: 3
82
89
  segments:
83
90
  - 0
84
91
  version: "0"
85
92
  requirements: []
86
93
 
87
94
  rubyforge_project: nowarning
88
- rubygems_version: 1.3.6
95
+ rubygems_version: 1.4.2
89
96
  signing_key:
90
97
  specification_version: 3
91
98
  summary: "Methodic : Hash table options specification and validation componant"