json-spec 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.gitmodules +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +960 -0
  7. data/Rakefile +10 -0
  8. data/api_documentation.md +611 -0
  9. data/cachivache/.gitignore +1 -0
  10. data/cachivache/Gemfile +4 -0
  11. data/cachivache/README.md +247 -0
  12. data/cachivache/Rakefile +19 -0
  13. data/cachivache/Vagrantfile +70 -0
  14. data/cachivache/cachivache.rb +59 -0
  15. data/cachivache/lib/let-behaviour.rb +27 -0
  16. data/cachivache/lib/rake-helper.rb +131 -0
  17. data/cachivache/lib/sh-file-context.rb +39 -0
  18. data/cachivache/lib/sh-if-context.rb +31 -0
  19. data/cachivache/stuff/.gitkeep +0 -0
  20. data/cachivache/stuff/ruby-json-spec.rb +22 -0
  21. data/examples/example-1-simple.rb +66 -0
  22. data/examples/example-2-default-expectations.rb +63 -0
  23. data/examples/example-3-each-field.rb +104 -0
  24. data/examples/example-4-to-be-as-defined-in.rb +117 -0
  25. data/examples/example-5-custom-expectations.rb +153 -0
  26. data/examples/example-6-custom-messages.rb +36 -0
  27. data/examples/example-7-full-example.rb +231 -0
  28. data/examples/fixtures.rb +77 -0
  29. data/examples/validation-printer.rb +47 -0
  30. data/json-spec.gemspec +29 -0
  31. data/lib/cabeza-de-termo/json-spec/errors/error.rb +6 -0
  32. data/lib/cabeza-de-termo/json-spec/errors/expectation-not-found-error.rb +8 -0
  33. data/lib/cabeza-de-termo/json-spec/errors/modifier-not-found-error.rb +8 -0
  34. data/lib/cabeza-de-termo/json-spec/errors/unkown-json-type-error.rb +8 -0
  35. data/lib/cabeza-de-termo/json-spec/errors/validation-error.rb +8 -0
  36. data/lib/cabeza-de-termo/json-spec/expectations-library/default-expectations/default-expectation-builder.rb +29 -0
  37. data/lib/cabeza-de-termo/json-spec/expectations-library/default-expectations/default-expectations-mapping.rb +54 -0
  38. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/block-expectation-definition.rb +16 -0
  39. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/class-expectation-definition.rb +15 -0
  40. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expectation-definition.rb +19 -0
  41. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expectations-definition-builder.rb +136 -0
  42. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expecting-all-of-expectation-definition.rb +23 -0
  43. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expecting-any-of-expectation-definition.rb +23 -0
  44. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/expecting-expectation-definition.rb +17 -0
  45. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-builders/negating-expectation-definition.rb +16 -0
  46. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/expectation-library-definition-builder.rb +35 -0
  47. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/class-modifier-definition.rb +15 -0
  48. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/composing-modifiers-definition.rb +28 -0
  49. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/modifier-definition.rb +13 -0
  50. data/lib/cabeza-de-termo/json-spec/expectations-library/definition-builders/modifier-builders/modifiers-definition-builder.rb +73 -0
  51. data/lib/cabeza-de-termo/json-spec/expectations-library/expectations-library.rb +150 -0
  52. data/lib/cabeza-de-termo/json-spec/expectations-library/initializers/default-library-initializer.rb +265 -0
  53. data/lib/cabeza-de-termo/json-spec/expectations-library/initializers/library-initializer.rb +9 -0
  54. data/lib/cabeza-de-termo/json-spec/expectations-library/messages/expectation-messages-mapping.rb +27 -0
  55. data/lib/cabeza-de-termo/json-spec/expectations/abstract-expectation.rb +39 -0
  56. data/lib/cabeza-de-termo/json-spec/expectations/all-expectations-composite.rb +33 -0
  57. data/lib/cabeza-de-termo/json-spec/expectations/any-expectation-composite.rb +33 -0
  58. data/lib/cabeza-de-termo/json-spec/expectations/block-expectation.rb +28 -0
  59. data/lib/cabeza-de-termo/json-spec/expectations/expectation.rb +51 -0
  60. data/lib/cabeza-de-termo/json-spec/expectations/is-email-expectation.rb +16 -0
  61. data/lib/cabeza-de-termo/json-spec/expectations/is-scalar-expectation.rb +17 -0
  62. data/lib/cabeza-de-termo/json-spec/expectations/is-url-expectation.rb +21 -0
  63. data/lib/cabeza-de-termo/json-spec/expectations/negated-expectation.rb +31 -0
  64. data/lib/cabeza-de-termo/json-spec/expectations/runner/abstract-expectations-runner.rb +27 -0
  65. data/lib/cabeza-de-termo/json-spec/expectations/runner/can-be-absent-expectations-runner.rb +50 -0
  66. data/lib/cabeza-de-termo/json-spec/expectations/runner/can-be-null-expectations-runner.rb +48 -0
  67. data/lib/cabeza-de-termo/json-spec/expectations/runner/expectations-runner.rb +43 -0
  68. data/lib/cabeza-de-termo/json-spec/expressions/json-any-of.rb +62 -0
  69. data/lib/cabeza-de-termo/json-spec/expressions/json-anything.rb +16 -0
  70. data/lib/cabeza-de-termo/json-spec/expressions/json-each-field.rb +58 -0
  71. data/lib/cabeza-de-termo/json-spec/expressions/json-each.rb +58 -0
  72. data/lib/cabeza-de-termo/json-spec/expressions/json-expression.rb +314 -0
  73. data/lib/cabeza-de-termo/json-spec/expressions/json-field-name.rb +16 -0
  74. data/lib/cabeza-de-termo/json-spec/expressions/json-field.rb +76 -0
  75. data/lib/cabeza-de-termo/json-spec/expressions/json-list.rb +40 -0
  76. data/lib/cabeza-de-termo/json-spec/expressions/json-object.rb +82 -0
  77. data/lib/cabeza-de-termo/json-spec/expressions/json-scalar.rb +20 -0
  78. data/lib/cabeza-de-termo/json-spec/expressions/json-spec.rb +174 -0
  79. data/lib/cabeza-de-termo/json-spec/instantiators/abstract-instantiator.rb +9 -0
  80. data/lib/cabeza-de-termo/json-spec/instantiators/all-expectations-composite-instantiator.rb +12 -0
  81. data/lib/cabeza-de-termo/json-spec/instantiators/any-expectation-composite-instantiator.rb +12 -0
  82. data/lib/cabeza-de-termo/json-spec/instantiators/block-expectation-instantiator.rb +16 -0
  83. data/lib/cabeza-de-termo/json-spec/instantiators/composite-instantiator.rb +45 -0
  84. data/lib/cabeza-de-termo/json-spec/instantiators/modifier-composite-instantiator.rb +12 -0
  85. data/lib/cabeza-de-termo/json-spec/instantiators/negated-expectation-instantiator.rb +20 -0
  86. data/lib/cabeza-de-termo/json-spec/instantiators/patial-application-instantiator.rb +26 -0
  87. data/lib/cabeza-de-termo/json-spec/json-spec.rb +2 -0
  88. data/lib/cabeza-de-termo/json-spec/message-formatters/block-message-formatter.rb +15 -0
  89. data/lib/cabeza-de-termo/json-spec/message-formatters/erb-message-formatter.rb +60 -0
  90. data/lib/cabeza-de-termo/json-spec/message-formatters/message-formatter.rb +9 -0
  91. data/lib/cabeza-de-termo/json-spec/metaprogramming/message-send.rb +37 -0
  92. data/lib/cabeza-de-termo/json-spec/metaprogramming/message.rb +37 -0
  93. data/lib/cabeza-de-termo/json-spec/metaprogramming/object-method.rb +14 -0
  94. data/lib/cabeza-de-termo/json-spec/modifiers/can-be-absent-modifier.rb +13 -0
  95. data/lib/cabeza-de-termo/json-spec/modifiers/can-be-null-modifier.rb +13 -0
  96. data/lib/cabeza-de-termo/json-spec/modifiers/expression-modifier.rb +9 -0
  97. data/lib/cabeza-de-termo/json-spec/modifiers/modifier-composite.rb +27 -0
  98. data/lib/cabeza-de-termo/json-spec/signals/signal.rb +6 -0
  99. data/lib/cabeza-de-termo/json-spec/signals/skip-branch-signal.rb +8 -0
  100. data/lib/cabeza-de-termo/json-spec/utilities/bind.rb +20 -0
  101. data/lib/cabeza-de-termo/json-spec/utilities/range.rb +70 -0
  102. data/lib/cabeza-de-termo/json-spec/value-holders/accessors-chain.rb +27 -0
  103. data/lib/cabeza-de-termo/json-spec/value-holders/missing-value.rb +21 -0
  104. data/lib/cabeza-de-termo/json-spec/value-holders/value-holder.rb +135 -0
  105. data/lib/cabeza-de-termo/json-spec/version.rb +5 -0
  106. data/lib/cabeza-de-termo/json-spec/walkers/expression-walker.rb +66 -0
  107. data/lib/cabeza-de-termo/json-spec/walkers/json-expectations-runner.rb +214 -0
  108. data/lib/cabeza-de-termo/json-spec/walkers/json-expression-explainer.rb +183 -0
  109. data/lib/cabeza-de-termo/json-spec/walkers/reporter/expectation-report.rb +63 -0
  110. data/lib/cabeza-de-termo/json-spec/walkers/reporter/json-expectations-reporter.rb +111 -0
  111. data/lib/cabeza-de-termo/json-spec/walkers/validator/json-validator-error.rb +29 -0
  112. data/lib/cabeza-de-termo/json-spec/walkers/validator/json-validator.rb +133 -0
  113. data/lib/cabeza-de-termo/json-spec/walkers/value-holders-stack-behaviour.rb +57 -0
  114. metadata +242 -0
