oval 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.scripts/{build-module.sh → build-puppet-module.sh} +2 -2
- data/.travis.yml +0 -10
- data/CHANGELOG +11 -1
- data/Modulefile +4 -4
- data/README.md +68 -20
- data/lib/oval/array_item.rb +1 -1
- data/lib/oval/base.rb +1 -1
- data/lib/oval/class_decl_base.rb +2 -1
- data/lib/oval/collection.rb +1 -15
- data/lib/oval/options.rb +1 -1
- data/oval.gemspec +1 -1
- data/spec/unit/oval/base_spec.rb +0 -2
- data/spec/unit/oval/class_decl_base_spec.rb +0 -2
- data/spec/unit/oval/collection_spec.rb +0 -10
- data/spec/unit/oval/options_spec.rb +7 -7
- metadata +4 -4
@@ -10,8 +10,8 @@ TARGET=`mktemp -d`
|
|
10
10
|
|
11
11
|
function do_build_module {
|
12
12
|
tag=$1
|
13
|
-
tgz="$TARGET/ptomulik-
|
14
|
-
dir="ptomulik-
|
13
|
+
tgz="$TARGET/ptomulik-oval-${tag}.tar.gz"
|
14
|
+
dir="ptomulik-oval-$tag/"
|
15
15
|
git archive --prefix $dir --output $tgz $tag
|
16
16
|
(cd $TARGET && tar -xzf $tgz && cd $TARGET/$dir && puppet module build)
|
17
17
|
}
|
data/.travis.yml
CHANGED
@@ -8,15 +8,5 @@ script: "bundle exec rake spec SPEC_OPTS='--format documentation'"
|
|
8
8
|
branches:
|
9
9
|
only:
|
10
10
|
master
|
11
|
-
env:
|
12
|
-
matrix:
|
13
|
-
- FACTER_GEM_VERSION="~> 1.3.0"
|
14
|
-
- FACTER_GEM_VERSION="~> 1.5.0"
|
15
|
-
- FACTER_GEM_VERSION="~> 1.6.0"
|
16
|
-
- FACTER_GEM_VERSION="~> 1.7.0"
|
17
|
-
#matrix:
|
18
|
-
# exclude:
|
19
|
-
# - rvm: 2.0.0
|
20
|
-
# env: FACTER_GEM_VERSION="~> 2.7.0"
|
21
11
|
notifications:
|
22
12
|
email: false
|
data/CHANGELOG
CHANGED
@@ -1,2 +1,12 @@
|
|
1
|
-
2014-
|
1
|
+
2014-02-02 Pawel Tomulik <ptomulik@meil.pw.edu.pl>
|
2
|
+
* release 0.0.2
|
3
|
+
* fixed Modulefile
|
4
|
+
* release 0.0.1
|
5
|
+
* added note to README.md
|
6
|
+
* corrected typos in README.md
|
7
|
+
* fixed .travis.yml to reduce matrix size
|
8
|
+
* fixed coveralls badge
|
9
|
+
* fixed some specs for ruby 2.0
|
10
|
+
* removed dead code from lib/oval/collection.rb
|
11
|
+
* fixed build-puppet-module script
|
2
12
|
* initial commit
|
data/Modulefile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
name 'ptomulik-
|
2
|
-
version '0.0.
|
3
|
-
source 'git://github.com/ptomulik/
|
1
|
+
name 'ptomulik-oval'
|
2
|
+
version '0.0.2'
|
3
|
+
source 'git://github.com/ptomulik/rubygems-oval.git'
|
4
4
|
author 'ptomulik'
|
5
5
|
license 'Apache License, Version 2.0'
|
6
6
|
summary 'Simple utility to validate Hashes of options.'
|
7
7
|
description 'Simple utility to validate Hashes of options.'
|
8
|
-
project_page 'https://gitbub.com/ptomulik/
|
8
|
+
project_page 'https://gitbub.com/ptomulik/rubygems-oval'
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#Oval - Options Validator
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/ptomulik/rubygems-oval.png?branch=master)](https://travis-ci.org/ptomulik/rubygems-oval)
|
4
|
-
[![Coverage Status](https://coveralls.io/
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/ptomulik/rubygems-oval/badge.png?branch=master)](https://coveralls.io/r/ptomulik/rubygems-oval?branch=master)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/ptomulik/rubygems-oval.png)](https://codeclimate.com/github/ptomulik/rubygems-oval)
|
6
6
|
|
7
7
|
####<a id="table-of-contents"></a>Table of Contents
|
@@ -24,24 +24,42 @@ Validate option hashes when passed to methods.
|
|
24
24
|
|
25
25
|
##<a id="module-description"></a>Module Description
|
26
26
|
|
27
|
-
Using hashes to pass options to methods is a very common ruby practice. With
|
27
|
+
Using hashes to pass options to methods is a very common ruby practice. With
|
28
|
+
**Oval** method authors may restrict callers to pass only declared options that
|
29
|
+
meet requirements described in a hash declaration.
|
28
30
|
|
29
|
-
The shape of acceptable hashes is described by a simple grammar. The validation
|
31
|
+
The shape of acceptable hashes is described by a simple grammar. The validation
|
32
|
+
is then carried out by a recursive-descent parser that matches the actual
|
33
|
+
values provided by caller against [declarators](#declarators) that comprise the
|
34
|
+
hash declaration.
|
30
35
|
|
31
|
-
A declaration consists of terminal and non-terminal declarators. Non-terminal
|
36
|
+
A declaration consists of terminal and non-terminal declarators. Non-terminal
|
37
|
+
declarators are created by methods of `Oval` module which have names starting
|
38
|
+
with `ov_` prefix. All other values (such as `:symbol`, `'string'`, `nil`, or
|
39
|
+
`Class`) are terminals. Terminals use `==` operator to match the values
|
40
|
+
provided by caller. Non-terminal use its own logic introducing more elaborate
|
41
|
+
matching criteria (see for example [ov_collection](#ov_collection)).
|
32
42
|
|
33
|
-
**Oval** raises **Oval::DeclError** if the declaration is not well-formed, that
|
43
|
+
**Oval** raises **Oval::DeclError** if the declaration is not well-formed, that
|
44
|
+
is if the description of options shape is erroneous. This is raised from the
|
45
|
+
point of declaration. Other, more common exception is the **Oval::ValueError**
|
46
|
+
which is raised each time the validation fails. This one is raised from within
|
47
|
+
a method which takes the options as an argument.
|
34
48
|
|
35
49
|
[[Table of Contents](#table-of-contents)]
|
36
50
|
|
37
51
|
##<a id="usage"></a>Usage
|
38
52
|
|
39
|
-
The usage is basically a two-step procedure. The first step is to declare
|
53
|
+
The usage is basically a two-step procedure. The first step is to declare
|
54
|
+
options shape. This would create a validator object. The second step is to
|
55
|
+
validate options within a method using the previously constructed validator.
|
56
|
+
For simple hashes the entire construction may fit to a single line. Let's start
|
57
|
+
with such a simple example.
|
40
58
|
|
41
59
|
###<a id="example-1-declaring-simple-options"></a>Example 1: Declaring Simple Options
|
42
60
|
|
43
61
|
The method `foo` in the following code accepts only `{}` and `{:foo => value}`
|
44
|
-
as `
|
62
|
+
as `ops`, where `value` is arbitrary:
|
45
63
|
|
46
64
|
```ruby
|
47
65
|
# Options validator
|
@@ -62,14 +80,26 @@ C.foo :foo => 10 # should pass
|
|
62
80
|
C.foo :foo => 10, :bar => 20 # Oval::ValueError "Invalid option :bar for ops. Allowed options are :foo"
|
63
81
|
```
|
64
82
|
|
65
|
-
Options are declared with [ov_xxx declarators](#declarators). The
|
66
|
-
|
67
|
-
|
68
|
-
|
83
|
+
Options are declared with [ov_xxx declarators](#declarators). The
|
84
|
+
[ov_options](#ov_options) method should always be at the top level. Then all
|
85
|
+
the allowed options should be listed inside of `[]` square brackets. Keys may
|
86
|
+
be any values convertible to strings (i.e. a key given in declaration must
|
87
|
+
`respond_to? :to_s`). Values are declared recursively using [ov_xxx
|
88
|
+
declarators](#declarators) or terminal declarators (any other ruby values).
|
89
|
+
|
90
|
+
In [Example 1](#example-1-declaring-simple-options) we have declared options
|
91
|
+
inside of a method for simplicity. This isn't an optimal technique. Usually
|
92
|
+
options' declaration remains same for the entire lifetime of an application, so
|
93
|
+
it is unnecessary to recreate the declaration each time function is called. In
|
94
|
+
other words, we should move the declaration outside of the method, convert it
|
95
|
+
to a singleton and only validate options inside of a function. For that
|
96
|
+
purpose, the [Example 1](#example-1-declaring-simple-options) could be modified
|
97
|
+
to the following form
|
69
98
|
|
70
99
|
###<a id="example-2-separating-declaration-from-validation"></a>Example 2: Separating declaration from validation
|
71
100
|
|
72
|
-
In this example we separate options declaration from the validation to reduce
|
101
|
+
In this example we separate options declaration from the validation to reduce
|
102
|
+
costs related to options declaration:
|
73
103
|
|
74
104
|
```ruby
|
75
105
|
# Options validator
|
@@ -93,19 +123,30 @@ end
|
|
93
123
|
|
94
124
|
###<a id="declarators"></a>Declarators
|
95
125
|
|
96
|
-
A declaration of options consists entirely of what we call here
|
126
|
+
A declaration of options consists entirely of what we call here
|
127
|
+
**declarators**. The [ov_options](#ov_options) should be used as a root of
|
128
|
+
every declaration (starting symbol in grammar terms). It accepts a Hash of the
|
129
|
+
form **{optname => optdecl, ...}** as an argument. The **optname** is an option
|
130
|
+
name, and **optdecl** is a declarator restricting the option's value. Each
|
131
|
+
option name (key) must be convertible to a `String`. Option value declarators
|
132
|
+
are non-terminal declarators (defined later in this section) or terminals (any
|
133
|
+
other ruby values). The simple declaration
|
97
134
|
|
98
135
|
```ruby
|
99
136
|
ov_options[ :foo => :bar ]
|
100
137
|
```
|
101
138
|
|
102
|
-
uses only terminals inside of **ov_options** and
|
139
|
+
uses only terminals inside of **ov_options** and literary permits only the
|
140
|
+
`{:foo => :bar}` or the empty hash `{}` as options (and nothing else). This is
|
141
|
+
how terminal declarators (`:foo` and `:bar` in this example) work. More freedom
|
142
|
+
may be introduced with non-terminal declarators, for example:
|
103
143
|
|
104
144
|
```ruby
|
105
145
|
ov_options[ :foo => ov_anything ]
|
106
146
|
```
|
107
147
|
|
108
|
-
defines an option `:foo` which accepts any value. In what follows, we'll
|
148
|
+
defines an option `:foo` which accepts any value. In what follows, we'll
|
149
|
+
document all the core non-terminal declarators implemented in **Oval**.
|
109
150
|
|
110
151
|
####<a id="ov\_anything"></a>ov\_anything
|
111
152
|
|
@@ -140,13 +181,17 @@ defines an option `:foo` which accepts any value. In what follows, we'll documen
|
|
140
181
|
ov_collection[ class_decl, item_decl ]
|
141
182
|
```
|
142
183
|
|
143
|
-
- Validation - permits only collections of type **class_decl** with items
|
184
|
+
- Validation - permits only collections of type **class_decl** with items
|
185
|
+
matching **item_decl** declaration
|
144
186
|
- Allowed values for **class\_decl** are:
|
145
187
|
- `Hash` or `Array` or any subclass of `Hash` or `Array`,
|
146
|
-
- `ov_subclass_of[klass]` where **klass** is `Hash` or `Array` or a subclass
|
188
|
+
- `ov_subclass_of[klass]` where **klass** is `Hash` or `Array` or a subclass
|
189
|
+
of any of them.
|
147
190
|
- Allowed values for **item_decl**:
|
148
|
-
- if **class\_decl** is `Array`-like, then any value is allowed as
|
149
|
-
|
191
|
+
- if **class\_decl** is `Array`-like, then any value is allowed as
|
192
|
+
**item\_decl**,
|
193
|
+
- if **class\_decl** is `Hash`-like, then **item\_decl** should be a
|
194
|
+
one-element Hash in form **{ key\_decl => val\_decl }**.
|
150
195
|
- Example
|
151
196
|
|
152
197
|
```ruby
|
@@ -226,7 +271,8 @@ defines an option `:foo` which accepts any value. In what follows, we'll documen
|
|
226
271
|
```
|
227
272
|
|
228
273
|
- Validation - permits only declared options and their values.
|
229
|
-
- Allowed values for `optkey_declN` - anything that is convertible to string
|
274
|
+
- Allowed values for `optkey_declN` - anything that is convertible to string
|
275
|
+
(namely, anything that responds to `to_s` method).
|
230
276
|
- Example:
|
231
277
|
|
232
278
|
```ruby
|
@@ -277,4 +323,6 @@ The API documentation is also available
|
|
277
323
|
|
278
324
|
##Limitations
|
279
325
|
|
326
|
+
- API documentation is currently very poor,
|
327
|
+
|
280
328
|
[[Table of Contents](#table-of-contents)]
|
data/lib/oval/array_item.rb
CHANGED
data/lib/oval/base.rb
CHANGED
data/lib/oval/class_decl_base.rb
CHANGED
data/lib/oval/collection.rb
CHANGED
@@ -70,10 +70,9 @@ class Oval::Collection < Oval::Base
|
|
70
70
|
|
71
71
|
attr_reader :class_decl
|
72
72
|
attr_reader :item_decl
|
73
|
-
attr_reader :class_validator
|
74
73
|
attr_reader :item_validator
|
75
74
|
|
76
|
-
|
75
|
+
private
|
77
76
|
|
78
77
|
def class_decl=(decl)
|
79
78
|
self.class.validate_class_decl(decl)
|
@@ -89,19 +88,6 @@ class Oval::Collection < Oval::Base
|
|
89
88
|
@item_validator = select_item_validator[item_decl]
|
90
89
|
end
|
91
90
|
|
92
|
-
def select_class_validator
|
93
|
-
if klass.is_a?(Class) and klass <= Hash
|
94
|
-
Oval::HashClass
|
95
|
-
elsif klass.is_a?(Class) and klass <= Array
|
96
|
-
Oval::ArrayClass
|
97
|
-
else
|
98
|
-
# well, we also may have klass that is not a class, but I'm too lazy to
|
99
|
-
# handle all possible exceptions,
|
100
|
-
raise RuntimeError, "Invalid class #{klass.inspect} assigned to klass. " +
|
101
|
-
"It seems like we have a bug in #{self.class.name}"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
91
|
def select_item_validator
|
106
92
|
if klass.is_a?(Class) and klass <= Hash
|
107
93
|
Oval::HashItem
|
data/lib/oval/options.rb
CHANGED
data/oval.gemspec
CHANGED
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.name = 'oval'
|
6
|
-
gem.version = '0.0.
|
6
|
+
gem.version = '0.0.2'
|
7
7
|
gem.authors = ["Pawel Tomulik"]
|
8
8
|
gem.email = ["ptomulik@meil.pw.edu.pl"]
|
9
9
|
gem.description = %q{Validate options when passed to methods}
|
data/spec/unit/oval/base_spec.rb
CHANGED
@@ -5,13 +5,6 @@ require 'oval/instance_of'
|
|
5
5
|
require 'oval/kind_of'
|
6
6
|
|
7
7
|
describe Oval::Collection do
|
8
|
-
## Anything = Oval::Anything
|
9
|
-
## SubclassOf = Oval::SubclassOf
|
10
|
-
## InstanceOf = Oval::InstanceOf
|
11
|
-
## KindOf = Oval::KindOf
|
12
|
-
## OneOf = Oval::OneOf
|
13
|
-
## DeclError = Oval::DeclError
|
14
|
-
## ValueError = Oval::ValueError
|
15
8
|
describe 'the class' do
|
16
9
|
it { described_class.should respond_to :[] }
|
17
10
|
it { described_class.should respond_to :new }
|
@@ -21,10 +14,7 @@ describe Oval::Collection do
|
|
21
14
|
let(:subject) { described_class[Array,nil] }
|
22
15
|
it { should respond_to :validate }
|
23
16
|
it { should respond_to :class_decl }
|
24
|
-
it { should respond_to :class_decl= }
|
25
17
|
it { should respond_to :item_decl }
|
26
|
-
it { should respond_to :item_decl= }
|
27
|
-
it { should respond_to :select_item_validator }
|
28
18
|
end
|
29
19
|
|
30
20
|
describe "[]" do
|
@@ -16,9 +16,9 @@ describe Oval::Options do
|
|
16
16
|
before { described_class.stubs(:validate_decl).once.with(:decl0) }
|
17
17
|
[
|
18
18
|
:validate,
|
19
|
-
:validate_option,
|
20
|
-
:validate_option_name,
|
21
|
-
:validate_option_value,
|
19
|
+
# :validate_option,
|
20
|
+
# :validate_option_name,
|
21
|
+
# :validate_option_value,
|
22
22
|
].each do |method|
|
23
23
|
it { should respond_to method }
|
24
24
|
end
|
@@ -151,11 +151,11 @@ describe Oval::Options do
|
|
151
151
|
|
152
152
|
describe "#validate_decl" do
|
153
153
|
context "validate_decl({:foo => :F, :bar => 4})" do
|
154
|
-
it { expect { described_class.validate_decl
|
154
|
+
it { expect { described_class.send(:validate_decl,{:foo => :F, :bar => 4}) }.to_not raise_error }
|
155
155
|
end
|
156
156
|
context "validate_decl(:decl1)" do
|
157
157
|
let(:msg) { "Invalid declaration :decl1 of type Symbol. Should be a Hash" }
|
158
|
-
it { expect { described_class.
|
158
|
+
it { expect { described_class.send(:validate_decl,:decl1) }.to raise_error Oval::DeclError, msg }
|
159
159
|
end
|
160
160
|
[
|
161
161
|
{},
|
@@ -167,7 +167,7 @@ describe Oval::Options do
|
|
167
167
|
let(:decl) { decl }
|
168
168
|
before { decl.keys.each {|key| described_class.expects(:validate_option_name_decl).once.with(key) } }
|
169
169
|
it "calls validate_option_name_decl(key) once for each key from #{decl.inspect} " do
|
170
|
-
expect { described_class.validate_decl
|
170
|
+
expect { described_class.send(:validate_decl,decl) }.to_not raise_error
|
171
171
|
end
|
172
172
|
end
|
173
173
|
end
|
@@ -177,7 +177,7 @@ describe Oval::Options do
|
|
177
177
|
[ :one, 'two', 3 ].each do |decl|
|
178
178
|
context "validate_option_name_decl(#{decl.inspect})" do
|
179
179
|
let(:decl) { decl }
|
180
|
-
it { expect { described_class.validate_option_name_decl
|
180
|
+
it { expect { described_class.send(:validate_option_name_decl,decl) }.to_not raise_error }
|
181
181
|
end
|
182
182
|
end
|
183
183
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oval
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -37,7 +37,7 @@ files:
|
|
37
37
|
- .fixtures.yml
|
38
38
|
- .gitignore
|
39
39
|
- .rspec
|
40
|
-
- .scripts/build-module.sh
|
40
|
+
- .scripts/build-puppet-module.sh
|
41
41
|
- .travis.yml
|
42
42
|
- .yardopts
|
43
43
|
- CHANGELOG
|
@@ -88,7 +88,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
88
88
|
version: '0'
|
89
89
|
segments:
|
90
90
|
- 0
|
91
|
-
hash:
|
91
|
+
hash: 2044800399727504758
|
92
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
93
|
none: false
|
94
94
|
requirements:
|
@@ -97,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
97
|
version: '0'
|
98
98
|
segments:
|
99
99
|
- 0
|
100
|
-
hash:
|
100
|
+
hash: 2044800399727504758
|
101
101
|
requirements: []
|
102
102
|
rubyforge_project:
|
103
103
|
rubygems_version: 1.8.23
|