graphql_rails 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Gemfile.lock +2 -2
  4. data/README.md +76 -8
  5. data/graphql_rails.gemspec +1 -1
  6. data/lib/graphql_rails/attribute.rb +7 -42
  7. data/lib/graphql_rails/attribute/attribute_type_parser.rb +99 -0
  8. data/lib/graphql_rails/controller.rb +17 -5
  9. data/lib/graphql_rails/controller/action.rb +93 -0
  10. data/lib/graphql_rails/controller/action_configuration.rb +1 -2
  11. data/lib/graphql_rails/controller/controller_function.rb +7 -6
  12. data/lib/graphql_rails/controller/request.rb +3 -3
  13. data/lib/graphql_rails/model.rb +1 -1
  14. data/lib/graphql_rails/model/configuration.rb +14 -50
  15. data/lib/graphql_rails/model/graphql_type_builder.rb +37 -0
  16. data/lib/graphql_rails/router.rb +36 -19
  17. data/lib/graphql_rails/router/{mutation_action.rb → mutation_route.rb} +2 -2
  18. data/lib/graphql_rails/router/{query_action.rb → query_route.rb} +2 -2
  19. data/lib/graphql_rails/router/resource_routes_builder.rb +82 -0
  20. data/lib/graphql_rails/router/route.rb +40 -0
  21. data/lib/graphql_rails/router/schema_builder.rb +9 -5
  22. data/lib/graphql_rails/rspec_controller_helpers.rb +94 -0
  23. data/lib/graphql_rails/version.rb +1 -1
  24. metadata +14 -29
  25. data/lib/graphiti.rb +0 -10
  26. data/lib/graphiti/attribute.rb +0 -86
  27. data/lib/graphiti/controller.rb +0 -54
  28. data/lib/graphiti/controller/action_configuration.rb +0 -46
  29. data/lib/graphiti/controller/configuration.rb +0 -32
  30. data/lib/graphiti/controller/controller_function.rb +0 -41
  31. data/lib/graphiti/controller/request.rb +0 -40
  32. data/lib/graphiti/errors/execution_error.rb +0 -18
  33. data/lib/graphiti/errors/validation_error.rb +0 -26
  34. data/lib/graphiti/model.rb +0 -33
  35. data/lib/graphiti/model/configuration.rb +0 -81
  36. data/lib/graphiti/router.rb +0 -65
  37. data/lib/graphiti/router/action.rb +0 -21
  38. data/lib/graphiti/router/mutation_action.rb +0 -18
  39. data/lib/graphiti/router/query_action.rb +0 -18
  40. data/lib/graphiti/router/resource_actions_builder.rb +0 -82
  41. data/lib/graphiti/router/schema_builder.rb +0 -37
  42. data/lib/graphiti/version.rb +0 -5
  43. data/lib/graphql_rails/controller/action_path_parser.rb +0 -75
  44. data/lib/graphql_rails/router/action.rb +0 -21
  45. data/lib/graphql_rails/router/resource_actions_builder.rb +0 -82
@@ -4,18 +4,22 @@ module GraphqlRails
4
4
  class Router
5
5
  # builds GraphQL::Schema based on previously defined grahiti data
6
6
  class SchemaBuilder
7
- attr_reader :queries, :mutations
7
+ attr_reader :queries, :mutations, :raw_actions
8
8
 
9
- def initialize(queries:, mutations:)
9
+ def initialize(queries:, mutations:, raw_actions:)
10
10
  @queries = queries
11
11
  @mutations = mutations
12
+ @raw_actions = raw_actions
12
13
  end
13
14
 
14
15
  def call
15
16
  query_type = build_type('Query', queries)
16
17
  mutation_type = build_type('Mutation', mutations)
18
+ raw = raw_actions
17
19
 
18
20
  GraphQL::Schema.define do
21
+ raw.each { |action| send(action[:name], *action[:args], &action[:block]) }
22
+
19
23
  query(query_type)
20
24
  mutation(mutation_type)
21
25
  end