@@ -0,0 +1,17 @@
1
+ require_relative "expectation-definition"
2
+ require "cabeza-de-termo/json-spec/instantiators/patial-application-instantiator"
3
+
4
+ module CabezaDeTermo
5
+ module JsonSpec
6
+ class ExpectingExpectationDefinition < ExpectationDefinition
7
+ def expect(expectation_method, *args)
8
+ @expectation_instantiator = expectation_instantiator_for(expectation_method)
9
+ @args = args
10
+ end
11
+
12
+ def expectation_instantiator()
13
+ PartialApplicationInstantiator.new(@expectation_instantiator, @args)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ require_relative "expectation-definition"
2
+ require "cabeza-de-termo/json-spec/instantiators/negated-expectation-instantiator"
3
+
4
+ module CabezaDeTermo
5
+ module JsonSpec
6
+ class NegatingExpectationDefinition < ExpectationDefinition
7
+ def negate(expectation_method)
8
+ @expectation_instantiator = expectation_instantiator_for(expectation_method)
9
+ end
10
+
11
+ def expectation_instantiator()
12
+ NegatedExpectationInstantiator.new(@expectation_instantiator)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ require_relative "modifier-builders/modifiers-definition-builder"
2
+ require_relative "expectation-builders/expectations-definition-builder"
3
+
4
+ module CabezaDeTermo
5
+ module JsonSpec
6
+ class ExpectationLibraryDefinitionBuilder
7
+ # Initializing
8
+
9
+ def initialize(expectations_library)
10
+ @expectations_library = expectations_library
11
+ end
12
+
13
+ # Accessing
14
+
15
+ def expectations_library
16
+ @expectations_library
17
+ end
18
+
19
+ def expectations(&block)
20
+ ExpectationsDefinitionBuilder.for(expectations_library, &block)
21
+ self
22
+ end
23
+
24
+ def modifiers(&block)
25
+ ModifiersDefinitionBuilder.for(expectations_library, &block)
26
+ self
27
+ end
28
+
29
+ def default_expectations(&block)
30
+ Bind.evaluation of: block, to: expectations_library.default_expectations
31
+ self
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,15 @@
1
+ require_relative "modifier-definition"
2
+
3
+ module CabezaDeTermo
4
+ module JsonSpec
5
+ class ClassModifierDefinition < ModifierDefinition
6
+ def klass(klass)
7
+ @klass = klass
8
+ end
9
+
10
+ def modifier_instantiator
11
+ @klass
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ require_relative "modifier-definition"
2
+ require "cabeza-de-termo/json-spec/instantiators/modifier-composite-instantiator"
3
+ require "cabeza-de-termo/json-spec/instantiators/patial-application-instantiator"
4
+
5
+ module CabezaDeTermo
6
+ module JsonSpec
7
+ class ComposingModifiersDefinition < ModifierDefinition
8
+ def initialize(expectations_library)
9
+ super(expectations_library)
10
+
11
+ @modifier_instantiators = []
12
+ end
13
+
14
+ def with(modifier_method, *args)
15
+ @modifier_instantiators << PartialApplicationInstantiator.new(modifier_instantiator_for(modifier_method), args)
16
+ self
17
+ end
18
+
19
+ def modifier_instantiator
20
+ ModifierCompositeInstantiator.with_all(@modifier_instantiators)
21
+ end
22
+
23
+ def modifier_instantiator_for(method_name)
24
+ @expectations_library.modifier_instantiator_for(method_name)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ module CabezaDeTermo
2
+ module JsonSpec
3
+ class ModifierDefinition
4
+ def initialize(expectations_library)
5
+ @expectations_library = expectations_library
6
+ end
7
+
8
+ def modifier_instantiator
9
+ raise 'Subclass responsibility'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,73 @@
1
+ require_relative "class-modifier-definition"
2
+ require_relative "composing-modifiers-definition"
3
+
4
+ module CabezaDeTermo
5
+ module JsonSpec
6
+ class ModifiersDefinitionBuilder
7
+ def self.for(expectations_library, &block)
8
+ new(expectations_library, &block)
9
+ end
10
+
11
+ def initialize(expectations_library, &block)
12
+ @expectations_library = expectations_library
13
+
14
+ Bind.evaluation of: block, to: self
15
+ end
16
+
17
+ # Accessing
18
+
19
+ def expectations_library
20
+ @expectations_library
21
+ end
22
+
23
+ def method_name
24
+ @method_name
25
+ end
26
+
27
+ def definition
28
+ @definition
29
+ end
30
+
31
+ # Building definition
32
+
33
+ def reset_current_definition
34
+ @method_name = nil
35
+ @definition = nil
36
+ end
37
+
38
+ def define(method_name, &block)
39
+ @method_name = method_name.to_sym
40
+
41
+ block.call
42
+
43
+ define_modifier_in_library
44
+ reset_current_definition
45
+ end
46
+
47
+ def with_class(klass)
48
+ @definition = ClassModifierDefinition.new(expectations_library)
49
+ @definition.klass klass
50
+ end
51
+
52
+ def composing(modifier)
53
+ @definition = ComposingModifiersDefinition.new(expectations_library)
54
+ @definition.with modifier
55
+ end
56
+
57
+ def define_modifier_in_library
58
+ expectations_library.define_modifier(method_name, modifier_instantiator)
59
+ end
60
+
61
+ def modifier_instantiator
62
+ definition.modifier_instantiator
63
+ end
64
+
65
+ # Messages delegation
66
+
67
+ # Delegate every method to the current definition builder
68
+ def method_missing(method_name, *args, &block)
69
+ @definition.send(method_name, *args, &block)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,150 @@
1
+ require_relative "initializers/default-library-initializer"
2
+ require_relative "messages/expectation-messages-mapping"
3
+ require_relative "default-expectations/default-expectations-mapping"
4
+
5
+ require_relative "definition-builders/expectation-library-definition-builder"
6
+
7
+ require "cabeza-de-termo/json-spec/errors/expectation-not-found-error"
8
+ require "cabeza-de-termo/json-spec/errors/modifier-not-found-error"
9
+
10
+ module CabezaDeTermo
11
+ module JsonSpec
12
+ class ExpectationsLibrary
13
+ @current = nil
14
+ @default_library_initializer = nil
15
+
16
+ # Instance accessing
17
+
18
+ def self.current()
19
+ @current = new_default if @current.nil?
20
+ @current
21
+ end
22
+
23
+ def self.set_current(expectations_library)
24
+ to_be_replaced = current
25
+ @current = expectations_library
26
+
27
+ to_be_replaced
28
+ end
29
+
30
+ def self.define(&block)
31
+ current.define(&block)
32
+ end
33
+
34
+ def self.reset()
35
+ @current = nil
36
+ end
37
+
38
+ # Initializing
39
+
40
+ def self.default_library_initializer()
41
+ set_default_library_initializer(new_default_library_initializer) if @default_library_initializer.nil?
42
+
43
+ @default_library_initializer
44
+ end
45
+
46
+ def self.set_default_library_initializer(library_initializer)
47
+ to_be_replaced = @default_library_initializer
48
+ @default_library_initializer = library_initializer
49
+
50
+ to_be_replaced
51
+ end
52
+
53
+ def self.new_default_library_initializer()
54
+ DefaultLibraryInitializer.new
55
+ end
56
+
57
+ def self.new_default()
58
+ default_library_initializer.new_library
59
+ end
60
+
61
+ # Instance methods
62
+
63
+ def initialize()
64
+ @expectations = {}
65
+ @modifiers = {}
66
+ @expectation_messages_mapping = new_expectations_messages_mapping
67
+ @default_expectations_mapping = new_default_expectations_mapping
68
+ end
69
+
70
+ # Accessing
71
+
72
+ def default_expectations()
73
+ @default_expectations_mapping
74
+ end
75
+
76
+ # Defining
77
+
78
+ def define(&block)
79
+ Bind.evaluation of: block, to: ExpectationLibraryDefinitionBuilder.new(self)
80
+ end
81
+
82
+ # Expectation messages
83
+
84
+ def has_message_formatter_for?(expectation_method)
85
+ @expectation_messages_mapping.has_message_formatter_for?(expectation_method)
86
+ end
87
+
88
+ def message_formatter_for(expectation_method)
89
+ @expectation_messages_mapping.message_formatter_for(expectation_method)
90
+ end
91
+
92
+ def define_message_formatter_for(expectation_method, message_block)
93
+ @expectation_messages_mapping.define_message_formatter_for(expectation_method, message_block)
94
+
95
+ self
96
+ end
97
+
98
+ # Expectations
99
+
100
+ def define_expectation(expectation_method, expectation_instantiator)
101
+ @expectations[expectation_method.to_sym] = expectation_instantiator
102
+ self
103
+ end
104
+
105
+ def has_expectation_for?(expectation_method)
106
+ @expectations.key?(expectation_method.to_sym)
107
+ end
108
+
109
+ def expectation_instantiator_for(expectation_method)
110
+ return @expectations[expectation_method.to_sym] if has_expectation_for?(expectation_method)
111
+ raise ExpectationNotFoundError.new("The Expectation method '#{expectation_method}' was not found.")
112
+ end
113
+
114
+ def new_expectation_from_message(message)
115
+ expectation_instantiator_for( message.method_name ).new( *message.args )
116
+ end
117
+
118
+ # Modifiers
119
+
120
+ def define_modifier(expectation_method, modifier_instantiator)
121
+ @modifiers[expectation_method.to_sym] = modifier_instantiator
122
+
123
+ self
124
+ end
125
+
126
+ def has_modifier_for?(expectation_method)
127
+ @modifiers.key?(expectation_method.to_sym)
128
+ end
129
+
130
+ def modifier_instantiator_for(method_name)
131
+ return @modifiers[method_name.to_sym] if has_modifier_for?(method_name)
132
+ raise ModifierNotFoundError.new("The modifier method '#{method_name}' was not found.")
133
+ end
134
+
135
+ def new_modifier_from_message(message)
136
+ modifier_instantiator_for(message.method_name).new( *message.args )
137
+ end
138
+
139
+ # Helpers
140
+
141
+ def new_expectations_messages_mapping()
142
+ ExpectationMessagesMapping.new
143
+ end
144
+
145
+ def new_default_expectations_mapping()
146
+ DefaultExpectationsMapping.new
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,265 @@
1
+ require_relative "library-initializer"
2
+
3
+ require "cabeza-de-termo/json-spec/expectations/is-scalar-expectation"
4
+ require "cabeza-de-termo/json-spec/expectations/is-url-expectation"
5
+ require "cabeza-de-termo/json-spec/expectations/is-email-expectation"
6
+
7
+ require "cabeza-de-termo/json-spec/modifiers/can-be-absent-modifier"
8
+ require "cabeza-de-termo/json-spec/modifiers/can-be-null-modifier"
9
+
10
+ module CabezaDeTermo
11
+ module JsonSpec
12
+ class DefaultLibraryInitializer < LibraryInitializer
13
+ def new_library()
14
+ library = ExpectationsLibrary.new
15
+ define_library(library)
16
+ end
17
+
18
+ def define_library(library)
19
+ library.define do
20
+
21
+ # Define expectations
22
+ expectations do
23
+ define :to_exist do
24
+ with_block { |value_holder, expected_value| value_holder.not_missing_value? }
25
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' exists."
26
+ end
27
+
28
+ define :to_be_absent do
29
+ negating :to_exist
30
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is absent."
31
+ end
32
+
33
+ define :to_be_kind_of do
34
+ with_block { |value_holder, expected_class| value_holder.value.kind_of? expected_class }
35
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is a <%= expectation.args[0] %>."
36
+ end
37
+
38
+ define :to_be_true do
39
+ expecting :to_be_kind_of, ::TrueClass
40
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is true."
41
+ end
42
+
43
+ define :to_be_false do
44
+ expecting :to_be_kind_of, ::FalseClass
45
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is false."
46
+ end
47
+
48
+ define :to_be_boolean do
49
+ expecting_any_of :to_be_true
50
+ or_also :to_be_true
51
+
52
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is a boolean."
53
+ end
54
+
55
+ define :to_be_float do
56
+ expecting :to_be_kind_of, ::Float
57
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is a float."
58
+ end
59
+
60
+ define :to_be_integer do
61
+ expecting :to_be_kind_of, ::Integer
62
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is an integer."
63
+ end
64
+
65
+ define :to_be_list do
66
+ expecting :to_be_kind_of, ::Array
67
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is a list."
68
+ end
69
+
70
+ define :to_be_number do
71
+ expecting :to_be_kind_of, ::Numeric
72
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is a number."
73
+ end
74
+
75
+ define :to_be_scalar do
76
+ with_class IsScalarExpectation
77
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is a scalar."
78
+ end
79
+
80
+ define :to_be_object do
81
+ expecting :to_be_kind_of, ::Hash
82
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is an object."
83
+ end
84
+
85
+ define :to_be_string do
86
+ expecting :to_be_kind_of, ::String
87
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is a string."
88
+ end
89
+
90
+ define :to_be_null do
91
+ with_block { |value_holder, expected_value| value_holder.value.nil? }
92
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is null."
93
+ end
94
+
95
+ define :not_null do
96
+ negating :to_be_null
97
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is not null."
98
+ end
99
+
100
+ define :to_be_defined do
101
+ expecting_all_of :to_exist
102
+ and_also :not_null
103
+
104
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is defined."
105
+ end
106
+
107
+ define :not_defined do
108
+ negating :to_be_defined
109
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is not defined."
110
+ end
111
+
112
+ define :to_be_empty do
113
+ with_block { |value_holder, expected_value| value_holder.is_empty? }
114
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is empty."
115
+ end
116
+
117
+ define :not_empty do
118
+ negating :to_be_empty
119
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is not empty."
120
+ end
121
+
122
+ define :_to_be_blank do
123
+ with_block { |value_holder, expected_value| value_holder.value.strip.empty? }
124
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is blank."
125
+ end
126
+
127
+ define :to_be_blank do
128
+ expecting_all_of :to_be_string
129
+ and_also :_to_be_blank
130
+
131
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is blank."
132
+ end
133
+
134
+ define :not_blank do
135
+ negating :to_be_blank
136
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is not blank."
137
+ end
138
+
139
+ define :to_be_equal_to do
140
+ with_block { |value_holder, expected_value| expected_value == value_holder.value }
141
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is equal to '<%= expectation.args[0] %>'."
142
+ end
143
+
144
+ define :not_equal_to do
145
+ negating :to_be_equal_to
146
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is not equal to '<%= expectation.args[0] %>'."
147
+ end
148
+
149
+ define :_to_match do
150
+ with_block do |value_holder, expected_regex|
151
+ expected_regex.match(value_holder.value) != nil
152
+ end
153
+
154
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' matches '<%= expectation.args[0] %>'."
155
+ end
156
+
157
+ define :to_match do
158
+ expecting_all_of :to_be_string
159
+ and_also :_to_match
160
+
161
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' matches '<%= expectation.child_expectations[1].args[0] %>'."
162
+ end
163
+
164
+ define :not_to_match do
165
+ negating :to_match
166
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' does not match '<%= expectation.child_expectations[1].args[0] %>'."
167
+ end
168
+
169
+ define :to_be_string_as_integer do
170
+ expecting :to_match, /^[-+]?\d+$/
171
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' has a valid integer format."
172
+ end
173
+
174
+ define :to_be_string_as_float do
175
+ expecting :to_match, /^[-+]?[0-9]*\.?[0-9]+$/
176
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' has a valid float format."
177
+ end
178
+
179
+ define :to_be_in do
180
+ with_block do |value_holder, possible_values|
181
+ possible_values.include?( value_holder.value )
182
+ end
183
+
184
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is equal to any of <%= expectation.args[0] %>."
185
+ end
186
+
187
+ define :not_in do
188
+ negating :to_be_in
189
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is not equal to any of <%= expectation.args[0] %>."
190
+ end
191
+
192
+ define :to_be_email do
193
+ with_class IsEmailExpectation
194
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is an email."
195
+ end
196
+
197
+ define :to_be_url do
198
+ with_class IsUrlExpectation
199
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is an url."
200
+ end
201
+
202
+ define :to_be_in_range do
203
+ with_block do |value_holder, expectedRange|
204
+ expectedRange.includes?( value_holder.value )
205
+ end
206
+
207
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is in range <%= expectation.args[0] %>."
208
+ end
209
+
210
+ define :not_in_range do
211
+ negating :to_be_in_range
212
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is not in range <%= expectation.args[0] %>."
213
+ end
214
+
215
+ define :to_be_between do
216
+ with_block do |value_holder, min, max|
217
+ Range::new_from('[', min, max, ']').includes?( value_holder.value )
218
+ end
219
+
220
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is between <%= Range.new(expectation.args[0], expectation.args[1]).to_s %>."
221
+ end
222
+
223
+ define :not_between do
224
+ negating :to_be_between
225
+ message "Failed asserting that the field '<%= field %>' with value = '<%= format value %>' is not between <%= Range.new(expectation.args[0], expectation.args[1]).to_s %>."
226
+ end
227
+ end
228
+
229
+ # Define modifiers
230
+ modifiers do
231
+ define :can_be_absent do
232
+ with_class CanBeAbsentModifier
233
+ end
234
+
235
+ define :can_be_null do
236
+ with_class CanBeNullModifier
237
+ end
238
+
239
+ define :can_be_undefined do
240
+ composing :can_be_null
241
+ with :can_be_absent
242
+ end
243
+ end
244
+
245
+ # Define default expectations
246
+ default_expectations do
247
+ for_every_object do
248
+ to_be_object
249
+ end
250
+
251
+ for_every_list do
252
+ to_be_list
253
+ end
254
+
255
+ for_every_scalar do
256
+ to_be_scalar
257
+ end
258
+ end
259
+ end
260
+
261
+ library
262
+ end
263
+ end
264
+ end
265
+ end