json-spec 0.1.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.
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,9 @@
1
+ module CabezaDeTermo
2
+ module JsonSpec
3
+ class LibraryInitializer
4
+ def new_library()
5
+ raise 'Subclass responsibility'
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ module CabezaDeTermo
2
+ module JsonSpec
3
+ class ExpectationMessagesMapping
4
+ def initialize()
5
+ @messages = {}
6
+ end
7
+
8
+ def messages
9
+ @messages
10
+ end
11
+
12
+ def message_formatter_for(expectation_method)
13
+ messages[expectation_method.to_sym]
14
+ end
15
+
16
+ def has_message_formatter_for?(expectation_method)
17
+ messages.key?(expectation_method.to_sym)
18
+ end
19
+
20
+ def define_message_formatter_for(expectation_method, message_block)
21
+ messages[expectation_method.to_sym] = message_block
22
+
23
+ self
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,39 @@
1
+ module CabezaDeTermo
2
+ module JsonSpec
3
+ class AbstractExpectation
4
+ # Accessing
5
+
6
+ def set_json_spec(json_spec)
7
+ raise 'Subclass responsibility'
8
+ end
9
+
10
+ def set_expectation_method(expectation_method)
11
+ raise 'Subclass responsibility'
12
+ end
13
+
14
+ # Message format
15
+
16
+ def failed_message_on(value_holder)
17
+ raise 'Subclass responsibility'
18
+ end
19
+
20
+ # Evaluating
21
+
22
+ def is_satisfied_by?(value_holder)
23
+ raise 'Subclass responsibility'
24
+ end
25
+
26
+ # Walking
27
+
28
+ def accept_walker(expression_walker)
29
+ raise 'Subclass responsibility'
30
+ end
31
+
32
+ # Explaining
33
+
34
+ def explain()
35
+ raise 'Subclass responsibility'
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ require_relative "expectation"
2
+
3
+ module CabezaDeTermo
4
+ module JsonSpec
5
+ class AllExpectationsComposite < Expectation
6
+ def initialize()
7
+ @child_expectations = []
8
+ end
9
+
10
+ def child_expectations
11
+ @child_expectations
12
+ end
13
+
14
+ def set_json_spec(json_spec)
15
+ super(json_spec)
16
+
17
+ child_expectations.each do |child_expectation|
18
+ child_expectation.set_json_spec(json_spec)
19
+ end
20
+ end
21
+
22
+ def add_child(child_expectation)
23
+ child_expectations << child_expectation
24
+ end
25
+
26
+ def is_satisfied_by?(value_holder)
27
+ child_expectations.all? do |child_expectation|
28
+ child_expectation.is_satisfied_by?(value_holder)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ require_relative "expectation"
2
+
3
+ module CabezaDeTermo
4
+ module JsonSpec
5
+ class AnyExpectationComposite < Expectation
6
+ def initialize()
7
+ @child_expectations = []
8
+ end
9
+
10
+ def child_expectations
11
+ @child_expectations
12
+ end
13
+
14
+ def set_json_spec(json_spec)
15
+ super(json_spec)
16
+
17
+ child_expectations.each do |child_expectation|
18
+ child_expectation.set_json_spec(json_spec)
19
+ end
20
+ end
21
+
22
+ def add_child(child_expectation)
23
+ child_expectations << child_expectation
24
+ end
25
+
26
+ def is_satisfied_by?(value_holder)
27
+ child_expectations.any? do |child_expectation|
28
+ child_expectation.is_satisfied_by?(value_holder)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ require_relative "expectation"
2
+
3
+ module CabezaDeTermo
4
+ module JsonSpec
5
+ class BlockExpectation < Expectation
6
+ def initialize(block , *args)
7
+ super()
8
+
9
+ @block = block
10
+ @args = args
11
+ end
12
+
13
+ def args
14
+ @args
15
+ end
16
+
17
+ def is_satisfied_by?(value_holder)
18
+ @block.call(value_holder, *args)
19
+ end
20
+
21
+ # Explaining
22
+
23
+ def explain_parameters()
24
+ '(' + args.join(', ') + ')'
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,51 @@
1
+ require_relative 'abstract-expectation'
2
+
3
+ module CabezaDeTermo
4
+ module JsonSpec
5
+ class Expectation < AbstractExpectation
6
+ # Accessing
7
+
8
+ def set_json_spec(json_spec)
9
+ @json_spec = json_spec
10
+ end
11
+
12
+ def json_spec()
13
+ @json_spec
14
+ end
15
+
16
+ def expectation_method()
17
+ @expectation_method
18
+ end
19
+
20
+ def set_expectation_method(expectation_method)
21
+ @expectation_method = expectation_method
22
+ end
23
+
24
+ # Message format
25
+
26
+ def failed_message_on(value_holder)
27
+ failed_message_block.message_on(self, value_holder)
28
+ end
29
+
30
+ def failed_message_block()
31
+ json_spec.message_formatter_for(expectation_method)
32
+ end
33
+
34
+ # Walking
35
+
36
+ def accept_walker(expression_walker)
37
+ expression_walker.walk_expectation(self)
38
+ end
39
+
40
+ # Explaining
41
+
42
+ def explain()
43
+ expectation_method.to_s + explain_parameters
44
+ end
45
+
46
+ def explain_parameters()
47
+ '()'
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,16 @@
1
+ require_relative "expectation"
2
+ require "validates_email_format_of"
3
+
4
+ module CabezaDeTermo
5
+ module JsonSpec
6
+ class IsEmailExpectation < Expectation
7
+ def is_satisfied_by?(value_holder)
8
+ is_valid_email?(value_holder.value)
9
+ end
10
+
11
+ def is_valid_email?(value)
12
+ ValidatesEmailFormatOf.validate_email_format(value).nil?
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "expectation"
2
+
3
+ module CabezaDeTermo
4
+ module JsonSpec
5
+ class IsScalarExpectation < Expectation
6
+ def is_satisfied_by?(value_holder)
7
+ is_scalar?(value_holder)
8
+ end
9
+
10
+ def is_scalar?(value_holder)
11
+ [::String, ::Numeric, ::TrueClass, ::FalseClass, ::NilClass].any? do |type|
12
+ value_holder.value.kind_of?(type)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ require_relative "expectation"
2
+ require 'uri'
3
+
4
+ module CabezaDeTermo
5
+ module JsonSpec
6
+ class IsUrlExpectation < Expectation
7
+ def is_satisfied_by?(value_holder)
8
+ begin
9
+ is_valid_url?(value_holder.value)
10
+ rescue URI::Error
11
+ false
12
+ end
13
+ end
14
+
15
+ def is_valid_url?(value)
16
+ uri = URI.parse(value)
17
+ !uri.scheme.nil? && !uri.host.nil?
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ require_relative "expectation"
2
+
3
+ module CabezaDeTermo
4
+ module JsonSpec
5
+ class NegatedExpectation < Expectation
6
+ def initialize(expectation)
7
+ super()
8
+
9
+ @negated_expectation = expectation
10
+ end
11
+
12
+ def negated_expectation()
13
+ @negated_expectation
14
+ end
15
+
16
+ def is_satisfied_by?(value_holder)
17
+ !negated_expectation.is_satisfied_by?(value_holder)
18
+ end
19
+
20
+ def failed_message_on(value_holder)
21
+ failed_message_block.message_on(negated_expectation, value_holder)
22
+ end
23
+
24
+ # Explaining
25
+
26
+ def explain()
27
+ expectation_method.to_s + negated_expectation.explain_parameters
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ module CabezaDeTermo
2
+ module JsonSpec
3
+ class AbstractExpectationsRunner
4
+ # Adding
5
+
6
+ def add(expectation)
7
+ raise 'Subclass responsibility'
8
+ end
9
+
10
+ # Walking
11
+
12
+ def accept_walker(expression_walker)
13
+ raise 'Subclass responsibility'
14
+ end
15
+
16
+ def accept_walker_with_value_holder(expression_walker, value_holder)
17
+ raise 'Subclass responsibility'
18
+ end
19
+
20
+ # Explaining
21
+
22
+ def explain_with(expression_walker)
23
+ raise 'Subclass responsibility'
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,50 @@
1
+ require_relative 'abstract-expectations-runner'
2
+ require 'cabeza-de-termo/json-spec/signals/skip-branch-signal'
3
+
4
+ module CabezaDeTermo
5
+ module JsonSpec
6
+ class CanBeAbsentExpectationsRunner < AbstractExpectationsRunner
7
+ def initialize(expectations_runner)
8
+ @underlaying_runner = expectations_runner
9
+ end
10
+
11
+ # Accessing
12
+
13
+ def underlaying_runner
14
+ @underlaying_runner
15
+ end
16
+
17
+ # Adding
18
+
19
+ def add(expectation)
20
+ underlaying_runner.add(expectation)
21
+ end
22
+
23
+ # Walking
24
+
25
+ def accept_walker(expression_walker)
26
+ expression_walker.walk_expectation_runner(self)
27
+ end
28
+
29
+ def accept_walker_with_value_holder(expression_walker, value_holder)
30
+ raise SkipBranchSignal.new if value_holder.is_missing_value?
31
+
32
+ underlaying_runner.accept_walker_with_value_holder(expression_walker, value_holder)
33
+ end
34
+
35
+ #
36
+ # Yes, this sucks. But I got kind of tired of this library and want to move on
37
+ # to something else.
38
+ #
39
+ def explain_with(expression_walker)
40
+ expression_walker.during_tab do
41
+ expression_walker.append_in_new_line('if present')
42
+ expression_walker.cr
43
+ expression_walker.append_tabs
44
+
45
+ underlaying_runner.explain_with(expression_walker)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,48 @@
1
+ require_relative 'abstract-expectations-runner'
2
+ require 'cabeza-de-termo/json-spec/signals/skip-branch-signal'
3
+
4
+ module CabezaDeTermo
5
+ module JsonSpec
6
+ class CanBeNullExpectationsRunner < AbstractExpectationsRunner
7
+ def initialize(expectations_runner)
8
+ @underlaying_runner = expectations_runner
9
+ end
10
+
11
+ # Accessing
12
+
13
+ def underlaying_runner
14
+ @underlaying_runner
15
+ end
16
+
17
+ # Adding
18
+
19
+ def add(expectation)
20
+ underlaying_runner.add(expectation)
21
+ end
22
+
23
+ # Walking
24
+
25
+ def accept_walker(expression_walker)
26
+ expression_walker.walk_expectation_runner(self)
27
+ end
28
+
29
+ def accept_walker_with_value_holder(expression_walker, value_holder)
30
+ raise SkipBranchSignal.new if value_holder.value.nil?
31
+
32
+ underlaying_runner.accept_walker_with_value_holder(expression_walker, value_holder)
33
+ end
34
+
35
+ # Explaining
36
+
37
+ def explain_with(expression_walker)
38
+ expression_walker.during_tab do
39
+ expression_walker.append_in_new_line('if not null')
40
+ expression_walker.cr
41
+ expression_walker.append_tabs
42
+
43
+ underlaying_runner.explain_with(expression_walker)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end