valuedate 0.0.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/.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