jat 0.0.5 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jat/attribute.rb +5 -16
  3. data/lib/jat/config.rb +4 -7
  4. data/lib/jat/plugins/activerecord/activerecord.rb +23 -0
  5. data/lib/jat/plugins/{_activerecord_preloads/_activerecord_preloads.rb → base/base_activerecord_preloads/base_activerecord_preloads.rb} +7 -2
  6. data/lib/jat/plugins/{_activerecord_preloads → base/base_activerecord_preloads}/lib/preloader.rb +16 -4
  7. data/lib/jat/plugins/{_lower_camel_case/_lower_camel_case.rb → base/base_lower_camel_case/base_lower_camel_case.rb} +6 -2
  8. data/lib/jat/plugins/{_preloads/_preloads.rb → base/base_preloads/base_preloads.rb} +6 -2
  9. data/lib/jat/plugins/{_preloads → base/base_preloads}/lib/format_user_preloads.rb +1 -1
  10. data/lib/jat/plugins/{_preloads → base/base_preloads}/lib/preloads_with_path.rb +1 -1
  11. data/lib/jat/plugins/cache/cache.rb +5 -1
  12. data/lib/jat/plugins/json_api/json_api.rb +7 -3
  13. data/lib/jat/plugins/json_api/lib/map.rb +4 -5
  14. data/lib/jat/plugins/json_api/lib/response.rb +1 -5
  15. data/lib/jat/plugins/json_api/lib/response_piece.rb +19 -10
  16. data/lib/jat/plugins/json_api/plugins/json_api_activerecord/json_api_activerecord.rb +23 -0
  17. data/lib/jat/plugins/{json_api_lower_camel_case → json_api/plugins/json_api_lower_camel_case}/json_api_lower_camel_case.rb +6 -2
  18. data/lib/jat/plugins/{json_api_maps_cache → json_api/plugins/json_api_maps_cache}/json_api_maps_cache.rb +5 -1
  19. data/lib/jat/plugins/json_api/plugins/json_api_preloads/json_api_preloads.rb +38 -0
  20. data/lib/jat/plugins/{json_api_activerecord → json_api/plugins/json_api_preloads}/lib/preloads.rb +1 -1
  21. data/lib/jat/plugins/{json_api_validate_params → json_api/plugins/json_api_validate_params}/json_api_validate_params.rb +5 -1
  22. data/lib/jat/plugins/{json_api_validate_params → json_api/plugins/json_api_validate_params}/lib/params_error.rb +0 -0
  23. data/lib/jat/plugins/{json_api_validate_params → json_api/plugins/json_api_validate_params}/lib/validate_fields_param.rb +0 -0
  24. data/lib/jat/plugins/{json_api_validate_params → json_api/plugins/json_api_validate_params}/lib/validate_include_param.rb +1 -3
  25. data/lib/jat/plugins/lower_camel_case/lower_camel_case.rb +23 -0
  26. data/lib/jat/plugins/maps_cache/maps_cache.rb +23 -0
  27. data/lib/jat/plugins/preloads/preloads.rb +23 -0
  28. data/lib/jat/plugins/simple_api/lib/fields_param_parser.rb +20 -36
  29. data/lib/jat/plugins/simple_api/lib/map.rb +4 -5
  30. data/lib/jat/plugins/simple_api/lib/response.rb +1 -5
  31. data/lib/jat/plugins/simple_api/lib/response_piece.rb +1 -5
  32. data/lib/jat/plugins/simple_api/plugins/simple_api_activerecord/simple_api_activerecord.rb +23 -0
  33. data/lib/jat/plugins/{simple_api_lower_camel_case → simple_api/plugins/simple_api_lower_camel_case}/simple_api_lower_camel_case.rb +6 -2
  34. data/lib/jat/plugins/{simple_api_maps_cache → simple_api/plugins/simple_api_maps_cache}/simple_api_maps_cache.rb +6 -4
  35. data/lib/jat/plugins/{simple_api_activerecord → simple_api/plugins/simple_api_preloads}/lib/preloads.rb +1 -1
  36. data/lib/jat/plugins/simple_api/plugins/simple_api_preloads/simple_api_preloads.rb +38 -0
  37. data/lib/jat/plugins/{simple_api_validate_params → simple_api/plugins/simple_api_validate_params}/lib/fields_error.rb +0 -0
  38. data/lib/jat/plugins/{simple_api_validate_params → simple_api/plugins/simple_api_validate_params}/lib/validate_fields_param.rb +0 -0
  39. data/lib/jat/plugins/{simple_api_validate_params → simple_api/plugins/simple_api_validate_params}/simple_api_validate_params.rb +6 -2
  40. data/lib/jat/plugins/simple_api/simple_api.rb +8 -7
  41. data/lib/jat/plugins/to_str/to_str.rb +5 -1
  42. data/lib/jat/plugins/types/types.rb +55 -0
  43. data/lib/jat/plugins/validate_params/validate_params.rb +23 -0
  44. data/lib/jat/plugins.rb +41 -15
  45. data/lib/jat.rb +24 -17
  46. data/test/lib/jat/attribute_test.rb +8 -0
  47. data/test/lib/jat/plugins/activerecord/activerecord_test.rb +27 -0
  48. data/test/lib/jat/plugins/{_activerecord_preloads/_activerecord_preloads_test.rb → base_activerecord_preloads/base_activerecord_preloads_test.rb} +3 -3
  49. data/test/lib/jat/plugins/{_activerecord_preloads → base_activerecord_preloads}/lib/preloader_test.rb +2 -2
  50. data/test/lib/jat/plugins/{_camel_lower/_camel_lower_test.rb → base_lower_camel_case/base_lower_camel_case_test.rb} +2 -2
  51. data/test/lib/jat/plugins/{_preloads/_preloads_test.rb → base_preloads/base_preloads_test.rb} +2 -2
  52. data/test/lib/jat/plugins/{_preloads → base_preloads}/lib/format_user_preloads_test.rb +3 -3
  53. data/test/lib/jat/plugins/{_preloads → base_preloads}/lib/preloads_with_path_test.rb +2 -2
  54. data/test/lib/jat/plugins/json_api/json_api_test.rb +1 -9
  55. data/test/lib/jat/plugins/json_api/lib/fields_param_parser_test.rb +20 -12
  56. data/test/lib/jat/plugins/json_api/lib/include_param_parser_test.rb +25 -11
  57. data/test/lib/jat/plugins/json_api/lib/map_test.rb +132 -124
  58. data/test/lib/jat/plugins/json_api/lib/response_piece_test.rb +13 -0
  59. data/test/lib/jat/plugins/json_api/lib/response_test.rb +6 -1
  60. data/test/lib/jat/plugins/json_api_activerecord/json_api_activerecord_test.rb +4 -18
  61. data/test/lib/jat/plugins/{json_api_camel_lower/json_api_camel_lower_test.rb → json_api_lower_camel_case/json_api_lower_camel_case_test.rb} +6 -0
  62. data/test/lib/jat/plugins/json_api_preloads/json_api_preloads_test.rb +51 -0
  63. data/test/lib/jat/plugins/{json_api_activerecord → json_api_preloads}/lib/preloads_test.rb +8 -6
  64. data/test/lib/jat/plugins/json_api_validate_params/json_api_validate_params_test.rb +30 -6
  65. data/test/lib/jat/plugins/lower_camel_case/lower_camel_case_test.rb +27 -0
  66. data/test/lib/jat/plugins/maps_cache/maps_cache_test.rb +27 -0
  67. data/test/lib/jat/plugins/preloads/preloads_test.rb +27 -0
  68. data/test/lib/jat/plugins/simple_api/lib/fields_param_parser_test.rb +57 -43
  69. data/test/lib/jat/plugins/simple_api/lib/map_test.rb +90 -82
  70. data/test/lib/jat/plugins/simple_api/lib/response_piece_test.rb +13 -0
  71. data/test/lib/jat/plugins/simple_api/lib/response_test.rb +18 -12
  72. data/test/lib/jat/plugins/simple_api/simple_api_test.rb +33 -6
  73. data/test/lib/jat/plugins/simple_api_activerecord/simple_api_activerecord_test.rb +4 -18
  74. data/test/lib/jat/plugins/{simple_api_camel_lower/simple_api_camel_lower_test.rb → simple_api_lower_camel_case/simple_api_lower_camel_case_test.rb} +7 -1
  75. data/test/lib/jat/plugins/{simple_api_activerecord → simple_api_preloads}/lib/preloads_test.rb +8 -8
  76. data/test/lib/jat/plugins/simple_api_preloads/simple_api_preloads_test.rb +51 -0
  77. data/test/lib/jat/plugins/simple_api_validate_params/simple_api_validate_params_test.rb +12 -0
  78. data/test/lib/jat/plugins/types/types_test.rb +83 -0
  79. data/test/lib/jat/plugins/validate_params/validate_params_test.rb +27 -0
  80. data/test/lib/jat/plugins_test.rb +88 -0
  81. data/test/test_helper.rb +8 -4
  82. metadata +98 -82
  83. data/lib/jat/plugins/json_api_activerecord/json_api_activerecord.rb +0 -31
  84. data/lib/jat/plugins/simple_api_activerecord/simple_api_activerecord.rb +0 -31
