search_object_graphql 0.1 → 1.0.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.
- checksums.yaml +5 -5
- data/.rubocop.yml +15 -3
- data/.ruby-version +1 -0
- data/.travis.yml +3 -2
- data/CHANGELOG.md +25 -0
- data/Gemfile +2 -0
- data/README.md +34 -33
- data/Rakefile +3 -1
- data/example/.ruby-version +1 -1
- data/example/Gemfile +3 -1
- data/example/README.md +3 -3
- data/example/Rakefile +2 -0
- data/example/app/controllers/application_controller.rb +2 -0
- data/example/app/controllers/graphql_controller.rb +22 -18
- data/example/app/graphql/mutations/.keep +0 -0
- data/example/app/graphql/resolvers/base_resolver.rb +6 -0
- data/example/app/graphql/resolvers/base_search_resolver.rb +3 -1
- data/example/app/graphql/resolvers/category_search.rb +5 -3
- data/example/app/graphql/resolvers/post_search.rb +6 -4
- data/example/app/graphql/schema.rb +3 -1
- data/example/app/graphql/types/base_enum.rb +6 -0
- data/example/app/graphql/types/base_input_object.rb +6 -0
- data/example/app/graphql/types/base_interface.rb +7 -0
- data/example/app/graphql/types/base_object.rb +6 -0
- data/example/app/graphql/types/base_scalar.rb +6 -0
- data/example/app/graphql/types/base_union.rb +6 -0
- data/example/app/graphql/types/category_type.rb +7 -6
- data/example/app/graphql/types/date_time_type.rb +3 -4
- data/example/app/graphql/types/mutation_type.rb +6 -0
- data/example/app/graphql/types/post_type.rb +13 -11
- data/example/app/graphql/types/query_type.rb +6 -5
- data/example/app/models/application_record.rb +2 -0
- data/example/app/models/category.rb +2 -0
- data/example/app/models/post.rb +2 -0
- data/example/bin/bundle +3 -1
- data/example/bin/rails +2 -0
- data/example/bin/rake +2 -0
- data/example/bin/setup +4 -2
- data/example/bin/update +4 -2
- data/example/config.ru +2 -0
- data/example/config/application.rb +1 -1
- data/example/db/migrate/20170507175133_create_demo_tables.rb +1 -1
- data/example/db/schema.rb +1 -1
- data/example/public/favicon.ico +0 -0
- data/lib/search_object/plugin/graphql.rb +26 -47
- data/lib/search_object/plugin/graphql/version.rb +3 -1
- data/search_object_graphql.gemspec +9 -9
- data/spec/search_object/plugin/graphql_spec.rb +114 -96
- data/spec/spec_helper.rb +2 -0
- data/spec/spec_helper_active_record.rb +2 -0
- metadata +31 -35
@@ -1,8 +1,9 @@
|
|
1
|
-
|
2
|
-
name 'Category'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module Types
|
4
|
+
class CategoryType < BaseObject
|
5
|
+
field :id, ID, null: false
|
6
|
+
field :name, String, null: false
|
7
|
+
field :posts, resolver: Resolvers::PostSearch
|
8
|
+
end
|
8
9
|
end
|
@@ -1,6 +1,5 @@
|
|
1
|
-
|
2
|
-
name 'DateTime'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
module Types
|
4
|
+
DateTimeType = GraphQL::Types::ISO8601DateTime
|
6
5
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
name 'Post'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
3
|
+
module Types
|
4
|
+
class PostType < BaseObject
|
5
|
+
field :id, ID, null: false
|
6
|
+
field :title, String, null: false
|
7
|
+
field :body, String, null: false
|
8
|
+
field :category, CategoryType, null: false
|
9
|
+
field :views_count, Int, null: false
|
10
|
+
field :likes_count, Int, null: false
|
11
|
+
field :comments_count, Int, null: false
|
12
|
+
field :is_published, Boolean, null: false, method: :published?
|
13
|
+
field :published_at, DateTimeType, null: false
|
14
|
+
end
|
13
15
|
end
|
@@ -1,7 +1,8 @@
|
|
1
|
-
|
2
|
-
name 'Query'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module Types
|
4
|
+
class QueryType < Types::BaseObject
|
5
|
+
field :categories, resolver: Resolvers::CategorySearch
|
6
|
+
field :posts, resolver: Resolvers::PostSearch
|
7
|
+
end
|
7
8
|
end
|
data/example/app/models/post.rb
CHANGED
data/example/bin/bundle
CHANGED
data/example/bin/rails
CHANGED
data/example/bin/rake
CHANGED
data/example/bin/setup
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
require 'pathname'
|
3
5
|
require 'fileutils'
|
4
|
-
include FileUtils
|
6
|
+
include FileUtils # rubocop:disable Style/MixinUsage
|
5
7
|
|
6
8
|
# path to your application root.
|
7
|
-
APP_ROOT = Pathname.new File.expand_path('
|
9
|
+
APP_ROOT = Pathname.new File.expand_path('..', __dir__)
|
8
10
|
|
9
11
|
def system!(*args)
|
10
12
|
system(*args) || abort("\n== Command #{args} failed ==")
|
data/example/bin/update
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
require 'pathname'
|
3
5
|
require 'fileutils'
|
4
|
-
include FileUtils
|
6
|
+
include FileUtils # rubocop:disable Style/MixinUsage
|
5
7
|
|
6
8
|
# path to your application root.
|
7
|
-
APP_ROOT = Pathname.new File.expand_path('
|
9
|
+
APP_ROOT = Pathname.new File.expand_path('..', __dir__)
|
8
10
|
|
9
11
|
def system!(*args)
|
10
12
|
system(*args) || abort("\n== Command #{args} failed ==")
|
data/example/config.ru
CHANGED
@@ -3,7 +3,7 @@ require_relative 'boot'
|
|
3
3
|
require "rails"
|
4
4
|
# Pick the frameworks you want:
|
5
5
|
require "active_model/railtie"
|
6
|
-
|
6
|
+
require "active_job/railtie"
|
7
7
|
require "active_record/railtie"
|
8
8
|
require "action_controller/railtie"
|
9
9
|
# require "action_mailer/railtie"
|
data/example/db/schema.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
13
|
+
ActiveRecord::Schema.define(version: 2017_05_07_175133) do
|
14
14
|
|
15
15
|
create_table "categories", force: :cascade do |t|
|
16
16
|
t.string "name", null: false
|
File without changes
|
@@ -1,26 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SearchObject
|
2
4
|
module Plugin
|
3
5
|
module Graphql
|
4
6
|
def self.included(base)
|
7
|
+
raise NotIncludedInResolverError, base unless base.ancestors.include? GraphQL::Schema::Resolver
|
8
|
+
|
5
9
|
base.include SearchObject::Plugin::Enum
|
6
10
|
base.extend ClassMethods
|
7
11
|
end
|
8
12
|
|
9
13
|
attr_reader :object, :context
|
10
14
|
|
11
|
-
def initialize(filters: {}, object: nil, context: {}, scope: nil)
|
15
|
+
def initialize(filters: {}, object: nil, context: {}, scope: nil, field: nil)
|
12
16
|
@object = object
|
13
17
|
@context = context
|
14
18
|
|
15
|
-
super filters: filters, scope: scope
|
19
|
+
super filters: filters, scope: scope, field: field
|
20
|
+
end
|
21
|
+
|
22
|
+
# NOTE(rstankov): GraphQL::Schema::Resolver interface
|
23
|
+
# Documentation - http://graphql-ruby.org/fields/resolvers.html#using-resolver
|
24
|
+
def resolve_with_support(args = {})
|
25
|
+
self.params = args.to_h
|
26
|
+
results
|
16
27
|
end
|
17
28
|
|
18
29
|
module ClassMethods
|
19
30
|
def option(name, options = {}, &block)
|
20
|
-
|
21
|
-
|
31
|
+
type = options.fetch(:type) { raise MissingTypeDefinitionError, name }
|
32
|
+
options[:enum] = type.values.map { |value, enum_value| enum_value.value || value } if type.respond_to?(:values)
|
22
33
|
|
23
|
-
|
34
|
+
argument(
|
35
|
+
name.to_s,
|
36
|
+
options[:type],
|
37
|
+
required: options[:required] || false,
|
38
|
+
description: options[:description],
|
39
|
+
camelize: options[:camelize]
|
40
|
+
)
|
24
41
|
|
25
42
|
super(name, options, &block)
|
26
43
|
end
|
@@ -28,35 +45,11 @@ module SearchObject
|
|
28
45
|
def types
|
29
46
|
GraphQL::Define::TypeDefiner.instance
|
30
47
|
end
|
48
|
+
end
|
31
49
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
new(filters: args.to_h, object: object, context: context).results
|
36
|
-
end
|
37
|
-
|
38
|
-
def arguments
|
39
|
-
config[:args] ||= {}
|
40
|
-
end
|
41
|
-
|
42
|
-
def type(value = :default, &block)
|
43
|
-
return config[:type] if value == :default && !block_given?
|
44
|
-
config[:type] = block_given? ? GraphQL::ObjectType.define(&block) : value
|
45
|
-
end
|
46
|
-
|
47
|
-
def complexity(value = :default)
|
48
|
-
return config[:complexity] || 1 if value == :default
|
49
|
-
config[:complexity] = value
|
50
|
-
end
|
51
|
-
|
52
|
-
def description(value = :default)
|
53
|
-
return config[:description] if value == :default
|
54
|
-
config[:description] = value
|
55
|
-
end
|
56
|
-
|
57
|
-
def deprecation_reason(value = :default)
|
58
|
-
return config[:deprecation_reason] if value == :default
|
59
|
-
config[:deprecation_reason] = value
|
50
|
+
class NotIncludedInResolverError < ArgumentError
|
51
|
+
def initialize(base)
|
52
|
+
super "#{base.name} should inherit from GraphQL::Schema::Resolver. Current ancestors #{base.ancestors}"
|
60
53
|
end
|
61
54
|
end
|
62
55
|
|
@@ -65,20 +58,6 @@ module SearchObject
|
|
65
58
|
super "GraphQL type has to passed as :type to '#{name}' option"
|
66
59
|
end
|
67
60
|
end
|
68
|
-
|
69
|
-
# :api: private
|
70
|
-
module Helper
|
71
|
-
module_function
|
72
|
-
|
73
|
-
def build_argument(name, options)
|
74
|
-
argument = GraphQL::Argument.new
|
75
|
-
argument.name = name.to_s
|
76
|
-
argument.type = options.fetch(:type) { raise MissingTypeDefinitionError, name }
|
77
|
-
argument.default_value = options[:default] if options.key? :default
|
78
|
-
argument.description = options[:description] if options.key? :description
|
79
|
-
argument
|
80
|
-
end
|
81
|
-
end
|
82
61
|
end
|
83
62
|
end
|
84
63
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'English'
|
5
6
|
require 'search_object/plugin/graphql/version'
|
@@ -19,13 +20,12 @@ Gem::Specification.new do |spec|
|
|
19
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
21
|
spec.require_paths = ['lib']
|
21
22
|
|
22
|
-
spec.add_dependency '
|
23
|
-
spec.add_dependency '
|
23
|
+
spec.add_dependency 'graphql', '~> 1.8'
|
24
|
+
spec.add_dependency 'search_object', '~> 1.2.2'
|
24
25
|
|
25
|
-
spec.add_development_dependency 'bundler', '~> 1.13'
|
26
|
-
spec.add_development_dependency 'rake'
|
27
|
-
spec.add_development_dependency 'rspec', '~> 3.5'
|
28
|
-
spec.add_development_dependency 'rubocop', '0.46.0'
|
29
|
-
spec.add_development_dependency 'rubocop-rspec', '1.8.0'
|
30
26
|
spec.add_development_dependency 'coveralls'
|
27
|
+
spec.add_development_dependency 'rake'
|
28
|
+
spec.add_development_dependency 'rspec', '~> 3.8'
|
29
|
+
spec.add_development_dependency 'rubocop', '0.62.0'
|
30
|
+
spec.add_development_dependency 'rubocop-rspec', '1.31.0'
|
31
31
|
end
|
@@ -1,29 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
require 'graphql'
|
3
5
|
require 'ostruct'
|
4
6
|
require 'search_object/plugin/graphql'
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
{ 'id' => id }
|
10
|
-
end
|
8
|
+
Post = Struct.new(:id) do
|
9
|
+
def to_json(_options = {})
|
10
|
+
{ 'id' => id }
|
11
11
|
end
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
field :id, !types.ID
|
17
|
-
end
|
14
|
+
class PostType < GraphQL::Schema::Object
|
15
|
+
field :id, ID, null: false
|
16
|
+
end
|
18
17
|
|
18
|
+
describe SearchObject::Plugin::Graphql do
|
19
19
|
def define_schema(&block)
|
20
|
-
query_type = GraphQL::
|
21
|
-
|
20
|
+
query_type = Class.new(GraphQL::Schema::Object) do
|
21
|
+
graphql_name 'Query'
|
22
22
|
|
23
23
|
instance_eval(&block)
|
24
24
|
end
|
25
25
|
|
26
|
-
GraphQL::Schema
|
26
|
+
Class.new(GraphQL::Schema) do
|
27
27
|
query query_type
|
28
28
|
|
29
29
|
max_complexity 1000
|
@@ -31,7 +31,7 @@ describe SearchObject::Plugin::Graphql do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def define_search_class(&block)
|
34
|
-
Class.new do
|
34
|
+
Class.new(GraphQL::Schema::Resolver) do
|
35
35
|
include SearchObject.module(:graphql)
|
36
36
|
|
37
37
|
scope { [] }
|
@@ -45,20 +45,38 @@ describe SearchObject::Plugin::Graphql do
|
|
45
45
|
|
46
46
|
define_schema do
|
47
47
|
if search_object.type.nil?
|
48
|
-
field :posts,
|
48
|
+
field :posts, [PostType], resolver: search_object
|
49
49
|
else
|
50
|
-
field :posts,
|
50
|
+
field :posts, resolver: search_object
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
it '
|
56
|
-
|
55
|
+
it 'requires class to inherit from GraphQL::Schema::Resolver' do
|
56
|
+
expect do
|
57
|
+
Class.new { include SearchObject.module(:graphql) }
|
58
|
+
end.to raise_error SearchObject::Plugin::Graphql::NotIncludedInResolverError
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'can be used as GraphQL::Schema::Resolver' do
|
62
|
+
post_type = Class.new(GraphQL::Schema::Object) do
|
63
|
+
graphql_name 'Post'
|
64
|
+
|
65
|
+
field :id, GraphQL::Types::ID, null: false
|
66
|
+
end
|
67
|
+
|
68
|
+
search_object = define_search_class do
|
57
69
|
scope { [Post.new('1'), Post.new('2'), Post.new('3')] }
|
58
70
|
|
71
|
+
type [post_type], null: 1
|
72
|
+
|
59
73
|
option(:id, type: !types.ID) { |scope, value| scope.select { |p| p.id == value } }
|
60
74
|
end
|
61
75
|
|
76
|
+
schema = define_schema do
|
77
|
+
field :posts, resolver: search_object
|
78
|
+
end
|
79
|
+
|
62
80
|
result = schema.execute '{ posts(id: "2") { id } }'
|
63
81
|
|
64
82
|
expect(result).to eq(
|
@@ -73,19 +91,19 @@ describe SearchObject::Plugin::Graphql do
|
|
73
91
|
scope { object.posts }
|
74
92
|
end
|
75
93
|
|
76
|
-
parent_type = GraphQL::
|
77
|
-
|
94
|
+
parent_type = Class.new(GraphQL::Schema::Object) do
|
95
|
+
graphql_name 'Parent'
|
78
96
|
|
79
|
-
field :posts,
|
97
|
+
field :posts, [PostType], resolver: search_object
|
80
98
|
end
|
81
99
|
|
82
100
|
schema = define_schema do
|
83
|
-
field :parent, parent_type
|
84
|
-
resolve ->(_obj, _args, _ctx) { OpenStruct.new posts: [Post.new('from_parent')] }
|
85
|
-
end
|
101
|
+
field :parent, parent_type, null: false
|
86
102
|
end
|
87
103
|
|
88
|
-
|
104
|
+
root = OpenStruct.new(parent: OpenStruct.new(posts: [Post.new('from_parent')]))
|
105
|
+
|
106
|
+
result = schema.execute '{ parent { posts { id } } }', root_value: root
|
89
107
|
|
90
108
|
expect(result).to eq(
|
91
109
|
'data' => {
|
@@ -124,86 +142,40 @@ describe SearchObject::Plugin::Graphql do
|
|
124
142
|
)
|
125
143
|
end
|
126
144
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
field :title, types.String
|
133
|
-
end
|
145
|
+
describe 'option' do
|
146
|
+
it 'converts GraphQL::Schema::Enum to SearchObject enum' do
|
147
|
+
schema = define_search_class_and_return_schema do
|
148
|
+
enum_type = Class.new(GraphQL::Schema::Enum) do
|
149
|
+
graphql_name 'PostOrder'
|
134
150
|
|
135
|
-
|
136
|
-
|
151
|
+
value 'PRICE'
|
152
|
+
value 'DATE'
|
153
|
+
end
|
137
154
|
|
138
|
-
|
139
|
-
{
|
140
|
-
__type(name: "Query") {
|
141
|
-
name
|
142
|
-
fields {
|
143
|
-
name
|
144
|
-
deprecationReason
|
145
|
-
type {
|
146
|
-
name
|
147
|
-
fields {
|
148
|
-
name
|
149
|
-
}
|
150
|
-
}
|
151
|
-
}
|
152
|
-
}
|
153
|
-
}
|
154
|
-
SQL
|
155
|
+
option(:order, type: enum_type)
|
155
156
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
'name' => 'Query',
|
160
|
-
'fields' => [{
|
161
|
-
'name' => 'posts',
|
162
|
-
'deprecationReason' => nil,
|
163
|
-
'type' => {
|
164
|
-
'name' => 'Test',
|
165
|
-
'fields' => [{
|
166
|
-
'name' => 'title'
|
167
|
-
}]
|
168
|
-
}
|
169
|
-
}]
|
170
|
-
}
|
171
|
-
}
|
172
|
-
)
|
173
|
-
end
|
157
|
+
define_method(:apply_order_with_price) do |_scope|
|
158
|
+
[Post.new('price')]
|
159
|
+
end
|
174
160
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
end
|
161
|
+
define_method(:apply_order_with_date) do |_scope|
|
162
|
+
[Post.new('date')]
|
163
|
+
end
|
164
|
+
end
|
180
165
|
|
181
|
-
|
182
|
-
{
|
183
|
-
__type(name: "Query") {
|
184
|
-
name
|
185
|
-
fields {
|
186
|
-
name
|
187
|
-
}
|
188
|
-
}
|
189
|
-
}
|
190
|
-
QUERY
|
166
|
+
result = schema.execute '{ posts(order: PRICE) { id } }'
|
191
167
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
'name' => 'Query',
|
196
|
-
'fields' => []
|
168
|
+
expect(result).to eq(
|
169
|
+
'data' => {
|
170
|
+
'posts' => [Post.new('price').to_json]
|
197
171
|
}
|
198
|
-
|
199
|
-
|
200
|
-
end
|
172
|
+
)
|
173
|
+
end
|
201
174
|
|
202
|
-
describe 'option' do
|
203
175
|
it 'converts GraphQL::EnumType to SearchObject enum' do
|
204
176
|
schema = define_search_class_and_return_schema do
|
205
|
-
enum_type = GraphQL::
|
206
|
-
|
177
|
+
enum_type = Class.new(GraphQL::Schema::Enum) do
|
178
|
+
graphql_name 'TestEnum'
|
207
179
|
|
208
180
|
value 'PRICE'
|
209
181
|
value 'DATE'
|
@@ -245,9 +217,21 @@ describe SearchObject::Plugin::Graphql do
|
|
245
217
|
)
|
246
218
|
end
|
247
219
|
|
220
|
+
it 'accepts "required"' do
|
221
|
+
schema = define_search_class_and_return_schema do
|
222
|
+
option(:id, type: types.String, required: true) do |_scope, value|
|
223
|
+
[Post.new(value)]
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
result = schema.execute '{ posts { id } }'
|
228
|
+
|
229
|
+
expect(result['errors'][0]['message']).to eq("Field 'posts' is missing required arguments: id")
|
230
|
+
end
|
231
|
+
|
248
232
|
it 'accepts description' do
|
249
233
|
schema = define_search_class_and_return_schema do
|
250
|
-
type PostType
|
234
|
+
type PostType, null: true
|
251
235
|
|
252
236
|
option('option', type: types.String, description: 'what this argument does') { [] }
|
253
237
|
end
|
@@ -281,6 +265,40 @@ describe SearchObject::Plugin::Graphql do
|
|
281
265
|
)
|
282
266
|
end
|
283
267
|
|
268
|
+
it 'accepts camelize' do
|
269
|
+
schema = define_search_class_and_return_schema do
|
270
|
+
type PostType, null: true
|
271
|
+
|
272
|
+
option('option_field', type: types.String, camelize: false)
|
273
|
+
end
|
274
|
+
|
275
|
+
result = schema.execute <<-SQL
|
276
|
+
{
|
277
|
+
__type(name: "Query") {
|
278
|
+
name
|
279
|
+
fields {
|
280
|
+
args {
|
281
|
+
name
|
282
|
+
}
|
283
|
+
}
|
284
|
+
}
|
285
|
+
}
|
286
|
+
SQL
|
287
|
+
|
288
|
+
expect(result.to_h).to eq(
|
289
|
+
'data' => {
|
290
|
+
'__type' => {
|
291
|
+
'name' => 'Query',
|
292
|
+
'fields' => [{
|
293
|
+
'args' => [{
|
294
|
+
'name' => 'option_field'
|
295
|
+
}]
|
296
|
+
}]
|
297
|
+
}
|
298
|
+
}
|
299
|
+
)
|
300
|
+
end
|
301
|
+
|
284
302
|
it 'raises error when no type is given' do
|
285
303
|
expect { define_search_class { option :name } }.to raise_error described_class::MissingTypeDefinitionError
|
286
304
|
end
|