@@ -23,12 +27,12 @@ module GraphqlRails
23
27
 
24
28
  private
25
29
 
26
- def build_type(type_name, actions)
30
+ def build_type(type_name, routes)
27
31
  GraphQL::ObjectType.define do
28
32
  name type_name
29
33
 
30
- actions.each do |action|
31
- field action.name, action.options
34
+ routes.each do |route|
35
+ field route.name, Controller::ControllerFunction.from_route(route)
32
36
  end
33
37
  end
34
38
  end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql_rails'
4
+
5
+ module GraphqlRails
6
+ # provides all helpers neccesary for testing graphql controllers. It is similar to rspec controller specs
7
+ #
8
+ # Adds 3 helper methods in to rspec test:
9
+ # * mutation
10
+ # * query
11
+ # * result
12
+ # `mutation` and `query`` methods are identical
13
+ #
14
+ # Usage:
15
+ # it 'works' do
16
+ # mutation(:createUser, params: { name: 'John'}, context: { current_user_id: 1 })
17
+ # expect(response).to be_successful?
18
+ # expect(response)not_to be_failure?
19
+ # expect(response.result).to be_a(User)
20
+ # expect(response.errors).to be_empty
21
+ # end
22
+ module RSpecControllerHelpers
23
+ # contains all details about testing response. Similar as in rspec controllers tests
24
+ class Response
25
+ def initialize(request)
26
+ @request = request
27
+ end
28
+
29
+ def result
30
+ request.object_to_return
31
+ end
32
+
33
+ def errors
34
+ request.errors
35
+ end
36
+
37
+ def success?
38
+ request.errors.empty?
39
+ end
40
+
41
+ def successful?
42
+ success?
43
+ end
44
+
45
+ def failure?
46
+ !success?
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :request
52
+ end
53
+
54
+ # instance which has similar behavior as
55
+ class FakeContext
56
+ extend Forwardable
57
+
58
+ def_delegators :@provided_values, :[], :[]=, :to_h, :key?, :fetch
59
+
60
+ def initialize(values:)
61
+ @errors = []
62
+ @provided_values = values
63
+ end
64
+
65
+ def add_error(error)
66
+ @errors << error
67
+ end
68
+ end
69
+
70
+ # controller request object more suitable for testing
71
+ class Request < GraphqlRails::Controller::Request
72
+ def initialize(params, context)
73
+ super(nil, params, context)
74
+ end
75
+ end
76
+
77
+ def query(query_name, params: {}, context: {})
78
+ context_object = FakeContext.new(values: context)
79
+ request = Request.new(params, context_object)
80
+ described_class.new(request).call(query_name)
81
+
82
+ @response = Response.new(request)
83
+ @response
84
+ end
85
+
86
+ def mutation(*args)
87
+ query(*args)
88
+ end
89
+
90
+ def response
91
+ @response
92
+ end
93
+ end
94
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Povilas Jurčys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-27 00:00:00.000000000 Z
11
+ date: 2018-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '5'
33
+ version: '4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '5'
40
+ version: '4'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -102,29 +102,12 @@ files:
102
102
  - bin/console
103
103
  - bin/setup
104
104
  - graphql_rails.gemspec
105
- - lib/graphiti.rb
106
- - lib/graphiti/attribute.rb
107
- - lib/graphiti/controller.rb
108
- - lib/graphiti/controller/action_configuration.rb
109
- - lib/graphiti/controller/configuration.rb
110
- - lib/graphiti/controller/controller_function.rb
111
- - lib/graphiti/controller/request.rb
112
- - lib/graphiti/errors/execution_error.rb
113
- - lib/graphiti/errors/validation_error.rb
114
- - lib/graphiti/model.rb
115
- - lib/graphiti/model/configuration.rb
116
- - lib/graphiti/router.rb
117
- - lib/graphiti/router/action.rb
118
- - lib/graphiti/router/mutation_action.rb
119
- - lib/graphiti/router/query_action.rb
120
- - lib/graphiti/router/resource_actions_builder.rb
121
- - lib/graphiti/router/schema_builder.rb
122
- - lib/graphiti/version.rb
123
105
  - lib/graphql_rails.rb