@@ -18,7 +18,7 @@ class Jat
18
18
  def parse(fields)
19
19
  return FROZEN_EMPTY_HASH unless fields
20
20
 
21
- new(fields).parse
21
+ new.parse(fields)
22
22
  end
23
23
  end
24
24
 
@@ -27,65 +27,49 @@ class Jat
27
27
  OPEN_BRACKET = "("
28
28
  CLOSE_BRACKET = ")"
29
29
 
30
- def initialize(fields)
31
- @fields = fields
32
- end
33
-
34
30
  # user => { user: {} }
35
31
  # user(id) => { user: { id: {} } }
36
32
  # user(id,name) => { user: { id: {}, name: {} } }
37
33
  # user,comments => { user: {}, comments: {} }
38
34
  # user(comments(text)) => { user: { comments: { text: {} } } }
39
- def parse
40
- current_attr = nil
35
+ def parse(fields)
36
+ res = {}
37
+ attribute = +""
38
+ path_stack = nil
41
39
 
42
40
  fields.each_char do |char|
43
41
  case char
44
42
  when COMMA
45
- next unless current_attr
46
-
47
- add_attribute(current_attr)
48
- current_attr = nil
43
+ add_attribute(res, path_stack, attribute, FROZEN_EMPTY_HASH)
49
44
  when CLOSE_BRACKET
