yaks 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +158 -56
  3. data/Rakefile +1 -3
  4. data/ataru_setup.rb +72 -0
  5. data/find_missing_tests.rb +34 -0
  6. data/lib/yaks.rb +8 -10
  7. data/lib/yaks/breaking_changes.rb +4 -6
  8. data/lib/yaks/builder.rb +1 -1
  9. data/lib/yaks/changelog.rb +1 -1
  10. data/lib/yaks/collection_mapper.rb +8 -5
  11. data/lib/yaks/collection_resource.rb +0 -1
  12. data/lib/yaks/config.rb +17 -7
  13. data/lib/yaks/configurable.rb +20 -14
  14. data/lib/yaks/default_policy.rb +82 -33
  15. data/lib/yaks/format.rb +7 -3
  16. data/lib/yaks/format/collection_json.rb +4 -4
  17. data/lib/yaks/format/hal.rb +1 -2
  18. data/lib/yaks/format/halo.rb +2 -4
  19. data/lib/yaks/format/json_api.rb +46 -27
  20. data/lib/yaks/html5_forms.rb +0 -2
  21. data/lib/yaks/mapper.rb +5 -5
  22. data/lib/yaks/mapper/association.rb +7 -7
  23. data/lib/yaks/mapper/association_mapper.rb +2 -0
  24. data/lib/yaks/mapper/attribute.rb +10 -4
  25. data/lib/yaks/mapper/config.rb +2 -2
  26. data/lib/yaks/mapper/form.rb +4 -10
  27. data/lib/yaks/mapper/form/config.rb +16 -17
  28. data/lib/yaks/mapper/form/dynamic_field.rb +1 -1
  29. data/lib/yaks/mapper/form/field.rb +16 -7
  30. data/lib/yaks/mapper/form/field/option.rb +5 -4
  31. data/lib/yaks/mapper/form/fieldset.rb +1 -1
  32. data/lib/yaks/mapper/form/legend.rb +18 -0
  33. data/lib/yaks/mapper/has_many.rb +1 -0
  34. data/lib/yaks/mapper/link.rb +7 -4
  35. data/lib/yaks/null_resource.rb +4 -5
  36. data/lib/yaks/pipeline.rb +2 -2
  37. data/lib/yaks/primitivize.rb +3 -2
  38. data/lib/yaks/reader/hal.rb +12 -13
  39. data/lib/yaks/reader/json_api.rb +50 -33
  40. data/lib/yaks/resource.rb +6 -7
  41. data/lib/yaks/resource/form.rb +2 -12
  42. data/lib/yaks/resource/form/field.rb +4 -3
  43. data/lib/yaks/resource/form/field/option.rb +1 -1
  44. data/lib/yaks/resource/form/fieldset.rb +1 -1
  45. data/lib/yaks/resource/form/legend.rb +18 -0
  46. data/lib/yaks/resource/has_fields.rb +13 -7
  47. data/lib/yaks/resource/link.rb +1 -1
  48. data/lib/yaks/runner.rb +5 -2
  49. data/lib/yaks/serializer.rb +2 -3
  50. data/lib/yaks/util.rb +7 -8
  51. data/lib/yaks/version.rb +1 -1
  52. data/spec/acceptance/acceptance_spec.rb +53 -38
  53. data/spec/acceptance/json_shared_examples.rb +45 -12
  54. data/spec/acceptance/models.rb +1 -1
  55. data/spec/integration/dynamic_form_fields_spec.rb +0 -1
  56. data/spec/integration/fieldset_spec.rb +18 -20
  57. data/spec/integration/map_to_resource_spec.rb +6 -6
  58. data/spec/json/{confucius.collection.json → confucius.collection_json.json} +0 -0
  59. data/spec/json/confucius.json_api.json +43 -27
  60. data/spec/json/list_of_quotes.collection_json.json +43 -0
  61. data/spec/json/list_of_quotes.hal.json +18 -0
  62. data/spec/json/list_of_quotes.json_api.json +25 -0
  63. data/spec/json/youtypeitwepostit.collection_json.json +45 -0
  64. data/spec/spec_helper.rb +4 -3
  65. data/spec/support/classes_for_policy_testing.rb +38 -14
  66. data/spec/support/deep_eql.rb +21 -18
  67. data/spec/support/pet_mapper.rb +2 -0
  68. data/spec/support/shared_contexts.rb +9 -9
  69. data/spec/unit/yaks/builder_spec.rb +41 -18
  70. data/spec/unit/yaks/collection_mapper_spec.rb +22 -19
  71. data/spec/unit/yaks/collection_resource_spec.rb +16 -8
  72. data/spec/unit/yaks/config_spec.rb +215 -19
  73. data/spec/unit/yaks/configurable_spec.rb +66 -7
  74. data/spec/unit/yaks/default_policy/derive_mapper_from_collection_spec.rb +47 -0
  75. data/spec/unit/yaks/default_policy/derive_mapper_from_item_spec.rb +114 -0
  76. data/spec/unit/yaks/default_policy/derive_mapper_from_object_spec.rb +29 -71
  77. data/spec/unit/yaks/default_policy_spec.rb +4 -5
  78. data/spec/unit/yaks/format/collection_json_spec.rb +35 -36
  79. data/spec/unit/yaks/format/hal_spec.rb +3 -3
  80. data/spec/unit/yaks/format/json_api_spec.rb +109 -68
  81. data/spec/unit/yaks/format_spec.rb +34 -0
  82. data/spec/unit/yaks/fp/callable_spec.rb +5 -3
  83. data/spec/unit/yaks/mapper/association_mapper_spec.rb +22 -4
  84. data/spec/unit/yaks/mapper/association_spec.rb +23 -11
  85. data/spec/unit/yaks/mapper/attribute_spec.rb +46 -7
  86. data/spec/unit/yaks/mapper/config_spec.rb +2 -3
  87. data/spec/unit/yaks/mapper/form/config_spec.rb +95 -0
  88. data/spec/unit/yaks/mapper/form/dynamic_field_spec.rb +30 -0
  89. data/spec/unit/yaks/mapper/form/field/option_spec.rb +48 -4
  90. data/spec/unit/yaks/mapper/form/field_spec.rb +43 -2
  91. data/spec/unit/yaks/mapper/form/fieldset_spec.rb +67 -8
  92. data/spec/unit/yaks/mapper/form/legend_spec.rb +52 -0
  93. data/spec/unit/yaks/mapper/form_spec.rb +84 -23
  94. data/spec/unit/yaks/mapper/has_many_spec.rb +39 -36
  95. data/spec/unit/yaks/mapper/has_one_spec.rb +28 -20
  96. data/spec/unit/yaks/mapper/link_spec.rb +68 -16
  97. data/spec/unit/yaks/mapper_spec.rb +118 -30
  98. data/spec/unit/yaks/null_resource_spec.rb +83 -52
  99. data/spec/unit/yaks/pipeline_spec.rb +101 -74
  100. data/spec/unit/yaks/primitivize_spec.rb +25 -6
  101. data/spec/unit/yaks/resource/form/field_spec.rb +5 -5
  102. data/spec/unit/yaks/resource/form/fieldset_spec.rb +7 -0
  103. data/spec/unit/yaks/resource/form/legend_spec.rb +8 -0
  104. data/spec/unit/yaks/resource/form_spec.rb +17 -37
  105. data/spec/unit/yaks/resource/has_fields_spec.rb +44 -3
  106. data/spec/unit/yaks/resource/link_spec.rb +11 -6
  107. data/spec/unit/yaks/resource_spec.rb +87 -98
  108. data/spec/unit/yaks/runner_spec.rb +112 -28
  109. data/spec/unit/yaks/serializer_spec.rb +1 -1
  110. data/spec/unit/yaks/util_spec.rb +30 -10
  111. data/spec/yaml/list_of_quotes.yaml +13 -0
  112. data/yaks.gemspec +21 -13
  113. metadata +129 -41
  114. data/lib/yaks/attributes.rb +0 -86
  115. data/lib/yaks/fp.rb +0 -26
  116. data/lib/yaks/identifier/link_relation.rb +0 -17
  117. data/resources/iana-link-relations.csv +0 -152
  118. data/spec/json/youtypeitwepostit.collection.json +0 -45
  119. data/spec/unit/yaks/attributes_spec.rb +0 -178
  120. data/spec/unit/yaks/fp_spec.rb +0 -29
