valuedate 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ doc
2
+ pkg
3
+ coverage
4
+ tags
data/README.rdoc ADDED
@@ -0,0 +1,61 @@
1
+ = Valuedate
2
+
3
+ Validates values using a schema.
4
+
5
+ Source[http://github.com/splattael/valuedate] | RDoc[http://rdoc.info/projects/splattael/valuedate] | Metrics[http://getcaliper.com/caliper/project?repo=git%3A%2F%2Fgithub.com%2Fsplattael%2Fvaluedate.git]
6
+
7
+ == Usage
8
+
9
+ schema = Valuedate.schema do
10
+ value.is_a(String).equals("test")
11
+ end
12
+
13
+ schema.validate("test") # => true
14
+ schema.validate("fail") # => false
15
+ schema.validate(23) # => false
16
+
17
+ deep = Valuedate.schema do
18
+ value.hash(
19
+ :type => value.is_a(String),
20
+ :value => value.hash(
21
+ :src => value.is_a(String),
22
+ :height => optional_value.is_a(Fixnum),
23
+ :width => optional_value.is_a(Fixnum)
24
+ )
25
+ )
26
+ end
27
+
28
+ deep.validate(
29
+ :type => "image",
30
+ :value => {
31
+ :src => "/bold.gif",
32
+ :height => 80,
33
+ :width => 80
34
+ }
35
+ ) # => true
36
+
37
+ # :height and width are optional
38
+ deep.validate(:type => "image", :value => { :src => "/bold.gif" }) # => true
39
+
40
+ == Matchers
41
+
42
+ Following matchers are defined:
43
+ * is_a(Class)
44
+ * equals(expected)
45
+ * any(list of validators)
46
+ * is(range, array or anything that responds_to #include?)
47
+
48
+ == Defining matchers
49
+
50
+ Valuedate.matcher(:equals) { |value, expected| value == expected }
51
+
52
+ == Install
53
+
54
+ git clone ...
55
+ rake install
56
+
57
+ == Authors
58
+ * Peter Suschlik
59
+
60
+ == TODO
61
+ * Implement and aggregate errors
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rake'
2
+
3
+ begin
4
+ require 'jeweler'
5
+ Jeweler::Tasks.new do |gem|
6
+ gem.name = "valuedate"
7
+ gem.summary = 'Validates values.'
8
+ gem.email = "peter-valuedate@suschlik.de"
9
+ gem.homepage = "http://github.com/splattael/valuedate"
10
+ gem.authors = ["Peter Suschlik"]
11
+
12
+ gem.has_rdoc = true
13
+ gem.extra_rdoc_files = [ "README.rdoc" ]
14
+
15
+ gem.add_dependency "riot", ">= 0.10.11"
16
+ gem.add_development_dependency "riot_notifier"
17
+
18
+ gem.test_files = Dir.glob('test/test_*.rb')
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
23
+ end
24
+
25
+ # Test
26
+ require 'rake/testtask'
27
+ desc 'Default: run unit tests.'
28
+ task :default => :test
29
+ task :test => :check_dependencies
30
+
31
+ Rake::TestTask.new(:test) do |test|
32
+ test.test_files = FileList.new('test/test_*.rb')
33
+ test.libs << 'test'
34
+ test.verbose = true
35
+ end
36
+
37
+ # RDoc
38
+ require 'rake/rdoctask'
39
+ Rake::RDocTask.new do |rd|
40
+ rd.title = "Valuedate"
41
+ rd.main = "README.rdoc"
42
+ rd.rdoc_files.include("README.rdoc", "lib/*.rb")
43
+ rd.rdoc_dir = "doc"
44
+ end
45
+
46
+
47
+ # Misc
48
+ desc "Tag files for vim"
49
+ task :ctags do
50
+ dirs = $LOAD_PATH.select {|path| File.directory?(path) }
51
+ system "ctags -R #{dirs.join(" ")}"
52
+ end
53
+
54
+ desc "Find whitespace at line ends"
55
+ task :eol do
56
+ system "grep -nrE ' +$' *"
57
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
data/lib/valuedate.rb ADDED
@@ -0,0 +1,86 @@
1
+ class Valuedate
2
+
3
+ class Scope
4
+ def value
5
+ Value.new
6
+ end
7
+
8
+ def optional_value
9
+ OptionalValue.new
10
+ end
11
+ end
12
+
13
+ class Value < Valuedate
14
+ end
15
+
16
+ class OptionalValue < Valuedate
17
+ def validate(value = nil)
18
+ value.nil? || super
19
+ end
20
+ end
21
+
22
+
23
+ def initialize(&block)
24
+ @validators = []
25
+ if block
26
+ validator = Scope.new.instance_eval(&block)
27
+ @validators << validator if validator.respond_to?(:call)
28
+ end
29
+ end
30
+
31
+ def hash(schema={})
32
+ valid? do |value|
33
+ value ||= {}
34
+ schema.all? do |(key, validator)|
35
+ validator.validate(value[key])
36
+ end
37
+ end
38
+ end
39
+
40
+ def validate(value = nil)
41
+ @validators.all? { |validator| validator.call(value) }
42
+ end
43
+
44
+ def call(value)
45
+ validate(value)
46
+ end
47
+
48
+ def valid?(&block)
49
+ @validators << block
50
+ self
51
+ end
52
+
53
+ def method_missing(method, *args, &block)
54
+ if matcher = Valuedate.matchers[method]
55
+ valid? { |value| matcher.call(value, *args) }
56
+ else
57
+ super
58
+ end
59
+ end
60
+
61
+ @matchers = {}
62
+ class << self
63
+ attr_reader :matchers
64
+
65
+ def validate(value, &block)
66
+ schema(&block).validate(value)
67
+ end
68
+
69
+ def schema(&block)
70
+ new(&block)
71
+ end
72
+
73
+ def matcher(name, &block)
74
+ undef_method(name) if respond_to?(name)
75
+ @matchers[name] = block
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ Valuedate.matcher(:equals) { |value, expected| value == expected }
82
+ Valuedate.matcher(:is_a) { |value, expected| value.is_a?(expected) }
83
+ Valuedate.matcher(:any) do |value, *validators|
84
+ validators.any? { |validator| validator.validate(value) }
85
+ end
86
+ Valuedate.matcher(:in) { |value, expected| expected.include?(value) }
data/test.watchr ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env watchr
2
+
3
+ begin
4
+ require File.join(ENV["HOME"], ".watchr.test.rb")
5
+ rescue LoadError
6
+ warn "Unable to load #{File.join(ENV["HOME"], ".watchr.test.rb")}"
7
+ warn "You might try this: http://gist.github.com/raw/273574/8804dff44b104e9b8706826dc8882ed985b4fd13/.watchr.test.rb"
8
+ exit
9
+ end
10
+
11
+ run_tests
12
+
13
+ watch('test/test_.*\.rb') {|md| run md[0] }
14
+ watch('lib/(.*)\.rb') {|md| run "test/test_#{underscore(md[1])}.rb" }
15
+ watch('test/helper.rb') { run_tests }
16
+
17
+ watch('VERSION') do
18
+ puts "Building gem"
19
+ system "rake build"
20
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'riot'
3
+ require 'riot_notifier'
4
+
5
+ require 'valuedate'
6
+
7
+ Riot.reporter = RiotNotifier
@@ -0,0 +1,172 @@
1
+ require 'helper'
2
+
3
+ class Riot::Situation
4
+ def v(value=nil, &block)
5
+ Valuedate.validate(value, &block)
6
+ end
7
+ end
8
+
9
+ context "Valuedate" do
10
+
11
+ asserts(:class) { Valuedate.schema }.equals(Valuedate)
12
+
13
+ context "empty" do
14
+ asserts("valid without block") { v }
15
+ asserts("valid empty block") { v {} }
16
+ asserts("valid nil block") { v { nil } }
17
+ asserts("valid nil") { v(nil) }
18
+ asserts("valid 1") { v(1) }
19
+ end
20
+
21
+ context "callable" do
22
+ asserts("valid with true") { v { proc {|v| true } } }
23
+ asserts("invalid with false") { !v { proc {|v| false } } }
24
+ end
25
+
26
+ context "matchers" do
27
+ asserts("equals") { Valuedate.matchers[:equals].call(1, 1) }
28
+ asserts("!equals") { !Valuedate.matchers[:equals].call(1, 2) }
29
+ asserts("is_a") { Valuedate.matchers[:is_a].call("string", String) }
30
+ asserts("!is_a") { !Valuedate.matchers[:is_a].call("string", Fixnum) }
31
+ end
32
+
33
+ context "equals" do
34
+ asserts("valid 1") { v(1) { value.equals 1 } }
35
+ asserts("invalid 2") { !v(2) { value.equals 1 } }
36
+ asserts("valid String") { v("test") { value.equals "test" } }
37
+ asserts("invalid String") { !v("test") { value.equals "tests" } }
38
+ asserts("invalid multiple") { !v(1) { value.equals 1; value.equals 2} }
39
+ end
40
+
41
+ context "is_a" do
42
+ asserts("valid String") { v("test") { value.is_a(String) } }
43
+ asserts("invalid String") { !v(1) { value.is_a(String) } }
44
+ asserts("valid multiple") { v("test") { value.is_a(String); value.is_a(Object) } }
45
+ asserts("invalid multiple") { !v("test") { value.is_a(String); value.is_a(Fixnum) } }
46
+ end
47
+
48
+ context "chaining" do
49
+ asserts("valid") { v(1) { value.is_a(Fixnum).equals(1) }}
50
+ asserts("invalid") { !v(1) { value.is_a(Fixnum).equals(2) }}
51
+ end
52
+
53
+ context "nesting" do
54
+ setup do
55
+ Valuedate.schema do
56
+ value.hash(
57
+ :key => value.is_a(String),
58
+ :value => value.is_a(Fixnum)
59
+ )
60
+ end
61
+ end
62
+
63
+ asserts("valid") { topic.validate(:key => "fasel", :value => 23) }
64
+ asserts("invalid") { !topic.validate(:key => 23, :value => 23) }
65
+ asserts("missing") { !topic.validate(:key => "fasel") }
66
+ end
67
+
68
+ context "deep nesting" do
69
+ setup do
70
+ Valuedate.schema do
71
+ value.hash(
72
+ :image => value.hash(
73
+ :src => value.is_a(String),
74
+ :height => value.is_a(Fixnum)
75
+ ),
76
+ :text => value.is_a(String)
77
+ )
78
+ end
79
+ end
80
+
81
+ asserts("valid") do
82
+ topic.validate(
83
+ :image => {
84
+ :src => "/image.gif",
85
+ :height => 80
86
+ },
87
+ :text => "Image"
88
+ )
89
+ end
90
+ asserts("invalid") do
91
+ !topic.validate(
92
+ :image => {
93
+ :src => "/image.gif",
94
+ },
95
+ :text => "Image"
96
+ )
97
+ end
98
+
99
+ end # deep nesting
100
+
101
+ context "optional_value" do
102
+ asserts("valid nil") { v(nil) { optional_value } }
103
+ asserts("valid 1") { v(1) { optional_value } }
104
+ asserts("valid empty optional String") { v(nil) { optional_value.is_a(String) } }
105
+ asserts("valid given and String") { v("test") { optional_value.is_a(String) } }
106
+ asserts("invalid given non-String") { !v(1) { optional_value.is_a(String) } }
107
+
108
+ context "netsted" do
109
+ setup do
110
+ Valuedate.schema do
111
+ optional_value.hash(
112
+ :image => value.hash(
113
+ :src => value.is_a(String),
114
+ :alt => optional_value.is_a(String),
115
+ :size => optional_value.hash(
116
+ :width => value.is_a(Fixnum),
117
+ :height => value.is_a(Fixnum)
118
+ )
119
+ )
120
+ )
121
+ end
122
+ end
123
+
124
+ asserts("valid empty") { topic.validate }
125
+ asserts("invalid non Hash") { !topic.validate(23) }
126
+ asserts("invalid wrong key") { !topic.validate(:type => {}) }
127
+ asserts("invalid empty image") { !topic.validate(:image => {}) }
128
+ asserts("valid all given") do
129
+ topic.validate(
130
+ :image => {
131
+ :src => "/img.gif",
132
+ :alt => "Alt",
133
+ :size => { :width => 80, :height => 80 }
134
+ }
135
+ )
136
+ end
137
+ asserts("valid minimal Hash") { topic.validate(:image => { :src => "/img.gif" }) }
138
+ asserts("invalid alt") { !topic.validate(:image => { :src => "/img.gif", :alt => 23 }) }
139
+ end
140
+ end
141
+
142
+ context "any" do
143
+ asserts("valid") { v(1) { value.any(value.equals(1), value.equals(2)) } }
144
+ asserts("valid") { v(2) { value.any(value.equals(1), value.equals(2)) } }
145
+ asserts("invalid") { !v(3) { value.any(value.equals(1), value.equals(2)) } }
146
+
147
+ context "nested" do
148
+ setup do
149
+ Valuedate.schema do
150
+ value.any(
151
+ value.hash(:result => value.equals("ok")),
152
+ value.hash(:error => value.equals("failed"), :init => value.equals(23))
153
+ )
154
+ end
155
+ end
156
+
157
+ asserts("invalid when empty") { !topic.validate }
158
+ asserts("valid when result ok") { topic.validate(:result => "ok") }
159
+ asserts("invalid when result nok") { !topic.validate(:result => "nok") }
160
+ asserts("valid when error") { topic.validate(:error => "failed", :init => 23) }
161
+ asserts("invalid missing init") { !topic.validate(:error => "failed") }
162
+ end
163
+ end
164
+
165
+ context "in" do
166
+ asserts("valid range") { v(1) { value.in(1..5) } }
167
+ asserts("invalid range") { !v(0) { value.in(1..5) } }
168
+ asserts("valid array") { v(1) { value.in([1,2,3]) } }
169
+ asserts("invalid array") { !v(0) { value.in([1,2,3]) } }
170
+ end
171
+
172
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: valuedate
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Peter Suschlik
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-28 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: riot
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.10.11
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: riot_notifier
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ description:
36
+ email: peter-valuedate@suschlik.de
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README.rdoc
43
+ files:
44
+ - .gitignore
45
+ - README.rdoc
46
+ - Rakefile
47
+ - VERSION
48
+ - lib/valuedate.rb
49
+ - test.watchr
50
+ - test/helper.rb
51
+ - test/test_valuedate.rb
52
+ has_rdoc: true
53
+ homepage: http://github.com/splattael/valuedate
54
+ licenses: []
55
+
56
+ post_install_message:
57
+ rdoc_options:
58
+ - --charset=UTF-8
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ requirements: []
74
+
75
+ rubyforge_project:
76
+ rubygems_version: 1.3.5
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: Validates values.
80
+ test_files:
81
+ - test/test_valuedate.rb