methodic 1.1 → 1.2

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