50
- if current_attr
51
- add_attribute(current_attr)
52
- current_attr = nil
53
- end
54
-
55
- route.pop
45
+ add_attribute(res, path_stack, attribute, FROZEN_EMPTY_HASH)
46
+ path_stack&.pop
56
47
  when OPEN_BRACKET
57
- next unless current_attr
58
-
59
- attribute_name = add_attribute(current_attr, {})
60
- route << attribute_name
61
- current_attr = nil
48
+ name = add_attribute(res, path_stack, attribute, {})
49
+ (path_stack ||= []).push(name) if name
62
50
  else
63
- current_attr = current_attr ? current_attr.insert(-1, char) : char
51
+ attribute.insert(-1, char)
64
52
  end
65
53
  end
66
54
 
67
- add_attribute(current_attr) if current_attr
55
+ add_attribute(res, path_stack, attribute, FROZEN_EMPTY_HASH)
68
56
 
69
57
  res
70
58
  end
71
59
 
72
60
  private
73
61
 
74
- attr_reader :fields
62
+ def add_attribute(res, path_stack, attribute, nested_attributes = FROZEN_EMPTY_HASH)
63
+ attribute.strip!
64
+ return if attribute.empty?
75
65
 
76
- def add_attribute(current_attr, nested_attrs = FROZEN_EMPTY_HASH)
77
- current_resource = route.empty? ? res : res.dig(*route)
78
- attribute_name = current_attr.strip.to_sym
79
- current_resource[attribute_name] = nested_attrs
80
- attribute_name
81
- end
66
+ name = attribute.to_sym
67
+ attribute.clear
82
68
 
