Checked 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +4 -0
- data/Checked.gemspec +30 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +1 -0
- data/lib/Checked/Args.rb +55 -0
- data/lib/Checked/Ask/DSL.rb +31 -0
- data/lib/Checked/Ask/Mods/Arrays.rb +25 -0
- data/lib/Checked/Ask/Mods/Strings.rb +26 -0
- data/lib/Checked/Ask/Mods/Vars.rb +12 -0
- data/lib/Checked/Ask.rb +69 -0
- data/lib/Checked/Base.rb +119 -0
- data/lib/Checked/Clean/DSL.rb +16 -0
- data/lib/Checked/Clean/Mods/Strings.rb +98 -0
- data/lib/Checked/Clean.rb +41 -0
- data/lib/Checked/Demand/DSL.rb +29 -0
- data/lib/Checked/Demand/Mods/Arrays.rb +72 -0
- data/lib/Checked/Demand/Mods/Bools.rb +37 -0
- data/lib/Checked/Demand/Mods/File_Addresses.rb +56 -0
- data/lib/Checked/Demand/Mods/Strings.rb +51 -0
- data/lib/Checked/Demand/Mods/Symbols.rb +20 -0
- data/lib/Checked/Demand/Mods/Vars.rb +91 -0
- data/lib/Checked/Demand.rb +46 -0
- data/lib/Checked/version.rb +3 -0
- data/lib/Checked.rb +14 -0
- data/spec/helper.rb +15 -0
- data/spec/main.rb +32 -0
- data/spec/tests/Ask.rb +13 -0
- data/spec/tests/Ask_Strings.rb +57 -0
- data/spec/tests/Checked.rb +43 -0
- data/spec/tests/Clean.rb +13 -0
- data/spec/tests/Clean_Strings.rb +76 -0
- data/spec/tests/Demand.rb +39 -0
- data/spec/tests/Demand_Arrays.rb +31 -0
- data/spec/tests/Demand_File_Addresses.rb +37 -0
- data/spec/tests/Demand_Vars.rb +19 -0
- metadata +117 -0
data/.document
ADDED
data/.gitignore
ADDED
data/Checked.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "Checked/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "Checked"
|
7
|
+
s.version = Checked::VERSION
|
8
|
+
s.authors = ["da99"]
|
9
|
+
s.email = ["i-hate-spam-45671204@mailinator.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Check your types and more.}
|
12
|
+
s.description = %q{
|
13
|
+
Various DSLs to clean, question (Ask), and validate (Demand) your objects,
|
14
|
+
their classes (data types), and their properties.
|
15
|
+
}
|
16
|
+
|
17
|
+
s.rubyforge_project = "Checked"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
|
24
|
+
# specify any dependencies here; for example:
|
25
|
+
# s.add_development_dependency "rspec"
|
26
|
+
# s.add_runtime_dependency "rest-client"
|
27
|
+
s.add_development_dependency 'rake'
|
28
|
+
s.add_development_dependency 'bacon'
|
29
|
+
s.add_development_dependency 'Bacon_Colored'
|
30
|
+
end
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 da99
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= Checked
|
2
|
+
|
3
|
+
Check types and more in your code.
|
4
|
+
|
5
|
+
== Contributing to Checked
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
+
* Fork the project
|
10
|
+
* Start a feature/bugfix branch
|
11
|
+
* Commit and push until you are happy with your contribution
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2011 da99. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/Checked/Args.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
module Checked
|
3
|
+
|
4
|
+
class Args
|
5
|
+
|
6
|
+
Unknown_Class = Class.new(RuntimeError)
|
7
|
+
|
8
|
+
module Base
|
9
|
+
|
10
|
+
def initialize *arr
|
11
|
+
arr.flatten.each { |var|
|
12
|
+
case var
|
13
|
+
when Array
|
14
|
+
var.each { |k|
|
15
|
+
define k
|
16
|
+
}
|
17
|
+
when Hash
|
18
|
+
var.each { |k,v|
|
19
|
+
define k
|
20
|
+
send("#{k}=", v)
|
21
|
+
}
|
22
|
+
else
|
23
|
+
raise Unknown_Class, var.inspect
|
24
|
+
end
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def define *raw
|
29
|
+
raw.flatten.each { |k|
|
30
|
+
eval %~
|
31
|
+
|
32
|
+
def #{k}
|
33
|
+
@#{k}
|
34
|
+
end
|
35
|
+
|
36
|
+
def #{k}= v
|
37
|
+
@#{k} = v
|
38
|
+
end
|
39
|
+
|
40
|
+
~
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def defined? key
|
45
|
+
respond_to?( key ) &&
|
46
|
+
respond_to?( :"#{key}=" )
|
47
|
+
end
|
48
|
+
|
49
|
+
end # === module Base
|
50
|
+
|
51
|
+
include Base
|
52
|
+
|
53
|
+
end # === module Args
|
54
|
+
|
55
|
+
end # === module Checked
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'Checked/Demand/DSL'
|
2
|
+
|
3
|
+
module Checked
|
4
|
+
class Ask
|
5
|
+
module DSL
|
6
|
+
|
7
|
+
include Demand::DSL
|
8
|
+
|
9
|
+
def ask? target, *args
|
10
|
+
Checked::Ask.new(target) { |a|
|
11
|
+
a.<< args
|
12
|
+
}.true?
|
13
|
+
end
|
14
|
+
|
15
|
+
def true? target, *args
|
16
|
+
demand! block_given?, :no_block!
|
17
|
+
q = Ask.new(target)
|
18
|
+
q << args
|
19
|
+
q.true?
|
20
|
+
end
|
21
|
+
|
22
|
+
def any? target, *args
|
23
|
+
demand! block_given?, :no_block!
|
24
|
+
q = Ask.new(target)
|
25
|
+
q << args
|
26
|
+
q.any?
|
27
|
+
end
|
28
|
+
|
29
|
+
end # === module DSL
|
30
|
+
end # === class Ask
|
31
|
+
end # === module Checked
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Checked
|
4
|
+
class Ask
|
5
|
+
module Mods
|
6
|
+
module Arrays
|
7
|
+
|
8
|
+
def self.apply?(d)
|
9
|
+
d.target.is_a?(Array)
|
10
|
+
end
|
11
|
+
|
12
|
+
def symbols?
|
13
|
+
valid! target, :array!
|
14
|
+
return false if target.empty?
|
15
|
+
target.all? { |val| val.is_a? Symbol }
|
16
|
+
end
|
17
|
+
|
18
|
+
def excludes? matcher
|
19
|
+
!target.includes?(matcher)
|
20
|
+
end
|
21
|
+
|
22
|
+
end # === module Arrays
|
23
|
+
end # === module Mods
|
24
|
+
end # === class Ask
|
25
|
+
end # === class Checked
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
module Checked
|
3
|
+
class Ask
|
4
|
+
module Mods
|
5
|
+
module Strings
|
6
|
+
|
7
|
+
def self.apply? d
|
8
|
+
d.target.is_a?(String)
|
9
|
+
end
|
10
|
+
|
11
|
+
def empty?
|
12
|
+
target.strip.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
def includes? matcher
|
16
|
+
!!target[matcher]
|
17
|
+
end
|
18
|
+
|
19
|
+
def excludes? matcher
|
20
|
+
!includes?(matcher)
|
21
|
+
end
|
22
|
+
|
23
|
+
end # === module Strings
|
24
|
+
end # === module Mods
|
25
|
+
end # === class Ask
|
26
|
+
end # === module Checked
|
data/lib/Checked/Ask.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'Checked/Base'
|
2
|
+
require 'Checked/Ask/DSL'
|
3
|
+
|
4
|
+
module Checked
|
5
|
+
class Ask
|
6
|
+
module Base
|
7
|
+
|
8
|
+
private # ==============================
|
9
|
+
|
10
|
+
include ::Checked::Base
|
11
|
+
|
12
|
+
#
|
13
|
+
# Demand::DSL is not used here
|
14
|
+
# because it uses the Questioner.
|
15
|
+
# It would cause an stack level/infinite loop
|
16
|
+
# error.
|
17
|
+
#
|
18
|
+
def valid! target, *args
|
19
|
+
v = Demand.new(target)
|
20
|
+
if args.empty?
|
21
|
+
yield v
|
22
|
+
else
|
23
|
+
raise "No block allowed with arguments: #{args.inspect}" if block_given?
|
24
|
+
v << args
|
25
|
+
end
|
26
|
+
|
27
|
+
v.target
|
28
|
+
end
|
29
|
+
|
30
|
+
public # ==============================
|
31
|
+
|
32
|
+
attr_reader :records
|
33
|
+
|
34
|
+
def before_init
|
35
|
+
@records = []
|
36
|
+
end
|
37
|
+
|
38
|
+
def < name, *args, &blok
|
39
|
+
a = super
|
40
|
+
valid!(a, :bool!)
|
41
|
+
records << a
|
42
|
+
a
|
43
|
+
end
|
44
|
+
|
45
|
+
def << *methods
|
46
|
+
valid! block_given?, :no_block!
|
47
|
+
super(*methods) { |name|
|
48
|
+
self.< name
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def true?
|
53
|
+
return false if records.empty?
|
54
|
+
records.all?
|
55
|
+
end
|
56
|
+
|
57
|
+
def any?
|
58
|
+
return false if records.empty?
|
59
|
+
records.any?
|
60
|
+
end
|
61
|
+
|
62
|
+
private # ==============================
|
63
|
+
|
64
|
+
|
65
|
+
end # === module Base
|
66
|
+
|
67
|
+
include Base
|
68
|
+
end # === class Ask
|
69
|
+
end # === module Checked
|
data/lib/Checked/Base.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
|
2
|
+
module Checked
|
3
|
+
module Base
|
4
|
+
|
5
|
+
def self.included var
|
6
|
+
klass_name = var.to_s.gsub(/::Base$/, '').split('::').last
|
7
|
+
klass = Checked.const_get(klass_name)
|
8
|
+
|
9
|
+
files = Dir.glob(File.join File.dirname(__FILE__), "#{klass_name}/Mods/*.rb")
|
10
|
+
raise "No Mods found for #{klass}" if files.empty?
|
11
|
+
|
12
|
+
files.each { |path|
|
13
|
+
name = File.basename(path).sub('.rb', '')
|
14
|
+
require "Checked/#{klass_name}/Mods/#{name}"
|
15
|
+
if name == 'Vars'
|
16
|
+
klass.class_eval {
|
17
|
+
include klass::Mods::Vars
|
18
|
+
}
|
19
|
+
else
|
20
|
+
klass.const_set(:Mod_List, []) unless klass.const_defined?(:Mod_List)
|
21
|
+
klass::Mod_List << klass::Mods.const_get(name)
|
22
|
+
end
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_accessor :target
|
27
|
+
attr_reader :target_name
|
28
|
+
|
29
|
+
def initialize target, &blok
|
30
|
+
|
31
|
+
if respond_to? :before_init
|
32
|
+
if method(:before_init).parameters === []
|
33
|
+
before_init
|
34
|
+
else
|
35
|
+
before_init target, &blok
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
@target = target
|
40
|
+
@target_name = target.respond_to?(:english_name) ?
|
41
|
+
target.english_name :
|
42
|
+
"#{target.class.name.gsub('_', ' ')}, #{target.inspect},"
|
43
|
+
|
44
|
+
self.class.const_get(:Mod_List).each { |mod|
|
45
|
+
if mod.apply?(self)
|
46
|
+
extend mod
|
47
|
+
end
|
48
|
+
}
|
49
|
+
|
50
|
+
if respond_to? :after_init
|
51
|
+
if method(:after_init).parameters === []
|
52
|
+
after_init
|
53
|
+
else
|
54
|
+
after_init target, &blok
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
yield(self) if block_given?
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Sets the name.
|
63
|
+
#
|
64
|
+
def * name
|
65
|
+
@target_name = "#{name}, #{target.inspect},"
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# ::Checked::Demand => demand
|
71
|
+
# ::Checked::Clean => clean
|
72
|
+
# ::Checked::Ask => ask
|
73
|
+
#
|
74
|
+
def purpose
|
75
|
+
@purpose ||= self.class.name.split('::').last.downcase.sub(/er$/, '')
|
76
|
+
end
|
77
|
+
|
78
|
+
def < name, *args, &blok
|
79
|
+
send(name, *args, &blok)
|
80
|
+
end
|
81
|
+
|
82
|
+
def << *methods
|
83
|
+
meths = begin
|
84
|
+
::Checked::Demand.new(methods.flatten) { |d|
|
85
|
+
d.* "(Originally: #{target_name})"
|
86
|
+
d.instance_eval { not_empty!; symbols! }
|
87
|
+
}.target
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
meths.each { |name|
|
92
|
+
|
93
|
+
begin
|
94
|
+
if block_given?
|
95
|
+
yield name
|
96
|
+
else
|
97
|
+
send name
|
98
|
+
end
|
99
|
+
rescue NoMethodError => e
|
100
|
+
raise e if !e.message[/undefined method `#{name.to_s}' for/]
|
101
|
+
to_name = lambda { |m| m.to_s.split('::').last }
|
102
|
+
mods = self.class::Mod_List.select { |m| m.instance_methods.include?(name.to_sym) }
|
103
|
+
all = self.class::Mod_List
|
104
|
+
|
105
|
+
if mods.empty?
|
106
|
+
e_msg = e.message
|
107
|
+
raise NoMethodError, "#{e_msg} using mods: #{all.map(&to_name).join(', ')}"
|
108
|
+
else
|
109
|
+
raise NoMethodError, err_msg(
|
110
|
+
"...can not #{purpose} #{name}, which is found in: #{mods.map(&to_name).join(', ')}"
|
111
|
+
)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
}
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
end # === module Base
|
119
|
+
end # === module Checked
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
module Checked
|
3
|
+
class Clean
|
4
|
+
module DSL
|
5
|
+
|
6
|
+
def clean target, *args
|
7
|
+
raise "No block allowed here." if block_given?
|
8
|
+
|
9
|
+
c = Clean.new(target)
|
10
|
+
c.<(*args)
|
11
|
+
c.target
|
12
|
+
end
|
13
|
+
|
14
|
+
end # === module DSL
|
15
|
+
end # === class Clean
|
16
|
+
end # === module Checked
|
@@ -0,0 +1,98 @@
|
|
1
|
+
|
2
|
+
module Checked
|
3
|
+
class Clean
|
4
|
+
module Mods
|
5
|
+
module Strings
|
6
|
+
|
7
|
+
def self.apply? d
|
8
|
+
d.target.is_a?(String) ||
|
9
|
+
d.target.is_a?(StringIO)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.on_apply d
|
13
|
+
case d.target
|
14
|
+
when StringIO
|
15
|
+
d.target.rewind
|
16
|
+
d.target= d.target.readlines
|
17
|
+
else
|
18
|
+
# Do nothing.
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def file_names matcher
|
23
|
+
strip.split.select { |word| word[matcher] }
|
24
|
+
end
|
25
|
+
|
26
|
+
def file_names_by_ext ext
|
27
|
+
names = file_names(ext)
|
28
|
+
bases = names.map { |s|
|
29
|
+
s.sub(%r!#{ext}$!, '')
|
30
|
+
}
|
31
|
+
|
32
|
+
names.zip bases
|
33
|
+
end
|
34
|
+
|
35
|
+
def shell
|
36
|
+
target
|
37
|
+
.strip
|
38
|
+
.split("\n")
|
39
|
+
.map(&:strip)
|
40
|
+
.reject { |line| line.empty? }
|
41
|
+
.join(' && ')
|
42
|
+
end
|
43
|
+
|
44
|
+
def chop_ext
|
45
|
+
target.sub /\.[^\.]+$/, ''
|
46
|
+
end
|
47
|
+
|
48
|
+
def ruby_name
|
49
|
+
c = ::Checked::Clean.new( File.basename( target ) )
|
50
|
+
c.< :chop_rb
|
51
|
+
c.target
|
52
|
+
end
|
53
|
+
|
54
|
+
def chop_rb
|
55
|
+
target.sub %r!\.rb$!, ''
|
56
|
+
end
|
57
|
+
|
58
|
+
def chop_slash_r
|
59
|
+
target.gsub "\r", ''
|
60
|
+
end
|
61
|
+
|
62
|
+
def os_stardard
|
63
|
+
chop_slash_r.strip
|
64
|
+
end
|
65
|
+
|
66
|
+
def file_names matcher
|
67
|
+
strip.split.select { |word| word[matcher] }
|
68
|
+
end
|
69
|
+
|
70
|
+
def file_names_by_ext ext
|
71
|
+
names = file_names(ext)
|
72
|
+
bases = names.map { |s|
|
73
|
+
s.sub(%r!#{ext}$!, '')
|
74
|
+
}
|
75
|
+
|
76
|
+
names.zip bases
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_single
|
80
|
+
target.gsub( /s\Z/, '' )
|
81
|
+
end
|
82
|
+
|
83
|
+
def to_plural
|
84
|
+
target.to_single + 's'
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_class_name
|
88
|
+
target.split('_').map(&:capitalize).join('_')
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_camel_case
|
92
|
+
target.split('_').map(&:capitalize).join
|
93
|
+
end
|
94
|
+
|
95
|
+
end # === module Strings
|
96
|
+
end # === module Mods
|
97
|
+
end # === class Clean
|
98
|
+
end # === module Checked
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "Checked/Base"
|
2
|
+
require "Checked/Clean/DSL"
|
3
|
+
require "Checked/Demand/DSL"
|
4
|
+
|
5
|
+
module Checked
|
6
|
+
class Clean
|
7
|
+
module Base
|
8
|
+
|
9
|
+
private # =============================
|
10
|
+
include ::Checked::Demand::DSL
|
11
|
+
|
12
|
+
public # ==============================
|
13
|
+
include ::Checked::Base
|
14
|
+
|
15
|
+
def < meth, *args
|
16
|
+
val = super
|
17
|
+
named_demand!("Cleaned val", val, :not_nil!)
|
18
|
+
|
19
|
+
self.target= super
|
20
|
+
end
|
21
|
+
|
22
|
+
def << *args
|
23
|
+
args.flatten.each { |name|
|
24
|
+
self.< name
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
private # ===========================================
|
29
|
+
|
30
|
+
def target= val
|
31
|
+
named_demand! "Clean target", val, :not_nil!
|
32
|
+
|
33
|
+
@target = val
|
34
|
+
end
|
35
|
+
|
36
|
+
end # === module Base
|
37
|
+
|
38
|
+
include Base
|
39
|
+
|
40
|
+
end # === class Clean
|
41
|
+
end # === class Checked
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module Checked
|
3
|
+
class Demand
|
4
|
+
module DSL
|
5
|
+
|
6
|
+
def demand! target, *args
|
7
|
+
if block_given?
|
8
|
+
raise "No block allowed here."
|
9
|
+
end
|
10
|
+
|
11
|
+
Demand.new(target) { |d|
|
12
|
+
d.<< args
|
13
|
+
}.target
|
14
|
+
end
|
15
|
+
|
16
|
+
def named_demand! name, target, *args
|
17
|
+
if block_given?
|
18
|
+
raise "No block allowed here."
|
19
|
+
end
|
20
|
+
|
21
|
+
Demand.new(target) { |d|
|
22
|
+
d.* name
|
23
|
+
d.<< args
|
24
|
+
}.target
|
25
|
+
end
|
26
|
+
|
27
|
+
end # === module Dsl
|
28
|
+
end # === class Demand
|
29
|
+
end # === module Checked
|
@@ -0,0 +1,72 @@
|
|
1
|
+
|
2
|
+
module Checked
|
3
|
+
class Demand
|
4
|
+
module Mods
|
5
|
+
module Arrays
|
6
|
+
|
7
|
+
def self.before_apply d
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.apply? d
|
11
|
+
d.target.is_a?(Array)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.after_apply d
|
15
|
+
end
|
16
|
+
|
17
|
+
def no_nils!
|
18
|
+
array!
|
19
|
+
if target.include?(nil)
|
20
|
+
fail!("...can't contain nils.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def no_empty_strings!
|
25
|
+
array!
|
26
|
+
target.each { |s|
|
27
|
+
|
28
|
+
if s.respond_to?(:rewind)
|
29
|
+
s.rewind
|
30
|
+
end
|
31
|
+
|
32
|
+
final = if s.respond_to?(:readlines)
|
33
|
+
s.readlines
|
34
|
+
else
|
35
|
+
s
|
36
|
+
end
|
37
|
+
|
38
|
+
if final.is_a?(String) && final.strip.empty?
|
39
|
+
fail!("...can't contain empty strings.")
|
40
|
+
end
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def symbols!
|
45
|
+
array!
|
46
|
+
not_empty!
|
47
|
+
if !target.all? { |v| v.is_a?(Symbol) }
|
48
|
+
fail! "...contains a non-symbol."
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def include! matcher
|
53
|
+
included = target.include?(matcher)
|
54
|
+
return true if included
|
55
|
+
fail!("...must contain: #{matcher.inspect}")
|
56
|
+
end
|
57
|
+
|
58
|
+
def exclude! matcher
|
59
|
+
raise_e = val.include?(matcher)
|
60
|
+
return true unless raise_e
|
61
|
+
fail!("...can't contain #{matcher.inspect}")
|
62
|
+
end
|
63
|
+
|
64
|
+
def matches_only! matcher
|
65
|
+
arr = target.reject { |val| val == matcher }
|
66
|
+
fail!( "...invalid elements: #{arr.inspect}" ) if !arr.empty?
|
67
|
+
end
|
68
|
+
|
69
|
+
end # === module Arrays
|
70
|
+
end # === module Mods
|
71
|
+
end # === class Demand
|
72
|
+
end # === module Checked
|