124
106
  - lib/graphql_rails/attribute.rb
107
+ - lib/graphql_rails/attribute/attribute_type_parser.rb
125
108
  - lib/graphql_rails/controller.rb
109
+ - lib/graphql_rails/controller/action.rb
126
110
  - lib/graphql_rails/controller/action_configuration.rb
127
- - lib/graphql_rails/controller/action_path_parser.rb
128
111
  - lib/graphql_rails/controller/configuration.rb
129
112
  - lib/graphql_rails/controller/controller_function.rb
130
113
  - lib/graphql_rails/controller/request.rb
@@ -132,12 +115,14 @@ files:
132
115
  - lib/graphql_rails/errors/validation_error.rb
133
116
  - lib/graphql_rails/model.rb
134
117
  - lib/graphql_rails/model/configuration.rb
118
+ - lib/graphql_rails/model/graphql_type_builder.rb
135
119
  - lib/graphql_rails/router.rb
136
- - lib/graphql_rails/router/action.rb
137
- - lib/graphql_rails/router/mutation_action.rb
138
- - lib/graphql_rails/router/query_action.rb
139
- - lib/graphql_rails/router/resource_actions_builder.rb
120
+ - lib/graphql_rails/router/mutation_route.rb
121
+ - lib/graphql_rails/router/query_route.rb
122
+ - lib/graphql_rails/router/resource_routes_builder.rb
123
+ - lib/graphql_rails/router/route.rb
140
124
  - lib/graphql_rails/router/schema_builder.rb
125
+ - lib/graphql_rails/rspec_controller_helpers.rb
141
126
  - lib/graphql_rails/version.rb
142
127
  homepage: https://github.com/povilasjurcys/graphql_rails