83
- def res
84
- @res ||= {}
85
- end
69
+ current_attrs = !path_stack || path_stack.empty? ? res : res.dig(*path_stack)
70
+ current_attrs[name] = nested_attributes
86
71
 
87
- def route
88
- @route ||= []
72
+ name
89
73
  end
90
74
  end
91
75
 
@@ -74,11 +74,10 @@ class Jat
74
74
  private
75
75
 
76
76
  def expose?(attribute, fields)
77
- case exposed
78
- when :all then true
79
- when :none then manually_exposed?(attribute, fields)
80
- else attribute.exposed? || manually_exposed?(attribute, fields)
81
- end
77
+ return true if exposed == :all
78
+ return manually_exposed?(attribute, fields) if exposed == :none
79
+
80
+ attribute.exposed? || manually_exposed?(attribute, fields)
82
81
  end
83
82
 
84
83
  def manually_exposed?(attribute, fields)
@@ -95,7 +95,7 @@ class Jat
95
95
  meta.each do |name, attribute|
96
96
  next if data.key?(name)
97
97
 
98
- value = attribute_value(attribute)
98
+ value = attribute.value(object, context)
99
99
 
100
100
  unless value.nil?
101
101
  data = data.dup if data.equal?(FROZEN_EMPTY_HASH)
@@ -109,10 +109,6 @@ class Jat
109
109
  def context_metadata
110
110
  context[:meta]&.transform_keys(&:to_sym) || FROZEN_EMPTY_HASH
111
111
  end
112
-
113
- def attribute_value(attribute)
114
- attribute.block.call(object, context)
115
- end
116
112
  end
117
113
 
118
114
  extend ClassMethods
@@ -37,7 +37,7 @@ class Jat
37
37
 
38
38
  map.each do |key, inner_map|
39
39
  attribute = jat_class.attributes.fetch(key)
40
- value = attribute_value(attribute)
40
+ value = attribute.value(object, context)
41
41
 
42
42
  result[key] =
43
43
  if attribute.relation?
@@ -56,10 +56,6 @@ class Jat
56
56
 
57
57
  private
58
58
 
59
- def attribute_value(attribute)
60
- attribute.block.call(object, context)
61
- end
62
-
63
59
  def inner_piece(attribute, value, inner_map)
64
60
  serializer = attribute.serializer.call
65
61
  serializer::ResponsePiece.to_h(value, context, inner_map)
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Jat
4
+ module Plugins
5
+ module SimpleApiActiverecord
6
+ def self.plugin_name
7
+ :simple_api_activerecord
8
+ end
9
+
10
+ def self.before_load(jat_class, **_opts)
11
+ return if jat_class.plugin_used?(:simple_api)
12
+ raise Error, "Please load :simple_api plugin first"
13
+ end
14
+
15
+ def self.load(jat_class, **opts)
16
+ jat_class.plugin :simple_api_preloads, **opts
17
+ jat_class.plugin :base_activerecord_preloads, **opts
18
+ end
19
+ end
20
+
21
+ register_plugin(SimpleApiActiverecord.plugin_name, SimpleApiActiverecord)
22
+ end
23
+ end
@@ -3,10 +3,14 @@
3
3
  class Jat
4
4
  module Plugins
5
5
  module SimpleApiLowerCamelCase
6
+ def self.plugin_name
7
+ :simple_api_lower_camel_case
8
+ end
9
+
6
10
  def self.before_load(jat_class, **_opts)
7
11
  raise Error, "Please load :simple_api plugin first" unless jat_class.plugin_used?(:simple_api)
8
12
 
9
- jat_class.plugin :_lower_camel_case
13
+ jat_class.plugin :base_lower_camel_case
10
14
  end
11
15
 
12
16
  def self.load(jat_class, **_opts)
@@ -25,6 +29,6 @@ class Jat
25
29
  end
26
30
  end
27
31
 
28
- register_plugin(:simple_api_lower_camel_case, SimpleApiLowerCamelCase)
32
+ register_plugin(SimpleApiLowerCamelCase.plugin_name, SimpleApiLowerCamelCase)
29
33
  end
30
34
  end
@@ -3,6 +3,10 @@
3
3
  class Jat
