masterplan 0.4.0 → 0.5.0
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/Gemfile +1 -1
- data/Gemfile.lock +9 -5
- data/README.rdoc +8 -5
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/lib/masterplan.rb +50 -17
- data/lib/masterplan/define_rules.rb +4 -1
- data/lib/masterplan/document.rb +1 -1
- data/lib/masterplan/rule.rb +2 -1
- data/masterplan.gemspec +11 -11
- data/spec/masterplan_spec.rb +180 -4
- metadata +26 -30
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
GEM
|
|
2
2
|
remote: http://rubygems.org/
|
|
3
3
|
specs:
|
|
4
|
-
activesupport (2.
|
|
5
|
-
|
|
4
|
+
activesupport (3.2.2)
|
|
5
|
+
i18n (~> 0.6)
|
|
6
|
+
multi_json (~> 1.0)
|
|
7
|
+
diff-lcs (1.1.3)
|
|
6
8
|
git (1.2.5)
|
|
9
|
+
i18n (0.6.0)
|
|
7
10
|
jeweler (1.5.2)
|
|
8
11
|
bundler (~> 1.0.0)
|
|
9
12
|
git (>= 1.2.5)
|
|
10
13
|
rake
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
multi_json (1.1.0)
|
|
15
|
+
rake (0.9.2.2)
|
|
16
|
+
rcov (1.0.0)
|
|
13
17
|
rspec (2.3.0)
|
|
14
18
|
rspec-core (~> 2.3.0)
|
|
15
19
|
rspec-expectations (~> 2.3.0)
|
|
@@ -23,7 +27,7 @@ PLATFORMS
|
|
|
23
27
|
ruby
|
|
24
28
|
|
|
25
29
|
DEPENDENCIES
|
|
26
|
-
activesupport
|
|
30
|
+
activesupport
|
|
27
31
|
bundler (~> 1.0.0)
|
|
28
32
|
jeweler (~> 1.5.2)
|
|
29
33
|
rcov
|
data/README.rdoc
CHANGED
|
@@ -128,6 +128,12 @@ The implicit rules are:
|
|
|
128
128
|
|
|
129
129
|
You can add extra rules with the rule method - see Masterplan::DefineRules#rule for details.
|
|
130
130
|
|
|
131
|
+
You can control the verbosity of the output with the :format option:
|
|
132
|
+
|
|
133
|
+
>> Masterplan.compare(:scheme => doc, :to => {:example => :data}, :format => :mini)
|
|
134
|
+
|
|
135
|
+
Valid values are :full (the default), or :mini. :mini produces only a one-line output (leaving out the "Expected...but was" part).
|
|
136
|
+
|
|
131
137
|
There is also an added assertion for unit tests or specs:
|
|
132
138
|
|
|
133
139
|
assert_masterplan(doc, [{:example => :data})
|
|
@@ -152,15 +158,12 @@ Note that for the moment, schemes, i.e. the outermost object, can only be hashes
|
|
|
152
158
|
|
|
153
159
|
(sudo) gem install masterplan
|
|
154
160
|
|
|
161
|
+
(Note that the latest version is probably not available as a gem directly).
|
|
162
|
+
|
|
155
163
|
Or, install latest version from Github with bundler by adding this to your Gemfile:
|
|
156
164
|
|
|
157
165
|
gem 'masterplan', :git => 'git://github.com/traveliq/masterplan.git'
|
|
158
166
|
|
|
159
|
-
== Dependencies
|
|
160
|
-
|
|
161
|
-
You'll need ActiveSupport, but that should be handled automatically.
|
|
162
|
-
Under Ruby 1.9.x, however, you need the test-unit gem. It works for us with test-unit 1.2.3.
|
|
163
|
-
|
|
164
167
|
== Authors
|
|
165
168
|
|
|
166
169
|
Martin Tepper (monogreen.de), Holger Pillmann (holger.pillmann@gmail.com), Dr. Florian Odronitz (odo@mac.com)
|
data/Rakefile
CHANGED
|
@@ -13,12 +13,12 @@ require 'jeweler'
|
|
|
13
13
|
Jeweler::Tasks.new do |gem|
|
|
14
14
|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
|
15
15
|
gem.name = "masterplan"
|
|
16
|
-
gem.homepage = "http://github.com/
|
|
16
|
+
gem.homepage = "http://github.com/MGPalmer/masterplan"
|
|
17
17
|
gem.license = "MIT"
|
|
18
18
|
summary = %Q{Masterplan is a library for comparing Ruby data structures against predefined templates - like XML Schema without the XML.}
|
|
19
19
|
gem.summary = summary
|
|
20
20
|
gem.description = summary + " Please see the README on github for more information."
|
|
21
|
-
gem.email = "
|
|
21
|
+
gem.email = "mgpalmer@monogreen.de"
|
|
22
22
|
gem.authors = ["Martin Tepper"]
|
|
23
23
|
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
|
24
24
|
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.5.0
|
data/lib/masterplan.rb
CHANGED
|
@@ -3,9 +3,6 @@ require 'active_support/version'
|
|
|
3
3
|
if ActiveSupport::VERSION::STRING >= "3.0.0"
|
|
4
4
|
require 'active_support/core_ext'
|
|
5
5
|
end
|
|
6
|
-
if RUBY_VERSION > '1.9'
|
|
7
|
-
gem 'test-unit'
|
|
8
|
-
end
|
|
9
6
|
require 'test/unit/assertions'
|
|
10
7
|
require 'masterplan'
|
|
11
8
|
require 'masterplan/rule'
|
|
@@ -20,12 +17,14 @@ module Masterplan
|
|
|
20
17
|
|
|
21
18
|
class << self
|
|
22
19
|
|
|
23
|
-
def compare(options = {:scheme => {}, :to => {}})
|
|
20
|
+
def compare(options = {:scheme => {}, :to => {}, :format => :full})
|
|
24
21
|
scheme = options[:scheme]
|
|
25
22
|
testee = options[:to]
|
|
23
|
+
format = options[:format] || :full
|
|
26
24
|
raise ArgumentError, ":to needs to be a hash !" unless testee.is_a?(Hash)
|
|
27
25
|
raise ArgumentError, ":scheme needs to be a Masterplan::Document !" unless scheme.is_a?(Document)
|
|
28
|
-
|
|
26
|
+
raise ArgumentError, ":format needs to be one of [:full, :mini] !" unless [:full, :mini].include?(format)
|
|
27
|
+
compare_hash(scheme, testee, format)
|
|
29
28
|
true
|
|
30
29
|
end
|
|
31
30
|
|
|
@@ -39,14 +38,44 @@ module Masterplan
|
|
|
39
38
|
end
|
|
40
39
|
end
|
|
41
40
|
|
|
42
|
-
def
|
|
43
|
-
|
|
41
|
+
def compare_hash_keys(template, testee, trail)
|
|
42
|
+
mandatory_keys = Set.new
|
|
43
|
+
optional_keys = Set.new
|
|
44
|
+
template.keys.each do |key|
|
|
45
|
+
if key.is_a?(Masterplan::Rule) && key.options["optional"]
|
|
46
|
+
optional_keys << key.example_value.to_s
|
|
47
|
+
else
|
|
48
|
+
mandatory_keys << key.to_s
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
failed = false
|
|
44
52
|
testee.stringify_keys!
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
testee_set = Set.new(testee.keys)
|
|
54
|
+
if((mandatory_keys - testee_set).size > 0) # missing keys
|
|
55
|
+
failed = true
|
|
56
|
+
else
|
|
57
|
+
extra_keys = (testee_set - mandatory_keys)
|
|
58
|
+
if extra_keys.size > 0 && !extra_keys.subset?(optional_keys)
|
|
59
|
+
failed = true
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
if failed
|
|
63
|
+
raise FailedError, "keys don't match in #{format_path(trail)}:\nexpected:\t#{mandatory_keys.sort.join(',')}\nreceived:\t#{testee.keys.sort.join(',')}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def compare_hash(template, testee, format, trail = ["root"])
|
|
68
|
+
compare_hash_keys(template, testee, trail)
|
|
69
|
+
template.each do |t_key_or_rule, t_value|
|
|
70
|
+
key_is_optional = t_key_or_rule.is_a?(Masterplan::Rule) && t_key_or_rule.options["optional"]
|
|
71
|
+
t_key = if key_is_optional
|
|
72
|
+
t_key_or_rule.example_value.to_s
|
|
73
|
+
else
|
|
74
|
+
t_key_or_rule.to_s
|
|
75
|
+
end
|
|
47
76
|
current_path = trail + [t_key]
|
|
48
77
|
value = testee[t_key]
|
|
49
|
-
compare_value(t_value, value, format_path(current_path))
|
|
78
|
+
compare_value(t_value, value, format_path(current_path)) unless key_is_optional and value.nil?
|
|
50
79
|
if value && t_value.is_a?(Array)
|
|
51
80
|
# all array elements need to be of the same type as the first value in the template
|
|
52
81
|
elements_template = t_value.first
|
|
@@ -54,7 +83,7 @@ module Masterplan
|
|
|
54
83
|
array_path = current_path + [index]
|
|
55
84
|
compare_value(elements_template, elements_value, format_path(array_path))
|
|
56
85
|
if elements_value.is_a?(Hash)
|
|
57
|
-
compare_hash(elements_template, elements_value, array_path)
|
|
86
|
+
compare_hash(elements_template, elements_value, format, array_path)
|
|
58
87
|
end
|
|
59
88
|
end
|
|
60
89
|
end
|
|
@@ -64,16 +93,16 @@ module Masterplan
|
|
|
64
93
|
array_path = current_path + [index]
|
|
65
94
|
compare_value(elements_template, elements_value, format_path(array_path))
|
|
66
95
|
if elements_value.is_a?(Hash)
|
|
67
|
-
compare_hash(elements_template, elements_value, array_path)
|
|
96
|
+
compare_hash(elements_template, elements_value, format, array_path)
|
|
68
97
|
end
|
|
69
98
|
end
|
|
70
99
|
end
|
|
71
100
|
if value.is_a?(Hash)
|
|
72
101
|
if t_value.is_a?(Masterplan::Rule)
|
|
73
102
|
compare_value(t_value, value, current_path)
|
|
74
|
-
compare_hash(t_value.example_value, value, current_path)
|
|
103
|
+
compare_hash(t_value.example_value, value, format, current_path)
|
|
75
104
|
else
|
|
76
|
-
compare_hash(t_value, value, current_path)
|
|
105
|
+
compare_hash(t_value, value, format, current_path)
|
|
77
106
|
end
|
|
78
107
|
end
|
|
79
108
|
end
|
|
@@ -84,10 +113,14 @@ module Masterplan
|
|
|
84
113
|
error = Masterplan::FailedError.new
|
|
85
114
|
error.printed = true
|
|
86
115
|
|
|
87
|
-
|
|
88
|
-
|
|
116
|
+
if format == :mini
|
|
117
|
+
raise error, e.message, caller
|
|
118
|
+
else
|
|
119
|
+
expected = PP.pp(template, '')
|
|
120
|
+
outcome = PP.pp(testee, '')
|
|
89
121
|
|
|
90
|
-
|
|
122
|
+
raise error, "#{e.message}\n\nExpected:\n#{expected}\n\nbut was:\n#{outcome}", caller
|
|
123
|
+
end
|
|
91
124
|
end
|
|
92
125
|
|
|
93
126
|
def format_path(trail)
|
|
@@ -5,11 +5,14 @@ module Masterplan
|
|
|
5
5
|
module DefineRules
|
|
6
6
|
|
|
7
7
|
# This turns the supplied +example_value+ (any object) into an object that carries rules about itself with it.
|
|
8
|
-
# The rules will be applied when a template is compared with assert_masterplan. Rules are:
|
|
8
|
+
# The rules will be applied when a template is compared with assert_masterplan or Masterplan.compare. Rules are:
|
|
9
9
|
# (default): This always applies - the value must be of the same class as the +example_value+
|
|
10
10
|
# 'allow_nil': This allows the value to be nil (breaking the first rule)
|
|
11
11
|
# 'included_in': Pass an array of values - the value must be one of these
|
|
12
12
|
# 'matches': Pass a regexp - the value must match it, and be a String
|
|
13
|
+
#
|
|
14
|
+
# There is one special rule that only works on hash keys:
|
|
15
|
+
# 'optional' : This makes the hash key optional, i.e. no error will occur if the key (and its value) are missing.
|
|
13
16
|
def rule(example_value, options = {})
|
|
14
17
|
Rule.new(example_value, options)
|
|
15
18
|
end
|
data/lib/masterplan/document.rb
CHANGED
data/lib/masterplan/rule.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Masterplan
|
|
2
2
|
class Rule
|
|
3
3
|
|
|
4
|
-
OPTIONS = ["allow_nil", "compare_each", "included_in", "matches"]
|
|
4
|
+
OPTIONS = ["allow_nil", "compare_each", "included_in", "matches", "optional"]
|
|
5
5
|
|
|
6
6
|
attr_accessor :options, :example_value
|
|
7
7
|
|
|
@@ -11,6 +11,7 @@ module Masterplan
|
|
|
11
11
|
options['compare_each'] ||= false
|
|
12
12
|
options["included_in"] ||= false
|
|
13
13
|
options["matches"] ||= false
|
|
14
|
+
options["optional"] ||= false
|
|
14
15
|
raise ArgumentError, "options can be #{OPTIONS.join(',')}, not #{options.keys.inspect}" unless options.keys.sort == OPTIONS.sort
|
|
15
16
|
self.example_value = example
|
|
16
17
|
self.options = options
|
data/masterplan.gemspec
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
|
-
s.name =
|
|
8
|
-
s.version = "0.
|
|
7
|
+
s.name = "masterplan"
|
|
8
|
+
s.version = "0.5.0"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Martin Tepper"]
|
|
12
|
-
s.date =
|
|
13
|
-
s.description =
|
|
14
|
-
s.email =
|
|
12
|
+
s.date = "2012-04-11"
|
|
13
|
+
s.description = "Masterplan is a library for comparing Ruby data structures against predefined templates - like XML Schema without the XML. Please see the README on github for more information."
|
|
14
|
+
s.email = "mgpalmer@monogreen.de"
|
|
15
15
|
s.extra_rdoc_files = [
|
|
16
16
|
"LICENSE.txt",
|
|
17
17
|
"README.rdoc"
|
|
@@ -34,11 +34,11 @@ Gem::Specification.new do |s|
|
|
|
34
34
|
"spec/masterplan_spec.rb",
|
|
35
35
|
"spec/spec_helper.rb"
|
|
36
36
|
]
|
|
37
|
-
s.homepage =
|
|
37
|
+
s.homepage = "http://github.com/MGPalmer/masterplan"
|
|
38
38
|
s.licenses = ["MIT"]
|
|
39
39
|
s.require_paths = ["lib"]
|
|
40
|
-
s.rubygems_version =
|
|
41
|
-
s.summary =
|
|
40
|
+
s.rubygems_version = "1.8.19"
|
|
41
|
+
s.summary = "Masterplan is a library for comparing Ruby data structures against predefined templates - like XML Schema without the XML."
|
|
42
42
|
s.test_files = [
|
|
43
43
|
"spec/masterplan_spec.rb",
|
|
44
44
|
"spec/spec_helper.rb"
|
|
@@ -48,20 +48,20 @@ Gem::Specification.new do |s|
|
|
|
48
48
|
s.specification_version = 3
|
|
49
49
|
|
|
50
50
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
51
|
-
s.add_runtime_dependency(%q<activesupport>, ["
|
|
51
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
|
52
52
|
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
|
53
53
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
54
54
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
|
55
55
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
|
56
56
|
else
|
|
57
|
-
s.add_dependency(%q<activesupport>, ["
|
|
57
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
|
58
58
|
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
|
59
59
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
60
60
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
|
61
61
|
s.add_dependency(%q<rcov>, [">= 0"])
|
|
62
62
|
end
|
|
63
63
|
else
|
|
64
|
-
s.add_dependency(%q<activesupport>, ["
|
|
64
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
|
65
65
|
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
|
66
66
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
|
67
67
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
data/spec/masterplan_spec.rb
CHANGED
|
@@ -6,7 +6,7 @@ describe "Masterplan" do
|
|
|
6
6
|
before(:each) do
|
|
7
7
|
@scheme = Masterplan::Document.new({
|
|
8
8
|
"ship" => {
|
|
9
|
-
|
|
9
|
+
:parts => [
|
|
10
10
|
{
|
|
11
11
|
"name" => "Mast",
|
|
12
12
|
"length" => rule(12.3, :allow_nil => true),
|
|
@@ -19,7 +19,11 @@ describe "Masterplan" do
|
|
|
19
19
|
"material" => "steel",
|
|
20
20
|
"scream" => "HAAAAAARGH"
|
|
21
21
|
}
|
|
22
|
-
]
|
|
22
|
+
],
|
|
23
|
+
rule(:flags, :optional => true) => {
|
|
24
|
+
"image" => "jolly roger",
|
|
25
|
+
"count" => 1
|
|
26
|
+
}
|
|
23
27
|
}
|
|
24
28
|
})
|
|
25
29
|
end
|
|
@@ -67,7 +71,17 @@ describe "Masterplan" do
|
|
|
67
71
|
end.should raise_error(ArgumentError, /scheme needs to be a Masterplan::Document/)
|
|
68
72
|
end
|
|
69
73
|
|
|
70
|
-
it "complains if
|
|
74
|
+
it "complains if not given a proper format key" do
|
|
75
|
+
lambda do
|
|
76
|
+
Masterplan.compare(
|
|
77
|
+
:scheme => Masterplan::Document.new({}),
|
|
78
|
+
:to => {},
|
|
79
|
+
:format => :medium
|
|
80
|
+
)
|
|
81
|
+
end.should raise_error(ArgumentError, ":format needs to be one of [:full, :mini] !")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "complains if there are extra keys (unless they are optional)" do
|
|
71
85
|
test_value_and_expect(
|
|
72
86
|
{ :ship => {}, :boat => {} },
|
|
73
87
|
Masterplan::FailedError, /expected: ship*\n*received: boat,ship/
|
|
@@ -88,6 +102,119 @@ describe "Masterplan" do
|
|
|
88
102
|
)
|
|
89
103
|
end
|
|
90
104
|
|
|
105
|
+
context "optional keys" do
|
|
106
|
+
|
|
107
|
+
it "complains if a value is nil when in an optional but given value" do
|
|
108
|
+
test_value_and_expect(
|
|
109
|
+
{
|
|
110
|
+
:ship => {
|
|
111
|
+
:parts => [
|
|
112
|
+
:name => "Thingy",
|
|
113
|
+
:length => 1.0,
|
|
114
|
+
:material => "human",
|
|
115
|
+
:scream => "UUUUUUUUH"
|
|
116
|
+
],
|
|
117
|
+
:flags => {
|
|
118
|
+
"image" => nil,
|
|
119
|
+
"count" => 1
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
Masterplan::FailedError, /value at 'root'=>'ship'=>'flags'=>'image' \(NilClass\) is not a String/
|
|
124
|
+
)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "complains if keys don't match up when in an optional but given value" do
|
|
128
|
+
test_value_and_expect(
|
|
129
|
+
{
|
|
130
|
+
:ship => {
|
|
131
|
+
:parts => [
|
|
132
|
+
:name => "Thingy",
|
|
133
|
+
:length => 1.0,
|
|
134
|
+
:material => "human",
|
|
135
|
+
:scream => "UUUUUUUUH"
|
|
136
|
+
],
|
|
137
|
+
"flags" => {
|
|
138
|
+
"count" => 1
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
Masterplan::FailedError, /expected: count,image*\n*received: count/
|
|
143
|
+
)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
context "with subsets of mandatory and optional keys" do
|
|
147
|
+
before(:each) do
|
|
148
|
+
@multi_scheme = Masterplan::Document.new({
|
|
149
|
+
:mandatory_1 => "aaa",
|
|
150
|
+
:mandatory_2 => "aaa",
|
|
151
|
+
rule(:optional_1, :optional => true) => "aaa",
|
|
152
|
+
rule(:optional_2, :optional => true) => "aaa",
|
|
153
|
+
})
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "doesn't complain when all keys are given" do
|
|
157
|
+
Masterplan.compare(
|
|
158
|
+
:scheme => @multi_scheme,
|
|
159
|
+
:to => {
|
|
160
|
+
:mandatory_1 => "aaa",
|
|
161
|
+
:mandatory_2 => "aaa",
|
|
162
|
+
:optional_1 => "aaa",
|
|
163
|
+
:optional_2 => "aaa",
|
|
164
|
+
}
|
|
165
|
+
).should be_true
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "doesn't complain when only mandatory keys are given" do
|
|
169
|
+
Masterplan.compare(
|
|
170
|
+
:scheme => @multi_scheme,
|
|
171
|
+
:to => {
|
|
172
|
+
:mandatory_1 => "aaa",
|
|
173
|
+
:mandatory_2 => "aaa",
|
|
174
|
+
}
|
|
175
|
+
).should be_true
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "doesn't complain when only some optional keys are given" do
|
|
179
|
+
Masterplan.compare(
|
|
180
|
+
:scheme => @multi_scheme,
|
|
181
|
+
:to => {
|
|
182
|
+
:mandatory_1 => "aaa",
|
|
183
|
+
:mandatory_2 => "aaa",
|
|
184
|
+
:optional_2 => "aaa"
|
|
185
|
+
}
|
|
186
|
+
).should be_true
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it "complains when one mandatory key is missing" do
|
|
190
|
+
lambda do
|
|
191
|
+
Masterplan.compare(
|
|
192
|
+
:scheme => @multi_scheme,
|
|
193
|
+
:to => {:optional_1 => "aa", :optional_2 => "aaa", :mandatory_2 => "aaa"}
|
|
194
|
+
)
|
|
195
|
+
end.should raise_error(Masterplan::FailedError, /expected: mandatory_1,mandatory_2*\n*received: mandatory_2,optional_1,optional_2/)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "complains when all mandatory keys are missing" do
|
|
199
|
+
lambda do
|
|
200
|
+
Masterplan.compare(
|
|
201
|
+
:scheme => @multi_scheme,
|
|
202
|
+
:to => {:optional_1 => "aa", :optional_2 => "aaa"}
|
|
203
|
+
)
|
|
204
|
+
end.should raise_error(Masterplan::FailedError, /expected: mandatory_1,mandatory_2*\n*received:/)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it "complains when everything is missing" do
|
|
208
|
+
lambda do
|
|
209
|
+
Masterplan.compare(
|
|
210
|
+
:scheme => @multi_scheme,
|
|
211
|
+
:to => {}
|
|
212
|
+
)
|
|
213
|
+
end.should raise_error(Masterplan::FailedError, /expected: mandatory_1,mandatory_2*\n*received:/)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
91
218
|
it "does not complain if a value is nil and the rule allows nil" do
|
|
92
219
|
Masterplan.compare(
|
|
93
220
|
:scheme => @scheme,
|
|
@@ -109,11 +236,60 @@ describe "Masterplan" do
|
|
|
109
236
|
)
|
|
110
237
|
end
|
|
111
238
|
|
|
239
|
+
[nil, :full].each do |format|
|
|
240
|
+
it "produces full output for format = #{format}" do
|
|
241
|
+
lambda do
|
|
242
|
+
Masterplan.compare(
|
|
243
|
+
:scheme => @scheme,
|
|
244
|
+
:to => { :ship => [] },
|
|
245
|
+
:format => format
|
|
246
|
+
)
|
|
247
|
+
end.should raise_error(
|
|
248
|
+
/value at 'root'=>'ship' \(Array\) is not a Hash !\n\s*?Expected:.*?but was/m
|
|
249
|
+
)
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it "produces one-line output when using :mini format" do
|
|
254
|
+
lambda do
|
|
255
|
+
Masterplan.compare(
|
|
256
|
+
:scheme => @scheme,
|
|
257
|
+
:to => { :ship => [] },
|
|
258
|
+
:format => :mini
|
|
259
|
+
)
|
|
260
|
+
end.should raise_error(
|
|
261
|
+
"value at 'root'=>'ship' (Array) is not a Hash !"
|
|
262
|
+
)
|
|
263
|
+
end
|
|
264
|
+
|
|
112
265
|
it "checks all values of value arrays, but only against the first array value of the scheme"
|
|
113
266
|
it "checks all array values one-to-one if the compare_each rule is used"
|
|
114
267
|
end
|
|
115
268
|
|
|
116
|
-
it "
|
|
269
|
+
it "converts into plain example hashes" do
|
|
270
|
+
@scheme.to_hash.should == {
|
|
271
|
+
"ship" => {
|
|
272
|
+
:parts => [
|
|
273
|
+
{
|
|
274
|
+
"name" => "Mast",
|
|
275
|
+
"scream" => "AAAAAAH",
|
|
276
|
+
"length" => 12.3,
|
|
277
|
+
"material" => "wood"
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"name" => "Rudder",
|
|
281
|
+
"scream" => "HAAAAAARGH",
|
|
282
|
+
"length" => nil,
|
|
283
|
+
"material" => "steel"
|
|
284
|
+
}
|
|
285
|
+
],
|
|
286
|
+
:flags => {
|
|
287
|
+
"image" => "jolly roger",
|
|
288
|
+
"count" => 1
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
end
|
|
117
293
|
it "doesn't create a Document out of anything other than a Hash"
|
|
118
294
|
it "checks that the examples of rules obey the rules"
|
|
119
295
|
it "has a unit test extension method"
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: masterplan
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 11
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
|
-
-
|
|
8
|
+
- 5
|
|
9
9
|
- 0
|
|
10
|
-
version: 0.
|
|
10
|
+
version: 0.5.0
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Martin Tepper
|
|
@@ -15,28 +15,24 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date:
|
|
19
|
-
default_executable:
|
|
18
|
+
date: 2012-04-11 00:00:00 Z
|
|
20
19
|
dependencies:
|
|
21
20
|
- !ruby/object:Gem::Dependency
|
|
22
|
-
|
|
23
|
-
version_requirements: &id001 !ruby/object:Gem::Requirement
|
|
21
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
24
22
|
none: false
|
|
25
23
|
requirements:
|
|
26
|
-
- -
|
|
24
|
+
- - ">="
|
|
27
25
|
- !ruby/object:Gem::Version
|
|
28
|
-
hash:
|
|
26
|
+
hash: 3
|
|
29
27
|
segments:
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
- 0
|
|
29
|
+
version: "0"
|
|
30
|
+
version_requirements: *id001
|
|
31
|
+
name: activesupport
|
|
34
32
|
prerelease: false
|
|
35
33
|
type: :runtime
|
|
36
|
-
requirement: *id001
|
|
37
34
|
- !ruby/object:Gem::Dependency
|
|
38
|
-
|
|
39
|
-
version_requirements: &id002 !ruby/object:Gem::Requirement
|
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
40
36
|
none: false
|
|
41
37
|
requirements:
|
|
42
38
|
- - ~>
|
|
@@ -47,12 +43,12 @@ dependencies:
|
|
|
47
43
|
- 3
|
|
48
44
|
- 0
|
|
49
45
|
version: 2.3.0
|
|
46
|
+
version_requirements: *id002
|
|
47
|
+
name: rspec
|
|
50
48
|
prerelease: false
|
|
51
49
|
type: :development
|
|
52
|
-
requirement: *id002
|
|
53
50
|
- !ruby/object:Gem::Dependency
|
|
54
|
-
|
|
55
|
-
version_requirements: &id003 !ruby/object:Gem::Requirement
|
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
56
52
|
none: false
|
|
57
53
|
requirements:
|
|
58
54
|
- - ~>
|
|
@@ -63,12 +59,12 @@ dependencies:
|
|
|
63
59
|
- 0
|
|
64
60
|
- 0
|
|
65
61
|
version: 1.0.0
|
|
62
|
+
version_requirements: *id003
|
|
63
|
+
name: bundler
|
|
66
64
|
prerelease: false
|
|
67
65
|
type: :development
|
|
68
|
-
requirement: *id003
|
|
69
66
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
|
|
71
|
-
version_requirements: &id004 !ruby/object:Gem::Requirement
|
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
|
72
68
|
none: false
|
|
73
69
|
requirements:
|
|
74
70
|
- - ~>
|
|
@@ -79,12 +75,12 @@ dependencies:
|
|
|
79
75
|
- 5
|
|
80
76
|
- 2
|
|
81
77
|
version: 1.5.2
|
|
78
|
+
version_requirements: *id004
|
|
79
|
+
name: jeweler
|
|
82
80
|
prerelease: false
|
|
83
81
|
type: :development
|
|
84
|
-
requirement: *id004
|
|
85
82
|
- !ruby/object:Gem::Dependency
|
|
86
|
-
|
|
87
|
-
version_requirements: &id005 !ruby/object:Gem::Requirement
|
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
|
88
84
|
none: false
|
|
89
85
|
requirements:
|
|
90
86
|
- - ">="
|
|
@@ -93,11 +89,12 @@ dependencies:
|
|
|
93
89
|
segments:
|
|
94
90
|
- 0
|
|
95
91
|
version: "0"
|
|
92
|
+
version_requirements: *id005
|
|
93
|
+
name: rcov
|
|
96
94
|
prerelease: false
|
|
97
95
|
type: :development
|
|
98
|
-
requirement: *id005
|
|
99
96
|
description: Masterplan is a library for comparing Ruby data structures against predefined templates - like XML Schema without the XML. Please see the README on github for more information.
|
|
100
|
-
email:
|
|
97
|
+
email: mgpalmer@monogreen.de
|
|
101
98
|
executables: []
|
|
102
99
|
|
|
103
100
|
extensions: []
|
|
@@ -122,8 +119,7 @@ files:
|
|
|
122
119
|
- masterplan.gemspec
|
|
123
120
|
- spec/masterplan_spec.rb
|
|
124
121
|
- spec/spec_helper.rb
|
|
125
|
-
|
|
126
|
-
homepage: http://github.com/traveliq/masterplan
|
|
122
|
+
homepage: http://github.com/MGPalmer/masterplan
|
|
127
123
|
licenses:
|
|
128
124
|
- MIT
|
|
129
125
|
post_install_message:
|
|
@@ -152,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
152
148
|
requirements: []
|
|
153
149
|
|
|
154
150
|
rubyforge_project:
|
|
155
|
-
rubygems_version: 1.
|
|
151
|
+
rubygems_version: 1.8.19
|
|
156
152
|
signing_key:
|
|
157
153
|
specification_version: 3
|
|
158
154
|
summary: Masterplan is a library for comparing Ruby data structures against predefined templates - like XML Schema without the XML.
|