143
128
  licenses:
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'graphql_rails/version'
4
- require 'graphql_rails/model'
5
- require 'graphql_rails/router'
6
- require 'graphql_rails/controller'
7
-
8
- # wonders starts here
9
- module GraphqlRails
10
- end
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'graphql'
4
-
5
- module GraphqlRails
6
- # contains info about single graphql attribute
7
- class Attribute
8
- attr_reader :name, :type
9
-
10
- def initialize(name, type = nil, required: false, hidden: false)
11
- @name = name.to_s
12
- @type = parse_type(type || type_by_attribute_name)
13
- @required = required
14
- @hidden = hidden
15
- end
16
-
17
- def graphql_field_type
18
- @graphql_field_type ||= required? ? type.to_non_null_type : type
19
- end
20
-
21
- def required?
22
- @required
23
- end
24
-
25
- def hidden?
26
- @hidden
27
- end
28
-
29
- def field_name
30
- field =
31
- if name.end_with?('?')
32
- "is_#{name.remove(/\?\Z/)}"
33
- else
34
- name
35
- end
36
-
37
- field.camelize(:lower)
38
- end
39
-
40
- private
41
-
42
- def type_by_attribute_name
43
- case name
44
- when 'id', /_id\Z/
45
- GraphQL::ID_TYPE
46
- when /\?\Z/
47
- GraphQL::BOOLEAN_TYPE
48
- else
49
- GraphQL::STRING_TYPE
50
- end
51
- end
52
-
53
- def parse_type(type)
54
- if graphql_type?(type)
55
- type
56
- elsif type.is_a?(String) || type.is_a?(Symbol)
57
- map_type_name_to_type(type.to_s.downcase)
58
- else
59
- raise "Unsupported type #{type.inspect} (class: #{type.class})"
60
- end
61
- end
62
-
63
- def graphql_type?(type)
64
- type.is_a?(GraphQL::BaseType) ||
65
- type.is_a?(GraphQL::ObjectType) ||
66
- (defined?(GraphQL::Schema::Member) && type.is_a?(Class) && type < GraphQL::Schema::Member)
67
- end
68
-
69
- def map_type_name_to_type(type_name)
70
- case type_name
71
- when 'id'
72
- GraphQL::ID_TYPE
73
- when 'int', 'integer'
74
- GraphQL::INT_TYPE
75
- when 'string', 'str', 'text', 'time', 'date'
76
- GraphQL::STRING_TYPE
77
- when 'bool', 'boolean', 'mongoid::boolean'
78
- GraphQL::BOOLEAN_TYPE
79
- when 'float', 'double', 'decimal'
80
- GraphQL::FLOAT_TYPE
81
- else
82
- raise "Don't know how to parse type with name #{type_name.inspect}"
83
- end
84
- end
85
- end
86
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/hash_with_indifferent_access'
4
- require_relative 'controller/configuration'
5
- require_relative 'controller/request'
6
-
7
- module GraphqlRails
8
- # base class for all graphql_rails controllers
9
- class Controller
10
- class << self
11
- def before_action(action_name)
12
- controller_configuration.add_before_action(action_name)
13
- end
14
-
15
- def action(method_name)
16
- controller_configuration.action(method_name)
17
- end
18
-
19
- def controller_configuration
20
- @controller_configuration ||= Controller::Configuration.new(self)
21
- end
22
- end
23
-
24
- def initialize(graphql_request)
25
- @graphql_request = graphql_request
26
- end
27
-
28
- def call(method_name)
29
- self.class.controller_configuration.before_actions.each { |action_name| send(action_name) }
30
-
31
- begin
32
- response = public_send(method_name)
33
- render response if graphql_request.no_object_to_return?
34
- rescue StandardError => error
35
- render error: error
36
- end
37
-
38
- graphql_request.object_to_return
39
- end
40
-
41
- protected
42
-
43
- attr_reader :graphql_request
44
-
45
- def render(object = nil, error: nil, errors: Array(error))
46
- graphql_request.errors = errors
47
- graphql_request.object_to_return = object
48
- end
49
-
50
- def params
51
- @params = HashWithIndifferentAccess.new(graphql_request.params)
52
- end
53
- end
54
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/string/filters'
4
- require 'graphql_rails/attribute'
5
-
6
- module GraphqlRails
7
- class Controller
8
- # stores all graphql_rails contoller specific config
9
- class ActionConfiguration
10
- attr_reader :attributes, :return_type
11
-
12
- def initialize
13
- @attributes = {}
14
- @can_return_nil = false
15
- end
16
-
17
- def permit(*no_type_attributes, **typed_attributes)
18
- no_type_attributes.each { |attribute| permit_attribute(attribute) }
19
- typed_attributes.each { |attribute, type| permit_attribute(attribute, type) }
20
- self
21
- end
22
-
23
- def can_return_nil
24
- @can_return_nil = true
25
- self
26
- end
27
-
28
- def returns(new_return_type)
29
- @return_type = new_return_type
30
- self
31
- end
32
-
33
- def can_return_nil?
34
- @can_return_nil
35
- end
36
-
37
- private
38
-
39
- def permit_attribute(name, type = nil)
40
- field_name = name.to_s.remove(/!\Z/)
41
- required = name.to_s.end_with?('!')
42
- attributes[field_name] = Attribute.new(field_name, type, required: required)
43
- end
44
- end
45
- end
46
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/string/inflections'
4
- require 'graphql_rails/attribute'
5
- require 'graphql_rails/controller/action_configuration'
6
-
7
- module GraphqlRails
8
- class Controller
9
- # stores all graphql_rails contoller specific config
10
- class Configuration
11
- attr_reader :before_actions
12
-
13
- def initialize(controller)
14
- @controller = controller
15
- @before_actions = Set.new
16
- @action_by_name = {}
17
- end
18
-
19
- def add_before_action(name)
20
- before_actions << name
21
- end
22
-
23
- def action(method_name)
24
- @action_by_name[method_name.to_s] ||= ActionConfiguration.new
25
- end
26
-
27
- private
28
-
29
- attr_reader :controller
30
- end
31
- end
32
- end