4
4
  module Plugins
5
5
  module SimpleApiMapsCache
6
+ def self.plugin_name
7
+ :simple_api_maps_cache
8
+ end
9
+
6
10
  def self.before_load(jat_class, **_opts)
7
11
  return if jat_class.plugin_used?(:simple_api)
8
12
 
@@ -36,13 +40,11 @@ class Jat
36
40
  end
37
41
 
38
42
  def cache_key(exposed, fields)
39
- key = "exposed:#{exposed}:"
40
- key += "fields:#{fields}:" if fields
41
- key
43
+ "exposed:#{exposed}:fields:#{fields}:"
42
44
  end
43
45
  end
44
46
  end
45
47
 
46
- register_plugin(:simple_api_maps_cache, SimpleApiMapsCache)
48
+ register_plugin(SimpleApiMapsCache.plugin_name, SimpleApiMapsCache)
47
49
  end
48
50
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  class Jat
4
4
  module Plugins
5
- module SimpleApiActiverecord
5
+ module SimpleApiPreloads
6
6
  class Preloads
7
7
  module ClassMethods
8
8
  def call(jat)
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./lib/preloads"
4
+
5
+ class Jat
6
+ module Plugins
7
+ module SimpleApiPreloads
8
+ def self.plugin_name
9
+ :simple_api_preloads
10
+ end
11
+
12
+ def self.before_load(jat_class, **opts)
13
+ raise Error, "Please load :simple_api plugin first" unless jat_class.plugin_used?(:simple_api)
14
+
15
+ jat_class.plugin :base_preloads, **opts
16
+ end
17
+
18
+ def self.load(jat_class, **_opts)
19
+ jat_class.extend(ClassMethods)
20
+ jat_class.include(InstanceMethods)
21
+ end
22
+
23
+ module ClassMethods
24
+ def preloads(context = {})
25
+ new(context).preloads
26
+ end
27
+ end
28
+
29
+ module InstanceMethods
30
+ def preloads
31
+ @preloads ||= Preloads.call(self)
32
+ end
33
+ end
34
+ end
35
+
36
+ register_plugin(SimpleApiPreloads.plugin_name, SimpleApiPreloads)
37
+ end
38
+ end
@@ -6,6 +6,10 @@ require_relative "./lib/validate_fields_param"
6
6
  class Jat
7
7
  module Plugins
8
8
  module SimpleApiValidateParams
9
+ def self.plugin_name
10
+ :simple_api_validate_params
11
+ end
12
+
9
13
  def self.before_load(jat_class, **_opts)
10
14
  return if jat_class.plugin_used?(:simple_api)
11
15
  raise Error, "Please load :simple_api plugin first"
@@ -34,12 +38,12 @@ class Jat
34
38
  end
35
39
 
36
40
  module FieldsParamParserMethods
37
- def parse
41
+ def parse(*)
38
42
  super.tap { |result| ValidateFieldsParam.call(self.class.jat_class, result) }
39
43
  end
40
44
  end
41
45
  end
42
46
 
43
- register_plugin(:simple_api_validate_params, SimpleApiValidateParams)
47
+ register_plugin(SimpleApiValidateParams.plugin_name, SimpleApiValidateParams)
44
48
  end
45
49
  end
@@ -8,7 +8,9 @@ require_relative "./lib/response_piece"
8
8
  class Jat
9
9
  module Plugins
10
10
  module SimpleApi
11
- DEFAULT_META_KEY = :meta
11
+ def self.plugin_name
12
+ :simple_api
13
+ end
12
14
 
13
15
  def self.before_load(jat_class, **_opts)
14
16
  response_plugin = jat_class.config[:response_plugin_loaded]
@@ -22,11 +24,10 @@ class Jat
22
24
  jat_class.extend(ClassMethods)
23
25
  end
24
26
 
25
- def self.after_load(jat_class, **opts)
26
- jat_class.config[:response_plugin_loaded] = :simple_api
27
- jat_class.plugin(:simple_api_activerecord, **opts) if opts[:activerecord]
27
+ def self.after_load(jat_class, **_opts)
28
+ jat_class.config[:response_plugin_loaded] = plugin_name
28
29
 
