graphql_rails 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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