jsexp 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.md +14 -1
  2. data/lib/jsexp.rb +42 -28
  3. data/test/jsexp_test.rb +22 -12
  4. metadata +2 -2
data/README.md CHANGED
@@ -13,7 +13,7 @@ Example
13
13
  schema = {
14
14
  'name' => String, # case expression
15
15
  'email' => /@/, # case expression
16
- 'p' => (0.0..1.0), # case expression
16
+ 'p' => (0.0..1.0), # definite range
17
17
  'id' => [:range, [0, :inf]], # indefinite range
18
18
  'color' => [:enum, ['red', 'green', 'blue']], # enum
19
19
  'offset' => [:tuple, [Float, Float]], # exact-size array
@@ -46,3 +46,16 @@ Non-features
46
46
  - nested schemas: This is a source of arbitrary complexity.
47
47
  - specific error messages: Refer to the schema to see what's wrong.
48
48
  - lambdas: Do more complex validation yourself.
49
+
50
+ Float Promotion
51
+ ---------------
52
+
53
+ Javascript does not distinguish between integer and float. To accomodate, we accept integers or floats for type Float.
54
+
55
+ Numeric Ranges
56
+ --------------
57
+
58
+ - (0..10): integers 0, 1, ..., 10 # to_a
59
+ - (0.0..10.0): floats [0.0, 10.0]
60
+ - [:range, [0, :inf]]: integers 0, 1, ...
61
+ - [:range, [0.0, :inf]]: floats [0.0, inf)
@@ -1,35 +1,49 @@
1
1
  module JSExp
2
-
3
- def JSExp.valid?(schema, obj)
4
- if schema.is_a?(Hash)
5
- obj.is_a?(Hash) && schema.map {|key, schema_|
6
- if schema_.is_a?(Array) && schema_[0] == :optional
7
- !obj.key?(key) || valid?(schema_[1], obj[key])
2
+ def JSExp.valid?(schema, obj)
3
+ if schema.is_a?(Hash)
4
+ obj.is_a?(Hash) && schema.map {|key, schema_|
5
+ if schema_.is_a?(Array) && schema_[0] == :optional
6
+ !obj.key?(key) || valid?(schema_[1], obj[key])
7
+ else
8
+ obj.key?(key) && valid?(schema_, obj[key])
9
+ end
10
+ }.all?
11
+ elsif schema.is_a?(Array)
12
+ case schema[0]
13
+ when :array
14
+ obj.is_a?(Array) && obj.map {|x| valid?(schema[1], x)}.all?
15
+ when :enum
16
+ schema[1].include?(obj)
17
+ when :range
18
+ min, max = schema[1]
19
+ bound = (min == :inf ? max : min)
20
+ same_domain?(bound, obj) &&
21
+ (min == :inf ? true : obj >= min) &&
22
+ (max == :inf ? true : obj <= max)
23
+ when :tuple
24
+ obj.is_a?(Array) && obj.size == schema[1].size && schema[1].each_index.map {|i| valid?(schema[1][i], obj[i])}.all?
25
+ end
26
+ elsif schema.is_a?(Range)
27
+ same_domain?(schema.min, obj) && schema.include?(obj)
28
+ elsif schema == Float
29
+ obj.is_a?(Integer) || obj.is_a?(Float)
30
+ else
31
+ case obj
32
+ when schema
33
+ true
8
34
  else
9
- obj.key?(key) && valid?(schema_, obj[key])
35
+ false
10
36
  end
11
- }.all?
12
- elsif schema.is_a?(Array)
13
- case schema[0]
14
- when :array
15
- obj.is_a?(Array) && obj.map {|x| valid?(schema[1], x)}.all?
16
- when :enum
17
- schema[1].include?(obj)
18
- when :range
19
- min, max = schema[1]
20
- (min == :inf ? true : obj.class == min.class && obj >= min) &&
21
- (max == :inf ? true : obj.class == max.class && obj <= max)
22
- when :tuple
23
- obj.is_a?(Array) && obj.size == schema[1].size && schema[1].each_index.map {|i| valid?(schema[1][i], obj[i])}.all?
24
37
  end
25
- else
26
- case obj
27
- when schema
28
- true
29
- else
30
- false
38
+ end
39
+ private
40
+ def JSExp.same_domain?(schema, obj)
41
+ # y.is_a?(x.class) fails when y.class == Bignum and x.class == Fixnum
42
+ case schema
43
+ when Integer
44
+ JSExp.valid?(Integer, obj)
45
+ when Float
46
+ JSExp.valid?(Float, obj)
31
47
  end
32
48
  end
33
49
  end
34
-
35
- end
@@ -8,25 +8,20 @@ describe JSExp do
8
8
  JSExp.valid?(String, 0).must_equal false
9
9
 
10
10
  JSExp.valid?(Integer, 0).must_equal true
11
- JSExp.valid?(Integer, 0.0).must_equal false
11
+ JSExp.valid?(Integer, '').must_equal false
12
12
 
13
13
  JSExp.valid?(Float, 0.0).must_equal true
14
- JSExp.valid?(Float, 0).must_equal false
14
+ JSExp.valid?(Float, '').must_equal false
15
15
 
16
16
  JSExp.valid?(/@/, 'user@example.com').must_equal true
17
17
  JSExp.valid?(/@/, '').must_equal false
18
-
19
- JSExp.valid?((0..10), 5).must_equal true
20
- JSExp.valid?((0..10), 11).must_equal false
21
-
22
- JSExp.valid?((0.0..1.0), 0.5).must_equal true
23
- JSExp.valid?((0.0..1.0), 1.1).must_equal false
24
18
  end
25
19
 
26
20
  it 'validates indefinite arrays' do
27
21
  JSExp.valid?([:array, Integer], []).must_equal true
28
22
  JSExp.valid?([:array, Integer], [0]).must_equal true
29
23
  JSExp.valid?([:array, Integer], [0, 0]).must_equal true
24
+
30
25
  JSExp.valid?([:array, Integer], [0.0]).must_equal false
31
26
  JSExp.valid?([:array, Integer], [0, 0.0]).must_equal false
32
27
  end
@@ -44,15 +39,19 @@ describe JSExp do
44
39
  JSExp.valid?(schema, {'id' => 0}).must_equal false
45
40
  end
46
41
 
42
+ it 'validates definite ranges' do
43
+ JSExp.valid?((0..10), 5).must_equal true
44
+ JSExp.valid?((0..10), 11).must_equal false
45
+
46
+ JSExp.valid?((0.0..1.0), 0.5).must_equal true
47
+ JSExp.valid?((0.0..1.0), 1.1).must_equal false
48
+ end
49
+
47
50
  it 'validates indefinite ranges' do
48
51
  JSExp.valid?([:range, [0, :inf]], 0).must_equal true
49
52
  JSExp.valid?([:range, [0, :inf]], -1).must_equal false
50
- JSExp.valid?([:range, [0, :inf]], 0.0).must_equal false
51
53
 
52
54
  JSExp.valid?([:range, [:inf, 0]], 0).must_equal true
53
- JSExp.valid?([:range, [:inf, 0]], 1).must_equal false
54
-
55
- JSExp.valid?([:range, [:inf, :inf]], 0).must_equal true
56
55
  end
57
56
 
58
57
  it 'validates tuples' do
@@ -61,4 +60,15 @@ describe JSExp do
61
60
  JSExp.valid?([:tuple, [Integer, Float]], [0]).must_equal false
62
61
  JSExp.valid?([:tuple, [Integer, Float]], [0, 0.0, 0]).must_equal false
63
62
  end
63
+
64
+ it 'handles float promotion' do
65
+ JSExp.valid?(Float, 0).must_equal true
66
+ JSExp.valid?(Integer, 0.0).must_equal false
67
+
68
+ JSExp.valid?((0.0..10.0), 5).must_equal true
69
+ JSExp.valid?((0..10), 5.0).must_equal false
70
+
71
+ JSExp.valid?([:range, [0.0, :inf]], 5).must_equal true
72
+ JSExp.valid?([:range, [0, :inf]], 5.0).must_equal false
73
+ end
64
74
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsexp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -41,7 +41,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
41
41
  version: '0'
42
42
  requirements: []
43
43
  rubyforge_project:
44
- rubygems_version: 1.8.11
44
+ rubygems_version: 1.8.15
45
45
  signing_key:
46
46
  specification_version: 3
47
47
  summary: json schemas