gql 0.0.19 → 0.0.20

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 770f58471faa9640c902c42c9d89329b3af9a458
4
- data.tar.gz: d95c3150739cbd190256a55adcec0a65c7a059b2
3
+ metadata.gz: 84b1f6dbe8ad680fd457f4f14dbd0183b4b18d46
4
+ data.tar.gz: 192058fde95f568491e87c6edd719b9a4c85b1c1
5
5
  SHA512:
6
- metadata.gz: bc67c88490eac0c385ae5cf53558249342552d8e1a97c6ba719adc4f0495be148529f928bd400236eca5aeeac5eb8377d94cb965bb5d5025ca1f9c32260d2c23
7
- data.tar.gz: 0927523dd03114407ffecb1797997a5620ab4dfc10efa7f0d84571945e47c24625a3a412deb9bdecf25e383ea18df4467db27f4d42c951b1f391caf732f54cd7
6
+ metadata.gz: dee4291ac7f769adf121c145b8f2a2a93bd0a3417aba29e218120cc2106045f2e4f19cbcd2491b778aff4531f6c04d88acb39500bae1d24763be054131cfe29a
7
+ data.tar.gz: ae67282c3aa9cf8b48155429c7f6714f16562ba3ff77fdf9f4a9edcfabc8fae59d02b7472490599f3959b36a2af82971ad8ff36754be8f3b8b61cf71d757ff64
data/lib/gql.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'active_support/dependencies/autoload'
2
+
2
3
  require 'gql/version'
4
+ require 'gql/errors'
3
5
 
4
6
  module GQL
5
7
  extend ActiveSupport::Autoload
@@ -9,33 +11,17 @@ module GQL
9
11
  autoload :Call
10
12
  autoload :Config
11
13
  autoload :Connection
12
- autoload :Error, 'gql/errors'
13
14
  autoload :Executor
14
15
  autoload :Field
16
+ autoload :Lazy
15
17
  autoload :Number
16
18
  autoload :Object
17
19
  autoload :Parser
20
+ autoload :Registry
18
21
  autoload :Scalar
19
22
  autoload :String
20
- autoload :TestCase
21
23
  autoload :Tokenizer
22
24
 
23
- module Errors
24
- extend ActiveSupport::Autoload
25
-
26
- autoload_at 'gql/errors' do
27
- autoload :CallNotFound
28
- autoload :FieldClassNotSet
29
- autoload :FieldNotFound
30
- autoload :InvalidFieldClass
31
- autoload :NoMethodError
32
- autoload :RootClassNotSet
33
- autoload :ScanError
34
- autoload :SyntaxError
35
- autoload :VariableNotFound
36
- end
37
- end
38
-
39
25
  module Schema
40
26
  extend ActiveSupport::Autoload
41
27
 
@@ -55,8 +41,8 @@ module GQL
55
41
  Thread.current[:gql_config] = value
56
42
  end
57
43
 
