jsexp 1.0.0 → 1.0.1

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.
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