@@ -13,7 +13,7 @@ RSpec.describe 'Mapping domain models to Resource objects' do
13
13
  specify {
14
14
  subject.subresources == [
15
15
  Yaks::Resource.new(
16
- type:'pet_peeve',
16
+ type: 'pet_peeve',
17
17
  rels: ['rel:pet_peeve'],
18
18
  attributes: {id: 4, type: 'parsing with regexps'}
19
19
  ),
@@ -23,11 +23,11 @@ RSpec.describe 'Mapping domain models to Resource objects' do
23
23
  members: [
24
24
  Yaks::Resource.new(
25
25
  type: 'pet',
26
- attributes: {:id => 2, :species => 'dog', :name => 'boingboing'}
26
+ attributes: {id: 2, species: 'dog', name: 'boingboing'}
27
27
  ),
28
28
  Yaks::Resource.new(
29
29
  type: 'pet',
30
- attributes: {:id => 3, :species => 'cat', :name => 'wassup'}
30
+ attributes: {id: 3, species: 'cat', name: 'wassup'}
31
31
  )
32
32
  ]
33
33
  )
@@ -38,7 +38,7 @@ RSpec.describe 'Mapping domain models to Resource objects' do
38
38
  should eq(
39
39
  [
40
40
  Yaks::Resource.new(
41
- type:'pet_peeve',
41
+ type: 'pet_peeve',
42
42
  rels: ['rel:pet_peeve'],
43
43
  attributes: {id: 4, type: 'parsing with regexps'}
44
44
  ),
@@ -48,11 +48,11 @@ RSpec.describe 'Mapping domain models to Resource objects' do
48
48
  members: [
49
49
  Yaks::Resource.new(
50
50
  type: 'pet',
51
- attributes: {:id => 2, :species => 'dog', :name => 'boingboing'}
51
+ attributes: {id: 2, species: 'dog', name: 'boingboing'}
52
52
  ),
53
53
  Yaks::Resource.new(
54
54
  type: 'pet',
55
- attributes: {:id => 3, :species => 'cat', :name => 'wassup'}
55
+ attributes: {id: 3, species: 'cat', name: 'wassup'}
56
56
  )
57
57
  ]
58
58
  )
@@ -1,50 +1,66 @@
1
1
  {
2
- "data": [
3
- {
4
- "id": 9,
5
- "type": "scholars",
6
- "href": "http://literature.example.com/authors/kongzi",
2
+ "data": {
3
+ "id": "9",
4
+ "type": "scholars",
5
+ "attributes": {
7
6
  "name": "孔子",
8
7
  "pinyin": "Kongzi",
9
- "latinized": "Confucius",
10
- "links": {
11
- "works": {"type": "works", "ids": [11,12]}
12
- }
8
+ "latinized": "Confucius"
9
+ },
10
+ "links": {
11
+ "profile": "http://literature.example.com/profiles/scholar",
12
+ "self": "http://literature.example.com/authors/kongzi",
13
+ "http://literature.example.com/rels/quotes": "http://literature.example.com/quotes/?author=kongzi&q={query}",
14
+ "works": {"linkage": [{"type": "works", "id": "11"}, {"type": "works", "id": "12"}]}
13
15
  }
14
- ],
15
- "linked": [
16
+ },
17
+ "included": [
16
18
  {
17
- "id": 11,
19
+ "id": "11",
18
20
  "type": "works",
19
- "href": "http://literature.example.com/work/11",
20
- "chinese_name": "論語",
21
- "english_name": "Analects",
21
+ "attributes": {
22
+ "chinese_name": "論語",
23
+ "english_name": "Analects"
24
+ },
22
25
  "links": {
23
- "quotes": {"type": "quotes", "ids": [17, 18]},
24
- "era": {"type": "erae", "id": 99}
26
+ "profile": "http://literature.example.com/profiles/work",
27
+ "self": "http://literature.example.com/work/11",
28
+ "quotes": {"linkage": [{"type": "quotes", "id": "17"}, {"type": "quotes", "id": "18"}]},
29
+ "era": {"linkage": {"type": "erae", "id": "99"}}
25
30
  }
26
31
  },
27
32
  {
28
- "id": 17,
33
+ "id": "17",
29
34
  "type": "quotes",
30
- "chinese": "廄焚。子退朝,曰:“傷人乎?” 不問馬。"
35
+ "attributes": {
36
+ "chinese": "廄焚。子退朝,曰:“傷人乎?” 不問馬。"
37
+ }
31
38
  },
32
39
  {
33
- "id": 18,
40
+ "id": "18",
34
41
  "type": "quotes",
35
- "chinese": "子曰:“其恕乎!己所不欲、勿施於人。”"
42
+ "attributes": {
43
+ "chinese": "子曰:“其恕乎!己所不欲、勿施於人。”"
44
+ }
36
45
  },
37
46
  {
38
- "id": 99,
47
+ "id": "99",
39
48
  "type": "erae",
40
- "name": "Zhou Dynasty"
49
+ "attributes": {
50
+ "name": "Zhou Dynasty"
51
+ }
41
52
  },
42
53
  {
43
- "id": 12,
54
+ "id": "12",
44
55
  "type": "works",
45
- "href": "http://literature.example.com/work/12",
46
- "chinese_name": "易經",
47
- "english_name": "Commentaries to the Yi-jing"
56
+ "attributes": {
57
+ "chinese_name": "易經",
58
+ "english_name": "Commentaries to the Yi-jing"
59
+ },
60
+ "links": {
61
+ "profile": "http://literature.example.com/profiles/work",
62
+ "self": "http://literature.example.com/work/12"
63
+ }
48
64
  }
49
65
  ]
50
66
  }
@@ -0,0 +1,43 @@
1
+ {
2
+ "collection": {
3
+ "version": "1.0",
4
+ "items": [
5
+ {
6
+ "data": [
7
+ {
8
+ "name": "id",
9
+ "value": 17
10
+ },
11
+ {
12
+ "name": "chinese",
13
+ "value": "廄焚。子退朝,曰:“傷人乎?” 不問馬。"
14
+ }
15
+ ]
16
+ },
17
+ {
18
+ "data": [
19
+ {
20
+ "name": "id",
21
+ "value": 18
22
+ },
23
+ {
24
+ "name": "chinese",
25
+ "value": "子曰:“其恕乎!己所不欲、勿施於人。”"
26
+ }
27
+ ]
28
+ },
29
+ {
30
+ "data": [
31
+ {
32
+ "name": "id",
33
+ "value": 99
34
+ },
35
+ {
36
+ "name": "chinese",
37
+ "value": null
38
+ }
39
+ ]
40
+ }
41
+ ]
42
+ }
43
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "_embedded": {
3
+ "rel:quotes": [
4
+ {
5
+ "id": 17,
6
+ "chinese": "廄焚。子退朝,曰:“傷人乎?” 不問馬。"
7
+ },
8
+ {
9
+ "id": 18,
10
+ "chinese": "子曰:“其恕乎!己所不欲、勿施於人。”"
11
+ },
12
+ {
13
+ "id": 99,
14
+ "chinese": null
15
+ }
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "data": [
3
+ {
4
+ "type": "quotes",
5
+ "id": "17",
6
+ "attributes": {
7
+ "chinese": "廄焚。子退朝,曰:“傷人乎?” 不問馬。"
8
+ }
9
+ },
10
+ {
11
+ "type": "quotes",
12
+ "id": "18",
13
+ "attributes": {
14
+ "chinese": "子曰:“其恕乎!己所不欲、勿施於人。”"
15
+ }
16
+ },
17
+ {
18
+ "type": "quotes",
19
+ "id": "99",
20
+ "attributes": {
21
+ "chinese": null
22
+ }
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "collection": {
3
+ "version": "1.0",
4
+ "href": "http://www.youtypeitwepostit.com/api/",
5
+
6
+ "links": [
7
+ { "rel": "self", "href": "http://www.youtypeitwepostit.com/api/" }
8
+ ],
9
+
10
+ "items": [
11
+ {
12
+ "href": "http://www.youtypeitwepostit.com/api/12091295723803341",
13
+ "data": [
14
+ {
15
+ "name": "text",
16
+ "value": "massage"
17
+ },
18
+ {
19
+ "name": "date_posted",
20
+ "value": "2014-05-29T07:56:58.035Z"
21
+ }
22
+ ],
23
+ "links": [
24
+ { "rel": "profile", "href": "http://www.youtypeitwepostit.com/profiles/message" }
25
+ ]
26
+ },
27
+ {
28
+ "href": "http://www.youtypeitwepostit.com/api/613856331910938",
29
+ "data": [
30
+ {
31
+ "name": "text",
32
+ "value": "Squid!"
33
+ },
34
+ {
35
+ "name": "date_posted",
36
+ "value": "2013-03-28T21:51:08.406Z"
37
+ }
38
+ ],
39
+ "links": [
40
+ { "rel": "profile", "href": "http://www.youtypeitwepostit.com/profiles/message" }
41
+ ]
42
+ }
43
+ ]
44
+ }
45
+ }
data/spec/spec_helper.rb CHANGED
@@ -18,14 +18,15 @@ require_relative 'support/youtypeit_models_mappers'
18
18
  require_relative 'support/deep_eql'
19
19
  require_relative 'support/classes_for_policy_testing'
20
20
 
21
-
22
21
  RSpec.configure do |rspec|
23
22
  rspec.include FixtureHelpers
24
23
  rspec.backtrace_exclusion_patterns = [] if ENV['FULLSTACK']
25
24
  rspec.disable_monkey_patching!
26
25
  rspec.raise_errors_for_deprecations!
27
- rspec.around(:each) do |example|
28
- Timeout.timeout(1, &example)
26
+ if defined?(Mutant)
27
+ rspec.around(:each) do |example|
28
+ Timeout.timeout(1, &example)
29
+ end
29
30
  end
30
31
  end
31
32
 
@@ -1,34 +1,58 @@
1
1
  # Used by Yaks::DefaultPolicy* tests to test various name inference schemes
2
2
 
3
- class SoyMapper ; end
4
- class Bean ; end
5
- class Soy < Bean; end
6
- class Wheat ; end
3
+ class SoyMapper; end
4
+ class Soy; end
5
+ class WildSoy < Soy; end
6
+
7
+ module Grain
8
+ class Soy; end
9
+ class WildSoy < Soy; end
10
+
11
+ class Wheat; end
12
+ class Durum < Wheat; end
13
+
14
+ module Dry
15
+ class Soy < ::Grain::Soy; end
16
+ class SoyMapper; end
17
+ end
18
+
19
+ class SoyMapper; end
20
+ class SoyCollectionMapper; end
21
+ end
22
+
23
+ class HomeMapper; end
24
+ class WheatMapper; end
25
+ class ObjectMapper; end
26
+ class BasicObjectMapper; end
7
27
 
8
28
  module MyMappers
9
- class SoyMapper ; end
10
- class BeanMapper ; end
29
+ class SoyMapper; end
30
+ class WheatMapper; end
31
+
32
+ module Grain
33
+ class SoyMapper; end
34
+ end
11
35
  end
12
36
 
13
- class SoyCollectionMapper ; end
37
+ class SoyCollectionMapper; end
14
38
 
15
39
  module Namespace
16
40
  module Nested
17
- class Rye ; end
18
- class Mung < Bean
19
- alias inspect to_s # on 1.9 inspect calls to_s
41
+ class Rye; end
42
+ class Mung
43
+ alias_method :inspect, :to_s # on 1.9 inspect calls to_s
20
44
  def to_s
21
45
  "mungbean"
22
46
  end
23
47
  end
24
48
  end
25
49
 
26
- class RyeMapper ; end
27
- class RyeCollectionMapper ; end
50
+ class RyeMapper; end
51
+ class RyeCollectionMapper; end
28
52
 
29
- class CollectionMapper ; end
53
+ class CollectionMapper; end
30
54
 
31
- class ShoeMapper ; end
55
+ class ShoeMapper; end
32
56
  end
33
57
 
34
58
  module DislikesCollectionMapper
@@ -25,7 +25,9 @@ module Matchers
25
25
  end
26
26
 
27
27
  def recurse(target, expectation)
28
- @result &&= DeepEql.new(expectation, stack, diffs).matches?(target)
28
+ # leave this in two lines so it doesn't short circuit
29
+ result = DeepEql.new(expectation, stack, diffs).matches?(target)
30
+ @result &&= result
29
31
  end
30
32
 
31
33
  def stack_as_jsonpath
@@ -51,14 +53,14 @@ module Matchers
51
53
  recurse(target[key], expectation[key])
52
54
  else
53
55
  add_failure_message begin
54
- if expectation[key].class == target[key].class
55
- "expected #{expectation[key].inspect}, got #{target[key].inspect}"
56
- else
57
- "expected #{expectation[key].class}: #{expectation[key].inspect}, got #{target[key].class}: #{target[key].inspect}"
58
- end
59
- rescue Encoding::CompatibilityError
60
- "expected #{expectation[key].encoding}, got #{target[key].encoding}"
61
- end
56
+ if expectation[key].class == target[key].class
57
+ "expected #{expectation[key].inspect}, got #{target[key].inspect}"
58
+ else
59
+ "expected #{expectation[key].class}: #{expectation[key].inspect}, got #{target[key].class}: #{target[key].inspect}"
60
+ end
61
+ rescue Encoding::CompatibilityError
62
+ "expected #{expectation[key].encoding}, got #{target[key].encoding}"
63
+ end
62
64
  end
63
65
  end
64
66
  pop
@@ -66,7 +68,6 @@ module Matchers
66
68
 
67
69
  def matches?(target)
68
70
  @target = target
69
-
70
71
  case expectation
71
72
  when Hash
72
73
  if target.is_a?(Hash)
@@ -74,12 +75,12 @@ module Matchers
74
75
  add_failure_message("expected #{expectation.class}, got #{target.class}")
75
76
  end
76
77
  (expectation.keys - target.keys).each do |key|
77
- add_failure_message "Expected key #{key}"
78
+ add_failure_message "Expected key #{key.inspect} => #{expectation[key].inspect}"
78
79
  end
79
80
  (target.keys - expectation.keys).each do |key|
80
- add_failure_message "Unexpected key #{key}"
81
+ add_failure_message "Unexpected key #{key.inspect} => #{target[key].inspect}"
81
82
  end
82
- (target.keys | expectation.keys).each do |key|
83
+ (target.keys & expectation.keys).each do |key|
83
84
  compare key
84
85
  end
85
86
  else
@@ -107,17 +108,19 @@ module Matchers
107
108
  def failure_message_for_should
108
109
  diffs.join("\n")
109
110
  end
110
- alias failure_message failure_message_for_should
111
+ alias_method :failure_message, :failure_message_for_should
111
112
 
112
113
  def failure_message_for_should_not
113
114
  "expected #{@target.inspect} not to be in deep_eql with #{@expectation.inspect}"
114
115
  end
115
- alias failure_message_when_negated failure_message_for_should_not
116
+ alias_method :failure_message_when_negated, :failure_message_for_should_not
116
117
  end
117
118
  end
118
119
 
119
- module RSpec::Matchers
120
- def deep_eql(exp)
121
- Matchers::DeepEql.new(exp)
120
+ module RSpec
121
+ module Matchers
122
+ def deep_eql(exp)
123
+ ::Matchers::DeepEql.new(exp)
124
+ end
122
125
  end
123
126
  end