58
- %w(root_field_class root_target_proc field_types
59
- default_list_field_class default_field_proc
44
+ %w(root_class root_target_proc field_types
45
+ default_list_class default_field_proc
60
46
  default_call_proc debug).each do |method|
61
47
  module_eval <<-DELEGATORS, __FILE__, __LINE__ + 1
62
48
  def #{method}
@@ -2,32 +2,26 @@ require 'active_support/core_ext/class/attribute'
2
2
 
3
3
  module GQL
4
4
  class Array < Field
5
- class_attribute :item_field_class, instance_accessor: false, instance_predicate: false
5
+ class_attribute :item_class, instance_accessor: false, instance_predicate: false
6
6
 
7
7
  class << self
8
8
  def build_class(id, proc, options = {})
9
- item_field_class = options.delete(:item_field_class) || self.item_field_class
10
-
11
- if item_field_class.is_a?(Hash)
12
- item_field_class.values.each do |ifc|
13
- Field.validate_is_subclass! ifc, 'item_field_class'
14
- end
15
- else
16
- Field.validate_is_subclass! item_field_class, 'item_field_class'
17
- item_field_class = Hash.new(item_field_class)
18
- end
9
+ item_class = options.delete(:item_class) || self.item_class
10
+ item_class = ::Hash.new(item_class) unless item_class.is_a?(::Hash)
19
11
 
20
12
  Class.new(self).tap do |field_class|
21
- field_class.id = id.to_s
13
+ field_class.id = id
22
14
  field_class.proc = proc
23
- field_class.item_field_class = item_field_class
15
+ field_class.item_class = item_class
24
16
  end
25
17
  end
26
18
  end
27
19
 
28
20
  def value
29
21
  target.map do |item|
30
- field = self.class.item_field_class[item.class].new(ast_node, item, variables, context)
22
+ field_class = Registry.fetch(self.class.item_class[item.class])
23
+
24
+ field = field_class.new(ast_node, item, variables, context)
31
25
  field.value
32
26
  end
33
27
  end
@@ -1,17 +1,11 @@
1
- require 'active_support/core_ext/class/subclasses'
2
-
3
1
  module GQL
4
2
  class Config
5
- def root_field_class
6
- @@root_field_class ||= nil
3
+ def root_class
4
+ @@root_class ||= nil
7
5
  end
8
6
 
9
- def root_field_class=(value)
10
- unless value.nil? || value <= Field
11
- raise Errors::InvalidFieldClass.new(value, Field)
12
- end
13
-
14
- @@root_field_class = value
7
+ def root_class=(value)
8
+ @@root_class = value
15
9
  end
16
10
 
17
11
  def root_target_proc
@@ -24,12 +18,12 @@ module GQL
24
18
 
25
19
  def field_types
26
20
  @@field_types ||= {
27
- array: Array,
28
- boolean: Boolean,
29
- connection: Connection,
30
- number: Number,
31
- object: Object,
32
- string: String
21
+ array: 'GQL::Array',
22
+ boolean: 'GQL::Boolean',
23
+ connection: 'GQL::Connection',
24
+ number: 'GQL::Number',
25
+ object: 'GQL::Object',
26
+ string: 'GQL::String'
33
27
  }
34
28
  end
35
29
 
@@ -37,16 +31,12 @@ module GQL
37
31
  @@field_types = value
38
32
  end
39
33
 
40
- def default_list_field_class
41
- @@default_list_field_class ||= Field
34
+ def default_list_class
35
+ @@default_list_class ||= 'GQL::Field'
42
36
  end
43
37
 
44
- def default_list_field_class=(value)
45
- unless value.nil? || value <= Field
46
- raise Errors::InvalidFieldClass.new(value, Field)
47
- end
48
-
49
- @@default_list_field_class = value
38
+ def default_list_class=(value)
39
+ @@default_list_class = value
50
40
  end
51
41
 
52
42
  def default_field_proc
@@ -77,6 +67,8 @@ module GQL
77
67
  def debug=(value)
78
68
  value = !!value
79
69
 
70
+ @@debug = nil unless defined?(@@debug)
71
+
80
72
  return if value == @@debug
81
73
 
82
74
  value ? switch_debug_on : switch_debug_off
@@ -86,39 +78,13 @@ module GQL
86
78
 
87
79
  private
88
80
  def switch_debug_on
89
- switch_on_type_field
90
- switch_on_execution_context
91
- end
92
-
93
- def switch_debug_off
94
- switch_off_type_field
95
- switch_off_execution_context
96
- end
97
-
98
- def switch_on_type_field
99
- return if Field.has_field? :__type__
100
-
101
- type_field_class = Field.object :__type__, -> { field_class }, field_class: Schema::Field
102
-
103
- Field.descendants.each do |field_class|
104
- field_class.fields[:__type__] = type_field_class
105
- end
106
- end
107
-
108
- def switch_off_type_field
109
- return unless Field.has_field? :__type__
110
-
111
- [Field, *Field.descendants].each do |field_class|
112
- field_class.remove_field :__type__
113
- end
114
- end
115
-
116
- def switch_on_execution_context
81
+ Field.object :__type__, -> { field_class }, class: Schema::Field
117
82
  Field.send :remove_const, :ExecutionContext if Field.const_defined?(:ExecutionContext)
118
83
  Field.const_set :ExecutionContext, Field::ExecutionContextDebug
119
84
  end
120
85
 
121
- def switch_off_execution_context
86
+ def switch_debug_off
87
+ Field.remove_field :__type__
122
88
  Field.send :remove_const, :ExecutionContext if Field.const_defined?(:ExecutionContext)
123
89
  Field.const_set :ExecutionContext, Field::ExecutionContextNoDebug
124
90
  end
@@ -1,16 +1,12 @@
1
- require 'active_support/core_ext/class/attribute'
2
-
3
1
  module GQL
4
2
  class Connection < Field
5
3
  class << self
6
4
  def build_class(id, proc, options = {})
7
- list_field_class = options.delete(:list_field_class) || GQL.default_list_field_class
8
- item_field_class = options.delete(:item_field_class)
9
-
10
- Field.validate_is_subclass! list_field_class, 'list_field_class'
5
+ list_class = options.delete(:list_class) || GQL.default_list_class
6
+ item_class = options.delete(:item_class)
11
7
 
12
- list_field_class.build_class(id, proc, options).tap do |field_class|
13
- field_class.array :edges, -> { target }, item_field_class: item_field_class
8
+ Registry.fetch(list_class).build_class(id, proc, options).tap do |field_class|
9
+ field_class.array :edges, -> { target }, item_class: item_class
14
10
  end
15
11
  end
16
12
  end
@@ -64,7 +64,7 @@ module GQL
64
64
  class RootClassNotSet < Error
65
65
  def initialize
66
66
  msg = "GQL root field class is not set. "
67
- msg << "Set it with `GQL.root_field_class = MyRootField'."
67
+ msg << "Set it with `GQL.root_class = MyRootField'."
68
68
 
69
69
  super(msg, 121)
70
70
  end
@@ -8,7 +8,7 @@ module GQL
8
8
  end
9
9
 
10
10
  def execute(context = {}, vars = {})
11
- field_class = GQL.root_field_class
11
+ field_class = GQL.root_class
12
12
 
13
13
  raise Errors::RootClassNotSet if field_class.nil?
14
14
 
@@ -16,7 +16,7 @@ module GQL
16
16
 
17
17
  target = GQL.root_target_proc.call(context)
18
18
 
19
- field = field_class.new(ast_root, target, variables, context)
19
+ field = Registry.fetch(field_class).new(ast_root, target, variables, context)
20
20
  field.value
21
21
  end
22
22
  end
@@ -1,7 +1,8 @@
1
1
  require 'active_support/core_ext/class/attribute'
2
2
 
3
- require 'gql/has_calls'
4
- require 'gql/has_fields'
3
+ require 'gql/mixins/common'
4
+ require 'gql/mixins/has_calls'
5
+ require 'gql/mixins/has_fields'
5
6
 
6
7
  module GQL
7
8
  class Field
@@ -14,20 +15,11 @@ module GQL
14
15
  field_class.proc = proc
15
16
  end
16
17
  end
17
-
18
- def validate_is_subclass!(subclass, name)
19
- if subclass.nil?
20
- raise Errors::FieldClassNotSet.new(self, name)
21
- end
22
-
23
- unless subclass <= self
24
- raise Errors::InvalidFieldClass.new(subclass, self)
25
- end
26
- end
27
18
  end
28
19
 
29
- include HasCalls
30
- include HasFields
20
+ extend Mixins::Common
21
+ include Mixins::HasCalls
22
+ include Mixins::HasFields
31
23
 
32
24
  attr_reader :ast_node, :target, :variables, :context
33
25
 
@@ -0,0 +1,31 @@
1
+ require 'active_support/core_ext/class/attribute'
2
+
3
+ module GQL
4
+ class Lazy < Field
5
+ class_attribute :owner, :type, :options, instance_accessor: false, instance_predicate: false
6
+
7
+ class << self
8
+ def build_class(id, proc, options)
9
+ Class.new(self).tap do |field_class|
10
+ field_class.owner = options.delete(:owner)
11
+ field_class.type = options.delete(:type)
12
+ field_class.id = id
13
+ field_class.proc = proc
14
+ field_class.options = options
15
+ end
16
+ end
17
+
18
+ def resolve
19
+ owner.remove_field id
20
+ owner.add_field id, proc, options.merge(type: Registry.fetch(type))
21
+ end
22
+ end
23
+
24
+ def value
25
+ field_class = self.class.resolve
26
+
27
+ field = field_class.new(ast_node, target, variables, context)
28
+ field.value
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/core_ext/string/inflections'
3
+
4
+ module GQL
5
+ module Mixins
6
+ module Common
7
+ def propagate(type, id, klass)
8
+ const_name = send("const_name_for_#{type}", id)
9
+ accessor = type.to_s.pluralize
10
+
11
+ const_set const_name, klass
12
+
13
+ [self, *descendants].each do |c|
14
+ c.send "#{accessor}=", c.send(accessor).merge(id => klass)
15
+ end
16
+ end
17
+
18
+ def shutdown(type, id)
19
+ const_name = send("const_name_for_#{type}", id)
20
+ accessor = type.to_s.pluralize
21
+
22
+ [self, *descendants].each do |c|
23
+ next unless c.send("has_#{type}?", id)
24
+
25
+ c.send :remove_const, const_name if c.const_defined?(const_name, false)
26
+ c.send(accessor).delete id
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,120 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/core_ext/array/extract_options'
3
+ require 'active_support/core_ext/class/attribute'
4
+ require 'active_support/core_ext/class/subclasses'
5
+ require 'active_support/core_ext/object/try'
6
+ require 'active_support/core_ext/string/inflections'
7
+
8
+ module GQL
9
+ module Mixins
10
+ module HasCalls
11
+ extend ActiveSupport::Concern
12
+
13
+ included do
14
+ class_attribute :calls, :call_proc, instance_accessor: false, instance_predicate: false
15
+ self.calls = {}
16
+ end
17
+
18
+ module ClassMethods
19
+ def add_call(id, *args, &block)
20
+ remove_call id
21
+
22
+ id = id.to_sym
23
+ options = args.extract_options!
24
+ call_spec = args.shift || block || proc_for_call(id)
25
+ result_spec = options[:returns] || call_spec.try(:result_class)
26
+ result_class = result_class_from_spec(result_spec)
27
+
28
+ build_call_class(call_spec, id, result_class).tap do |call_class|
29
+ propagate :call, id, call_class
30
+ end
31
+ end
32
+
33
+ alias :call :add_call
34
+
35
+ def remove_call(id)
36
+ shutdown :call, id.to_sym
37
+ end
38
+
39
+ def has_call?(id)
40
+ calls.has_key? id.to_sym
41
+ end
42
+
43
+ private
44
+ def build_call_class(spec, id, result_class)
45
+ call_class_from_spec(spec).tap do |call_class|
46
+ call_class.id = id
47
+ call_class.result_class = result_class
48
+
49
+ if result_class && result_class.name.nil?
50
+ call_class.const_set :Result, result_class
51
+ end
52
+ end
53
+ end
54
+
55
+ def call_class_from_spec(spec)
56
+ return Class.new(spec) unless spec.is_a?(Proc)
57
+
58
+ Class.new(Call).tap do |call_class|
59
+ call_class.class_eval do
60
+ self.proc = spec
61
+
62
+ def execute(*args)
63
+ instance_exec(*args, &self.class.proc)
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ def const_name_for_call(id)
70
+ :"#{id.to_s.camelize}Call"
71
+ end
72
+
73
+ def proc_for_call(id)
74
+ instance_exec id, &(call_proc || GQL.default_call_proc)
75
+ end
76
+
77
+ def result_class_from_spec(spec)
78
+ result_class =
79
+ case spec
80
+ when ::Array
81
+ result_class_from_connection_spec spec.dup
82
+ when ::Hash
83
+ result_class_from_mapping_spec spec.dup
84
+ else
85
+ spec
86
+ end
87
+
88
+ result_class && Registry.fetch(result_class)
89
+ end
90
+
91
+ def result_class_from_connection_spec(spec)
92
+ if spec.size == 1
93
+ spec.unshift GQL.default_list_class
94
+ end
95
+
96
+ options = {
97
+ list_class: spec.first,
98
+ item_class: spec.last
99
+ }
100
+
101
+ Connection.build_class :result, nil, options
102
+ end
103
+
104
+ def result_class_from_mapping_spec(spec)
105
+ Object.build_class :result, nil, class: spec
106
+ end
107
+ end
108
+
109
+ private
110
+ def value_of_call(ast_call)
111
+ call_class = call_class_for_id(ast_call.id)
112
+ call_class.execute(self.class, ast_call, target, variables, context)
113
+ end
114
+
115
+ def call_class_for_id(id)
116
+ self.class.calls[id] or raise Errors::CallNotFound.new(id, self.class)
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,138 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/core_ext/array/extract_options'
3
+ require 'active_support/core_ext/class/attribute'
4
+ require 'active_support/core_ext/class/subclasses'
5
+ require 'active_support/core_ext/string/inflections'
6
+
7
+ module GQL
8
+ module Mixins
9
+ module HasFields
10
+ extend ActiveSupport::Concern
11
+
12
+ included do
13
+ class_attribute :fields, :field_proc, instance_accessor: false, instance_predicate: false
14
+ self.fields = {}
15
+ end
16
+
17
+ module ClassMethods
18
+ def add_field(id, *args, &block)
19
+ remove_field id
20
+
21
+ id = id.to_sym
22
+ options = args.extract_options!
23
+ type = options.delete(:type) || Field
24
+ proc = args.shift || block || proc_for_field(id)
25
+
26
+ build_field_class(type, id, proc, options).tap do |field_class|
27
+ propagate :field, id, field_class
28
+ end
29
+ end
30
+
31
+ alias :field :add_field
32
+
33
+ def remove_field(id)
34
+ shutdown :field, id.to_sym
35
+ end
36
+
37
+ def has_field?(id)
38
+ fields.has_key? id.to_sym
39
+ end
40
+
41
+ def cursor(id_or_proc)
42
+ id = id_or_proc.is_a?(Proc) ? nil : id_or_proc
43
+ proc = id ? -> { target.public_send(id) } : id_or_proc
44
+
45
+ add_field :cursor, proc, type: Scalar
46
+ end
47
+
48
+ def respond_to?(method, *args)
49
+ super || GQL.field_types.has_key?(method)
50
+ end
51
+
52
+ def method_missing(method, *args, &block)
53
+ if type = GQL.field_types[method]
54
+ define_field_method method, type
55
+ send method, *args, &block
56
+ else
57
+ super
58
+ end
59
+ rescue NoMethodError => exc
60
+ raise Errors::NoMethodError.new(self, method, exc)
61
+ end
62
+
63
+ private
64
+ def build_field_class(type, id, proc, options)
65
+ if type.is_a? ::String
66
+ Lazy.build_class id, proc, options.merge(owner: self, type: type)
67
+ else
68
+ Registry.fetch(type).build_class id, proc, options
69
+ end
70
+ end
71
+
72
+ def const_name_for_field(id)
73
+ prefix = id == :__type__ ? 'Schema_Type' : id.to_s.camelize
74
+ :"#{prefix}Field"
75
+ end
76
+
77
+ def proc_for_field(id)
78
+ instance_exec id, &(field_proc || GQL.default_field_proc)
79
+ end
80
+
81
+ def define_field_method(name, type)
82
+ Field.define_singleton_method name do |*args, &block|
83
+ options = args.extract_options!.merge(type: type)
84
+ args = args.push(options)
85
+
86
+ add_field(*args, &block)
87
+ end
88
+ end
89
+ end
90
+
91
+ private
92
+ def value_of_fields(ast_fields)
93
+ ast_fields.reduce({}) do |result, ast_field|
94
+ key = ast_field.alias_id || ast_field.id
95
+
96
+ result.merge key => value_of_field(ast_field)
97
+ end
98
+ end
99
+
100
+ def value_of_field(ast_field)
101
+ if ast_field.id == :node
102
+ field = self.class.new(ast_field, target, variables, context)
103
+ field.value
104
+ else
105
+ field_class = field_class_for_id(ast_field.id)
106
+ next_target = target_for_field(target, field_class.proc)
107
+
108
+ field = field_class.new(ast_field, next_target, variables, context)
109
+ field.value
110
+ end
111
+ end
112
+
113
+ def field_class_for_id(id)
114
+ self.class.fields[id] or raise Errors::FieldNotFound.new(id, self.class)
115
+ end
116
+
117
+ def target_for_field(current_target, proc)
118
+ args = [current_target, context]
119
+ args.push self.class if GQL.debug
120
+
121
+ method = self.class.const_get(:ExecutionContext).new(*args)
122
+ method.execute proc
123
+ end
124
+
125
+ class ExecutionContextNoDebug < Struct.new(:target, :context)
126
+ def execute(method, args = [])
127
+ instance_exec(*args, &method)
128
+ end
129
+ end
130
+
131
+ class ExecutionContextDebug < Struct.new(:target, :context, :field_class)
132
+ def execute(method, args = [])
133
+ instance_exec(*args, &method)
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -2,14 +2,26 @@ require 'active_support/core_ext/class/attribute'
2
2
 
3
3
  module GQL
4
4
  class Object < Field
5
+ class_attribute :object_class, instance_accessor: false, instance_predicate: false
6
+
5
7
  class << self
6
8
  def build_class(id, proc, options = {})
7
- field_class = options.delete(:field_class)
8
-
9
- Field.validate_is_subclass! field_class, 'field_class'
9
+ object_class = options.delete(:class) || options.delete(:as)
10
+ object_class = ::Hash.new(object_class) unless object_class.is_a?(::Hash)
10
11
 
11
- field_class.build_class id, proc, options
12
+ Class.new(self).tap do |klass|
13
+ klass.id = id
14
+ klass.proc = proc
15
+ klass.object_class = object_class
16
+ end
12
17
  end
13
18
  end
19
+
20
+ def value
21
+ field_class = Registry.fetch(self.class.object_class[target.class])
22
+
23
+ field = field_class.new(ast_node, target, variables, context)
24
+ field.value
25
+ end
14
26
  end
15
27
  end
@@ -0,0 +1,39 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+ require 'active_support/per_thread_registry'
3
+
4
+ module GQL
5
+ class Registry
6
+ extend ActiveSupport::PerThreadRegistry
7
+
8
+ attr_reader :cache
9
+
10
+ def initialize
11
+ reset
12
+ end
13
+
14
+ def reset
15
+ @cache = {}
16
+ end
17
+
18
+ def fetch(key, baseclass = Field)
19
+ cache[key] || begin
20
+ raise Errors::FieldClassNotSet.new(baseclass, 'TODO') if key.nil?
21
+
22
+ const, name =
23
+ if key.instance_of? ::Class
24
+ [key, key.name]
25
+ else
26
+ [key.constantize, key]
27
+ end
28
+
29
+ raise Errors::InvalidFieldClass.new(const, baseclass) unless const <= baseclass
30
+
31
+ cache.update name => const, const => const
32
+
33
+ cache[key]
34
+ end
35
+ end
36
+
37
+ alias_method :[], :fetch
38
+ end
39
+ end
@@ -5,8 +5,8 @@ module GQL
5
5
 
6
6
  string :id
7
7
  string :name
8
- object :result_class, -> { target.result_class || CallerClass }, field_class: Field
9
- array :parameters, -> { (target.proc || target.instance_method(:execute)).parameters }, item_field_class: Parameter
8
+ object :result_class, -> { target.result_class || CallerClass }, class: Field
9
+ array :parameters, -> { (target.proc || target.instance_method(:execute)).parameters }, item_class: Parameter
10
10
 
11
11
  def scalar_value
12
12
  target.name
@@ -5,8 +5,8 @@ module GQL
5
5
 
6
6
  string :id
7
7
  string :name
8
- connection :calls, -> { target.calls.values }, list_field_class: List, item_field_class: Call
9
- connection :fields, -> { target.fields.values }, list_field_class: List, item_field_class: Field
8
+ connection :calls, -> { target.calls.values }, list_class: List, item_class: Call
9
+ connection :fields, -> { target.fields.values }, list_class: List, item_class: Field
10
10
 
11
11
  def scalar_value
12
12
  target.name
@@ -1,3 +1,3 @@
1
1
  module GQL
2
- VERSION = '0.0.19'
2
+ VERSION = '0.0.20'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.19
4
+ version: 0.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Andert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-12 00:00:00.000000000 Z
11
+ date: 2015-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-perf
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.1'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: activesupport
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -112,11 +126,14 @@ files:
112
126
  - lib/gql/errors.rb
113
127
  - lib/gql/executor.rb
114
128
  - lib/gql/field.rb
115
- - lib/gql/has_calls.rb
116
- - lib/gql/has_fields.rb
129
+ - lib/gql/lazy.rb
130
+ - lib/gql/mixins/common.rb
131
+ - lib/gql/mixins/has_calls.rb
132
+ - lib/gql/mixins/has_fields.rb
117
133
  - lib/gql/number.rb
118
134
  - lib/gql/object.rb
119
135
  - lib/gql/parser.rb
136
+ - lib/gql/registry.rb
120
137
  - lib/gql/scalar.rb
121
138
  - lib/gql/schema/call.rb
122
139
  - lib/gql/schema/caller_class.rb
@@ -124,7 +141,6 @@ files:
124
141
  - lib/gql/schema/list.rb
125
142
  - lib/gql/schema/parameter.rb
126
143
  - lib/gql/string.rb
127
- - lib/gql/test_case.rb
128
144
  - lib/gql/tokenizer.rb
129
145
  - lib/gql/version.rb
130
146
  homepage: https://github.com/martinandert/gql
@@ -1,104 +0,0 @@
1
- require 'active_support/concern'
2
- require 'active_support/core_ext/array/extract_options'
3
- require 'active_support/core_ext/class/attribute'
4
- require 'active_support/core_ext/string/inflections'
5
- require 'active_support/core_ext/object/try'
6
-
7
- module GQL
8
- module HasCalls
9
- extend ActiveSupport::Concern
10
-
11
- included do
12
- class_attribute :calls, :call_proc, instance_accessor: false, instance_predicate: false
13
- self.calls = {}
14
- end
15
-
16
- module ClassMethods
17
- def add_call(id, *args, &block)
18
- options = args.extract_options!
19
-
20
- call_spec = args.shift || block || proc_for_call(id)
21
- result_spec = options[:returns] || call_spec.try(:result_class)
22
- result_class = result_class_from_spec(result_spec)
23
-
24
- Field.validate_is_subclass! result_class, 'result_class' if result_class
25
-
26
- call_class = call_class_from_spec(call_spec)
27
- call_class.id = id.to_s
28
- call_class.result_class = result_class
29
-
30
- if result_class && result_class.name.nil?
31
- call_class.const_set :Result, result_class
32
- end
33
-
34
- self.const_set const_name_for_call(id), call_class
35
- self.calls = calls.merge(id.to_sym => call_class)
36
- end
37
-
38
- alias :call :add_call
39
-
40
- def remove_call(id)
41
- const_name = const_name_for_call(id)
42
-
43
- send :remove_const, const_name if const_defined?(const_name)
44
- calls.delete id
45
- end
46
-
47
- def has_call?(id)
48
- calls.has_key? id
49
- end
50
-
51
- private
52
- def const_name_for_call(id)
53
- :"#{id.to_s.camelize}Call"
54
- end
55
-
56
- def proc_for_call(id)
57
- instance_exec id, &(call_proc || GQL.default_call_proc)
58
- end
59
-
60
- def result_class_from_spec(spec)
61
- return spec unless spec.is_a? ::Array
62
-
63
- result_class_from_connection_spec spec.dup
64
- end
65
-
66
- def result_class_from_connection_spec(spec)
67
- if spec.size == 1
68
- spec.unshift GQL.default_list_field_class
69
- end
70
-
71
- options = {
72
- list_field_class: spec.first,
73
- item_field_class: spec.last
74
- }
75
-
76
- Connection.build_class :result, nil, options
77
- end
78
-
79
- def call_class_from_spec(spec)
80
- return Class.new(spec) unless spec.is_a?(Proc)
81
-
82
- Class.new(Call).tap do |call_class|
83
- call_class.class_eval do
84
- self.proc = spec
85
-
86
- def execute(*args)
87
- instance_exec(*args, &self.class.proc)
88
- end
89
- end
90
- end
91
- end
92
- end
93
-
94
- private
95
- def value_of_call(ast_call)
96
- call_class = call_class_for_id(ast_call.id)
97
- call_class.execute(self.class, ast_call, target, variables, context)
98
- end
99
-
100
- def call_class_for_id(id)
101
- self.class.calls[id] or raise Errors::CallNotFound.new(id, self.class)
102
- end
103
- end
104
- end
@@ -1,132 +0,0 @@
1
- require 'active_support/concern'
2
- require 'active_support/core_ext/array/extract_options'
3
- require 'active_support/core_ext/class/attribute'
4
- require 'active_support/core_ext/string/inflections'
5
-
6
- module GQL
7
- module HasFields
8
- extend ActiveSupport::Concern
9
-
10
- included do
11
- class_attribute :fields, :field_proc, instance_accessor: false, instance_predicate: false
12
- self.fields = {}
13
- end
14
-
15
- module ClassMethods
16
- def add_field(id, *args, &block)
17
- options = args.extract_options!
18
- type = options.delete(:type) || Field
19
- proc = args.shift || block || proc_for_field(id)
20
-
21
- Field.validate_is_subclass! type, 'type'
22
-
23
- type.build_class(id, proc, options).tap do |field_class|
24
- const_name = const_name_for_field(id)
25
-
26
- const_set const_name, field_class unless const_defined?(const_name)
27
- self.fields = fields.merge(id.to_sym => field_class)
28
- end
29
- end
30
-
31
- alias :field :add_field
32
-
33
- def remove_field(id)
34
- const_name = const_name_for_field(id)
35
-
36
- send :remove_const, const_name if const_defined?(const_name)
37
- fields.delete id
38
- end
39
-
40
- def has_field?(id)
41
- fields.has_key? id
42
- end
43
-
44
- def cursor(id_or_proc)
45
- id = id_or_proc.is_a?(Proc) ? nil : id_or_proc
46
- proc = id ? -> { target.public_send(id) } : id_or_proc
47
-
48
- add_field :cursor, proc, type: Scalar
49
- end
50
-
51
- def respond_to?(method, *args)
52
- super || GQL.field_types.has_key?(method)
53
- end
54
-
55
- def method_missing(method, *args, &block)
56
- if type = GQL.field_types[method]
57
- define_field_method method, type
58
- send method, *args, &block
59
- else
60
- super
61
- end
62
- rescue NoMethodError => exc
63
- raise Errors::NoMethodError.new(self, method, exc)
64
- end
65
-
66
- private
67
- def const_name_for_field(id)
68
- prefix = id == :__type__ ? 'Schema_Type' : id.to_s.camelize
69
- :"#{prefix}Field"
70
- end
71
-
72
- def proc_for_field(id)
73
- instance_exec id, &(field_proc || GQL.default_field_proc)
74
- end
75
-
76
- def define_field_method(name, type)
77
- Field.define_singleton_method name do |*args, &block|
78
- options = args.extract_options!.merge(type: type)
79
- args = args.push(options)
80
-
81
- add_field(*args, &block)
82
- end
83
- end
84
- end
85
-
86
- private
87
- def value_of_fields(ast_fields)
88
- ast_fields.reduce({}) do |result, ast_field|
89
- key = ast_field.alias_id || ast_field.id
90
-
91
- result.merge key => value_of_field(ast_field)
92
- end
93
- end
94
-
95
- def value_of_field(ast_field)
96
- if ast_field.id == :node
97
- field = self.class.new(ast_field, target, variables, context)
98
- field.value
99
- else
100
- field_class = field_class_for_id(ast_field.id)
101
- next_target = target_for_field(target, field_class.proc)
102
-
103
- field = field_class.new(ast_field, next_target, variables, context)
104
- field.value
105
- end
106
- end
107
-
108
- def field_class_for_id(id)
109
- self.class.fields[id] or raise Errors::FieldNotFound.new(id, self.class)
110
- end
111
-
112
- def target_for_field(current_target, proc)
113
- args = [current_target, context]
114
- args.push self.class if GQL.debug
115
-
116
- method = self.class.const_get(:ExecutionContext).new(*args)
117
- method.execute proc
118
- end
119
-
120
- class ExecutionContextNoDebug < Struct.new(:target, :context)
121
- def execute(method, args = [])
122
- instance_exec(*args, &method)
123
- end
124
- end
125
-
126
- class ExecutionContextDebug < Struct.new(:target, :context, :field_class)
127
- def execute(method, args = [])
128
- instance_exec(*args, &method)
129
- end
130
- end
131
- end
132
- end
@@ -1,4 +0,0 @@
1
- module GQL
2
- class TestCase < ActiveSupport::TestCase
3
- end
4
- end