29
- jat_class.meta_key(DEFAULT_META_KEY)
30
+ jat_class.meta_key(:meta)
30
31
 
31
32
  fields_parser_class = Class.new(FieldsParamParser)
32
33
  fields_parser_class.jat_class = jat_class
@@ -78,7 +79,7 @@ class Jat
78
79
  # Assign same meta
79
80
  added_meta.each_value do |attribute|
80
81
  params = attribute.params
81
- subclass.attribute(params[:name], **params[:opts], &params[:block])
82
+ subclass.meta(params[:name], **params[:opts], &params[:block])
82
83
  end
83
84
  end
84
85
 
@@ -119,6 +120,6 @@ class Jat
119
120
  end
120
121
  end
121
122
 
122
- register_plugin(:simple_api, SimpleApi)
123
+ register_plugin(SimpleApi.plugin_name, SimpleApi)
123
124
  end
124
125
  end
@@ -3,6 +3,10 @@
3
3
  class Jat
4
4
  module Plugins
5
5
  module ToStr
6
+ def self.plugin_name
7
+ :to_str
8
+ end
9
+
6
10
  def self.load(jat_class, **_opts)
7
11
  jat_class.include(InstanceMethods)
8
12
  jat_class.extend(ClassMethods)
@@ -45,6 +49,6 @@ class Jat
45
49
  end
46
50
  end
47
51
 
48
- register_plugin(:to_str, ToStr)
52
+ register_plugin(ToStr.plugin_name, ToStr)
49
53
  end
50
54
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Jat
4
+ module Plugins
5
+ module Types
6
+ def self.plugin_name
7
+ :types
8
+ end
9
+
10
+ def self.load(jat_class, **_opts)
11
+ jat_class::Attribute.include(InstanceMethods)
12
+ end
13
+
14
+ def self.after_load(jat_class, **_opts)
15
+ jat_class.config[:types] = {
16
+ array: ->(value) { Array(value) },
17
+ bool: ->(value) { !!value },
18
+ float: ->(value) { Float(value) },
19
+ hash: ->(value) { Hash(value) },
20
+ int: ->(value) { Integer(value) },
21
+ str: ->(value) { String(value) }
22
+ }
23
+ end
24
+
25
+ module InstanceMethods
26
+ def block
27
+ return @block if instance_variable_defined?(:@block)
28
+
29
+ original_block = super
30
+ type = opts[:type]
31
+ return original_block unless type
32
+
33
+ @block = typed_block(type, original_block)
34
+ end
35
+
36
+ private
37
+
38
+ def typed_block(type, original_block)
39
+ proc do |object, context|
40
+ value = original_block.call(object, context)
41
+
42
+ # Type conversion
43
+ if type.is_a?(Symbol)
44
+ self.class.jat_class.config.fetch(:types).fetch(type).call(value)
45
+ else
46
+ type.call(value)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ register_plugin(Types.plugin_name, Types)
54
+ end
55
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Jat
4
+ module Plugins
5
+ module ValidateParams
6
+ def self.plugin_name
7
+ :validate_params
8
+ end
9
+
10
+ def self.load(jat_class, **opts)
11
+ if jat_class.plugin_used?(:json_api)
12
+ jat_class.plugin :json_api_validate_params, **opts
13
+ elsif jat_class.plugin_used?(:simple_api)
14
+ jat_class.plugin :simple_api_validate_params, **opts
15
+ else
16
+ raise Error, "Please load :json_api or :simple_api plugin first"
17
+ end
18
+ end
19
+ end
20
+
21
+ register_plugin(ValidateParams.plugin_name, ValidateParams)
22
+ end
23
+ end
data/lib/jat/plugins.rb CHANGED
@@ -1,26 +1,52 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Jat
4
+ class PluginLoadError < Error; end
5
+
4
6
  module Plugins
5
7
  @plugins = {}
6
8
 
