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