Skip to content

Commit

Permalink
always require node descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
rmosolgo committed May 3, 2015
1 parent ca5a891 commit dbf4988
Show file tree
Hide file tree
Showing 19 changed files with 63 additions and 2 deletions.
1 change: 1 addition & 0 deletions lib/graphql/introspection/call_type.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class GraphQL::Introspection::CallType < GraphQL::Node
exposes "GraphQL::Call"
desc 'A call that can be made on a node'
field.string(:name)
field.string(:arguments)

Expand Down
1 change: 1 addition & 0 deletions lib/graphql/introspection/field_type.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class GraphQL::Introspection::FieldType < GraphQL::Node
exposes "GraphQL::Field"
desc "A property of a node"
field.string(:name)
field.string(:type)
field.introspection_connection(:calls)
Expand Down
1 change: 1 addition & 0 deletions lib/graphql/introspection/root_call_argument_node.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class GraphQL::Introspection::RootCallArgumentNode < GraphQL::Node
exposes "GraphQL::RootCallArgument"
desc "An argument to a query root call"
field.string(:name)
field.string(:type)
end
2 changes: 2 additions & 0 deletions lib/graphql/introspection/root_call_type.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
class GraphQL::Introspection::RootCallType < GraphQL::Node
exposes "GraphQL::RootCall"
desc "A call that can be used as the root of a query"

field.string(:name)
field.string(:returns)
field.introspection_connection(:arguments)
Expand Down
1 change: 1 addition & 0 deletions lib/graphql/introspection/schema_type.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class GraphQL::Introspection::SchemaType < GraphQL::Node
exposes "GraphQL::Schema::Schema"
desc "The schema for a GraphQL endpoint"
field.introspection_connection(:calls)
field.introspection_connection(:types)

Expand Down
1 change: 1 addition & 0 deletions lib/graphql/introspection/type_type.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class GraphQL::Introspection::TypeType < GraphQL::Node
exposes "GraphQL::Node"
desc "A node type in this GraphQL system"
type "__type__"
field.string(:name)
field.string(:description)
Expand Down
5 changes: 3 additions & 2 deletions lib/graphql/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# @example Expose a class in your app
# class PostNode < GraphQL::Node
# exposes('Post')
#
# desc('A blog post about something interesting')
# cursor(:id)
#
# field.number(:id)
Expand All @@ -22,6 +22,7 @@
# @example Expose a data type
# class DateType < GraphQL::Node
# exposes "Date"
# desc('A given year-month-day')
# type :date
# call :minus_days, -> (prev_value, minus_days) { prev_value - minus_days.to_i }
# field.number(:year)
Expand Down Expand Up @@ -147,7 +148,7 @@ def desc(describe)

# The description of this node
def description
@description || raise("#{name}.description isn't defined")
@description
end

# @param [String] type_name
Expand Down
5 changes: 5 additions & 0 deletions lib/graphql/schema/schema_validation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ class GraphQL::Schema::SchemaValidation
def validate(schema)
schema.types.each do |type_name, type_class|

if type_class.exposes_class_names.any?
# make sure description is present
type_class.description.blank? && raise("#{type_class.name} must have a description: declare one with `desc 'my description'` in the class definition!")
end

type_class.exposes_class_names.each do |exposes_class_name|
begin
Object.const_get(exposes_class_name)
Expand Down
1 change: 1 addition & 0 deletions lib/graphql/types/boolean_type.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
class GraphQL::Types::BooleanType < GraphQL::Types::ObjectType
exposes("TrueClass", "FalseClass")
desc("True or false")
end
1 change: 1 addition & 0 deletions lib/graphql/types/date_time_type.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class GraphQL::Types::DateTimeType < GraphQL::Types::DateType
exposes "DateTime"
desc("A date with hours, minutes and seconds")
type :date_time
field.number(:hour)
field.number(:min)
Expand Down
1 change: 1 addition & 0 deletions lib/graphql/types/date_type.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class GraphQL::Types::DateType < GraphQL::Node
exposes "Date"
desc "A given year-month-day"
type :date
field.number(:year)
field.number(:month)
Expand Down
1 change: 1 addition & 0 deletions lib/graphql/types/number_type.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
class GraphQL::Types::NumberType < GraphQL::Types::ObjectType
exposes("Numeric")
desc("A number (float or int)")
end
1 change: 1 addition & 0 deletions lib/graphql/types/object_type.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class GraphQL::Types::ObjectType < GraphQL::Node
exposes("Object")
desc("Any object")
def as_result
target
end
Expand Down
1 change: 1 addition & 0 deletions lib/graphql/types/string_type.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
class GraphQL::Types::StringType < GraphQL::Types::ObjectType
exposes("String")
desc("A string of text")
end
1 change: 1 addition & 0 deletions lib/graphql/types/time_type.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class GraphQL::Types::TimeType < GraphQL::Types::DateTimeType
exposes "Time"
desc("A date-time with milliseconds")
type :time
field.number(:usec)
end
8 changes: 8 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Nodes are delegators that wrap objects in your app. You must whitelist fields by
```ruby
class FishNode < GraphQL::Node
exposes "Fish"
desc "A slippery, delicious animal that lives in water"
cursor(:id)
field.number(:id)
field.string(:name)
Expand All @@ -49,6 +50,7 @@ You can also declare connections between objects:
```ruby
class AquariumNode < GraphQL::Node
exposes "Aquarium"
desc "A place where fish live"
cursor(:id)
field.number(:id)
field.number(:occupancy)
Expand Down Expand Up @@ -193,3 +195,9 @@ You could do something like this [inside a Rails controller](https://github.com/
- Implement calls as arguments
- double-check how to handle `pals.first(3) { count }`
- Implement call argument introspection (wait for spec)

## Goals:

- Implement the GraphQL spec (when Facebook releases it) & support a Relay front end
- Provide idiomatic, plain-Ruby API with similarities to reference implementation where possible
- Support `graphql-rails`
16 changes: 16 additions & 0 deletions spec/graphql/node_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,20 @@
end
end
end

describe '.description' do
before do
@prev_desc = Nodes::AlbumNode.description
end

after do
Nodes::AlbumNode.desc(@prev_desc)
end

it 'returns the descripiton declared with `.desc`' do
new_desc = "A photo album"
Nodes::AlbumNode.desc(new_desc)
assert_equal(new_desc, Nodes::AlbumNode.description)
end
end
end
14 changes: 14 additions & 0 deletions spec/graphql/schema/schema_validation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,18 @@
assert_raises(GraphQL::FieldNotImplementedError) { schema.validate }
end
end

describe 'when a description is missing' do
before do
@prev_desc = Nodes::PostNode.description
Nodes::PostNode.desc(nil)
end
after do
Nodes::PostNode.desc(@prev_desc)
end

it 'raises an error' do
assert_raises(RuntimeError) { schema.validate }
end
end
end
3 changes: 3 additions & 0 deletions spec/support/nodes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def length
class CommentNode < ApplicationNode
node_for Comment
exposes "Comment"
desc("Comment on a blog post")
field.string(:content)
field.letter_selection(:letters)
field.post(:post)
Expand All @@ -96,6 +97,7 @@ class ThumbUpNode < ApplicationNode
node_for(Like)
exposes "Like"
type "upvote"
desc("A show of support for a post")
field.number :post_id
field.number :person_id
def id
Expand All @@ -105,6 +107,7 @@ def id

class ContextNode < GraphQL::Node
exposes "Context"
desc("A request context")
field.string(:person_name)
field.boolean(:present)

Expand Down

0 comments on commit dbf4988

Please sign in to comment.