7
- # Register the given plugin with Jat, so that it can be loaded using
8
- # `Jat.plugin` with a symbol. Should be used by plugin files. Example:
9
- #
10
- # Jat::Plugins.register_plugin(:plugin_name, PluginModule)
11
- def self.register_plugin(name, mod)
12
- @plugins[name] = mod
13
- end
9
+ class << self
10
+ # Registers given plugin to be able to load it using symbol name.
11
+ #
12
+ # Example: Jat::Plugins.register_plugin(:plugin_name, PluginModule)
13
+ def register_plugin(name, mod)
14
+ @plugins[name] = mod
15
+ end
16
+
17
+ # If the registered plugin already exists, use it. Otherwise, require
18
+ # and return it. This raises a LoadError if such a plugin doesn't exist,
19
+ # or a Jat::Error if it exists but it does not register itself
20
+ # correctly.
21
+ def find_plugin(name)
22
+ return name if name.is_a?(Module)
23
+ return @plugins[name] if @plugins.key?(name)
24
+
25
+ begin
26
+ require_plugin(name)
27
+ rescue PluginLoadError
28
+ name_str = name.to_s
29
+ if name_str.start_with?("json_api")
30
+ require_plugin(name, "/json_api/plugins")
31
+ elsif name_str.start_with?("simple_api")
32
+ require_plugin(name, "/simple_api/plugins")
33
+ elsif name_str.start_with?("base")
34
+ require_plugin(name, "/base")
35
+ else
36
+ raise
37
+ end
38
+ end
39
+
40
+ @plugins[name] || raise(PluginLoadError, "Plugin '#{name}' did not register itself correctly")
41
+ end
14
42
 
15
- # If the registered plugin already exists, use it. Otherwise, require
16
- # and return it. This raises a LoadError if such a plugin doesn't exist,
17
- # or a Jat::Error if it exists but it does not register itself
18
- # correctly.
19
- def self.find_plugin(name)
20
- return name if name.is_a?(Module)
21
- require "jat/plugins/#{name}/#{name}" unless @plugins.key?(name)
43
+ private
22
44
 
23
- @plugins[name] || raise(Error, "plugin #{name} did not register itself correctly in Jat::Plugins")
45
+ def require_plugin(name, prefix = nil)
46
+ require "jat/plugins#{prefix}/#{name}/#{name}"
47
+ rescue LoadError
48
+ raise PluginLoadError, "Plugin '#{name}' does not exist"
49
+ end
24
50
  end
25
51
  end
26
52
  end
data/lib/jat.rb CHANGED
@@ -1,17 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "jat/attribute"
4
- require_relative "jat/config"
5
- require_relative "jat/plugins"
6
-
7
3
  # Main namespace
8
4
  class Jat
5
+ # A generic exception used by Jat.
6
+ class Error < StandardError; end
7
+
9
8
  FROZEN_EMPTY_HASH = {}.freeze
10
9
  FROZEN_EMPTY_ARRAY = [].freeze
10
+ end
11
11
 
12
- # A generic exception used by Jat.
13
- class Error < StandardError; end
12
+ require_relative "jat/attribute"
13
+ require_relative "jat/config"
14
+ require_relative "jat/plugins"
14
15
 
16
+ class Jat
15
17
  @config = Config.new({plugins: []})
16
18
 
17
19
  module ClassMethods
@@ -43,24 +45,29 @@ class Jat
43
45
 
44
46
  plugin = Plugins.find_plugin(name)
45
47
 
46
- # Before load usually used to check plugin can be attached or to load additional plugins
48
+ # We split loading of plugin to three methods - before_load, load, after_load:
49
+ #
50
+ # - **before_load** usually used to check requirements and to load additional plugins
51
+ # - **load** usually used to include plugin modules
52
+ # - **after_load** usually used to add config options
47
53
  plugin.before_load(self, **opts) if plugin.respond_to?(:before_load)
48
-
49
- # Usually used to include/extend plugin modules
50
54
  plugin.load(self, **opts) if plugin.respond_to?(:load)
51
-
52
- # Store attached plugins, so we can check them later
53
- config[:plugins] << plugin
54
-
55
- # Set some config options for current plugin or load additional plugins
56
55
  plugin.after_load(self, **opts) if plugin.respond_to?(:after_load)
57
56
 
57
+ # Store attached plugins, so we can check it is loaded later
58
+ config[:plugins] << (plugin.respond_to?(:plugin_name) ? plugin.plugin_name : plugin)
59
+
58
60
  plugin
59
61
  end
60
62
 
61
- def plugin_used?(name)
62
- plugin = Plugins.find_plugin(name)
63
- config[:plugins].include?(plugin)
63
+ def plugin_used?(plugin)
64
+ plugin_name =
65
+ case plugin
66
+ when Module then plugin.respond_to?(:plugin_name) ? plugin.plugin_name : plugin
67
+ else plugin
68
+ end
69
+
70
+ config[:plugins].include?(plugin_name)
64
71
  end
65
72
 
66
73
  def call
@@ -148,5 +148,13 @@ describe Jat::Attribute do
148
148
  attribute = attribute_class.new(name: "foo", opts: {key: :length})
149
149
  assert_equal 3, attribute.value([1, 2, 3], nil)
150
150
  end
151
+
152
+ it "raises error if provide block with more than 2 params" do
153
+ jat_class.attribute(:foo) {}
154
+ jat_class.attribute(:foo) { |_| }
155
+ jat_class.attribute(:foo) { |_, _| }
156
+ err = assert_raises(Jat::Error) { jat_class.attribute(:foo) { |_, _, _| } }
157
+ assert_equal "Block can have 0-2 parameters", err.message
158
+ end
151
159
  end
152
160
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe "Jat::Plugins::Activerecord" do
6
+ it "raises error if no response plugin is loaded" do
7
+ new_class = Class.new(Jat)
8
+ err = assert_raises(Jat::Error) { new_class.plugin :activerecord }
9
+ assert_equal "Please load :json_api or :simple_api plugin first", err.message
10
+ end
11
+
12
+ it "loads simple_api compatible plugin" do
13
+ new_class = Class.new(Jat)
14
+ new_class.plugin :simple_api
15
+ new_class.plugin :activerecord
16
+
17
+ assert new_class.plugin_used?(:simple_api_activerecord)
18
+ end
19
+
20
+ it "loads json_api compatible plugin" do
21
+ new_class = Class.new(Jat)
22
+ new_class.plugin :json_api
23
+ new_class.plugin :activerecord
24
+
25
+ assert new_class.plugin_used?(:json_api_activerecord)
26
+ end
27
+ end
@@ -2,13 +2,13 @@
2
2
 
3
3
  require "test_helper"
4
4
 
5
- describe "Jat::Plugins::ActiverecordPreloads" do
5
+ describe "Jat::Plugins::BaseActiverecordPreloads" do
6
6
  let(:jat_class) do
7
7
  api_test = api_test()
8
8
 
9
9
  Class.new(Jat) do
10
10
  include api_test
11
- plugin(:_activerecord_preloads)
11
+ plugin(:base_activerecord_preloads)
12
12
  end
13
13
  end
14
14
 
@@ -27,7 +27,7 @@ describe "Jat::Plugins::ActiverecordPreloads" do
27
27
  jat = jat_class.new
28
28
  jat.expects(:preloads).returns(preloads)
29
29
 
30
- Jat::Plugins::ActiverecordPreloads::Preloader
30
+ Jat::Plugins::BaseActiverecordPreloads::Preloader
31
31
  .expects(:preload)
32
32
  .with(object, preloads).returns("OBJ_WITH_PRELOADS")
33
33
 
@@ -4,11 +4,11 @@ require "test_helper"
4
4
  require "support/activerecord"
5
5
 
6
6
  describe "Jat::Plugins::ActiverecordPreloads" do
7
- before { Jat::Plugins.find_plugin(:_activerecord_preloads) }
7
+ before { Jat::Plugins.find_plugin(:base_activerecord_preloads) }
8
8
 
9
9
  describe "Preloader" do
10
10
  let(:described_class) { plugin::Preloader }
11
- let(:plugin) { Jat::Plugins::ActiverecordPreloads }
11
+ let(:plugin) { Jat::Plugins::BaseActiverecordPreloads }
12
12
 
13
13
  describe ".handlers" do
14
14
  it "returns memorized array of handlers" do