Skip to content

Commit

Permalink
Merge branch 'master' into doc-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
gjtorikian authored Jun 14, 2019
2 parents c635eec + bd23c98 commit 389cd3f
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 14 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ In your ERB layouts, there are several helper methods you can use. The helper me
* `slugify(str)` - This slugifies the given string.
* `include(filename, opts)` - This embeds a template from your `includes` folder, passing along the local options provided.
* `markdownify(string)` - This converts a string into HTML via CommonMarker.
* `graphql_operation_types`, `graphql_mutation_types`, `graphql_object_types`, `graphql_interface_types`, `graphql_enum_types`, `graphql_union_types`, `graphql_input_object_types`, `graphql_scalar_types` - Collections of the various GraphQL types.
* `graphql_operation_types`, `graphql_mutation_types`, `graphql_object_types`, `graphql_interface_types`, `graphql_enum_types`, `graphql_union_types`, `graphql_input_object_types`, `graphql_scalar_types`, `graphql_directive_types` - Collections of the various GraphQL types.

To call these methods within templates, you must use the dot notation, such as `<%= slugify.(text) %>`.

Expand All @@ -127,8 +127,8 @@ The following options are available:
| `delete_output` | Deletes `output_dir` before generating content. | `false` |
| `pipeline_config` | Defines two sub-keys, `pipeline` and `context`, which are used by `html-pipeline` when rendering your output. | `pipeline` has `ExtendedMarkdownFilter`, `EmojiFilter`, and `TableOfContentsFilter`. `context` has `gfm: false` and `asset_root` set to GitHub's CDN. |
| `renderer` | The rendering class to use. | `GraphQLDocs::Renderer`
| `templates` | The templates to use when generating HTML. You may override any of the following keys: `default`, `includes`, `operations`, `objects`, `mutations`, `interfaces`, `enums`, `unions`, `input_objects`, `scalars`. | The defaults are found in _lib/graphql-docs/layouts/_.
| `landing_pages` | The landing page to use when generating HTML for each type. You may override any of the following keys: `index`, `query`, `object`, `mutation`, `interface`, `enum`, `union`, `input_object`, `scalar`. | The defaults are found in _lib/graphql-docs/landing\_pages/_.
| `templates` | The templates to use when generating HTML. You may override any of the following keys: `default`, `includes`, `operations`, `objects`, `mutations`, `interfaces`, `enums`, `unions`, `input_objects`, `scalars`, `directives`. | The defaults are found in _lib/graphql-docs/layouts/_.
| `landing_pages` | The landing page to use when generating HTML for each type. You may override any of the following keys: `index`, `query`, `object`, `mutation`, `interface`, `enum`, `union`, `input_object`, `scalar`, `directive`. | The defaults are found in _lib/graphql-docs/landing\_pages/_.
| `classes` | Additional class names you can provide to certain elements. | The full list is available in _lib/graphql-docs/configuration.rb_.
| `notices` | A proc used to add notices to schema members. See *Customizing Notices* section below. | `nil` |

Expand Down
2 changes: 2 additions & 0 deletions lib/graphql-docs/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module Configuration
unions: "#{File.dirname(__FILE__)}/layouts/graphql_unions.html",
input_objects: "#{File.dirname(__FILE__)}/layouts/graphql_input_objects.html",
scalars: "#{File.dirname(__FILE__)}/layouts/graphql_scalars.html",
directives: "#{File.dirname(__FILE__)}/layouts/graphql_directives.html",
},

landing_pages: {
Expand All @@ -49,6 +50,7 @@ module Configuration
union: "#{File.dirname(__FILE__)}/landing_pages/union.md",
input_object: "#{File.dirname(__FILE__)}/landing_pages/input_object.md",
scalar: "#{File.dirname(__FILE__)}/landing_pages/scalar.md",
directive: "#{File.dirname(__FILE__)}/landing_pages/directive.md",

variables: {} # only used for ERB landing pages
},
Expand Down
18 changes: 16 additions & 2 deletions lib/graphql-docs/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ def initialize(parsed_schema, options)

@renderer = @options[:renderer].new(@parsed_schema, @options)

%i(operations objects mutations interfaces enums unions input_objects scalars).each do |sym|
%i(operations objects mutations interfaces enums unions input_objects scalars directives).each do |sym|
if !File.exist?(@options[:templates][sym])
raise IOError, "`#{sym}` template #{@options[:templates][sym]} was not found"
end
instance_variable_set("@graphql_#{sym}_template", ERB.new(File.read(@options[:templates][sym])))
end

%i(index object query mutation interface enum union input_object scalar).each do |sym|
%i(index object query mutation interface enum union input_object scalar directive).each do |sym|
if @options[:landing_pages][sym].nil?
instance_variable_set("@#{sym}_landing_page", nil)
elsif !File.exist?(@options[:landing_pages][sym])
Expand Down Expand Up @@ -58,6 +58,7 @@ def generate
create_graphql_union_pages
create_graphql_input_object_pages
create_graphql_scalar_pages
create_graphql_directive_pages

unless @graphql_index_landing_page.nil?
write_file('static', 'index', @graphql_index_landing_page, trim: false)
Expand Down Expand Up @@ -95,6 +96,10 @@ def generate
write_file('static', 'scalar', @graphql_scalar_landing_page, trim: false)
end

unless @graphql_directive_landing_page.nil?
write_file('static', 'directive', @graphql_directive_landing_page, trim: false)
end

if @options[:use_default_styles]
assets_dir = File.join(File.dirname(__FILE__), 'layouts', 'assets')
FileUtils.mkdir_p(File.join(@options[:output_dir], 'assets'))
Expand Down Expand Up @@ -196,6 +201,15 @@ def create_graphql_scalar_pages
end
end

def create_graphql_directive_pages
graphql_directive_types.each do |directive_type|
opts = default_generator_options(type: directive_type)

contents = @graphql_directives_template.result(OpenStruct.new(opts).instance_eval { binding })
write_file('directive', directive_type[:name], contents)
end
end

private

def default_generator_options(opts = {})
Expand Down
4 changes: 4 additions & 0 deletions lib/graphql-docs/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ def graphql_scalar_types
@parsed_schema[:scalar_types] || []
end

def graphql_directive_types
@parsed_schema[:directive_types] || []
end

def split_into_metadata_and_contents(contents, parse: true)
opts = {}
pieces = yaml_split(contents)
Expand Down
9 changes: 9 additions & 0 deletions lib/graphql-docs/landing_pages/directive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: Directives
---

# Directives

Directives provide a way to describe alternate runtime execution and type validation behavior in a GraphQL document.

For more information, see [the GraphQL spec](https://graphql.github.io/graphql-spec/draft/#sec-Language.Directives).
15 changes: 15 additions & 0 deletions lib/graphql-docs/layouts/graphql_directives.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<h1><%= type[:name] %></h1>

<%= include.('notices.html', notices: type[:notices]) %>

<%= type[:description] %>

<%= include.('locations.html', locations: type[:locations]) %>

<% unless type[:arguments].empty? %>

<h2>Arguments</h2>

<%= include.('arguments.html', arguments: type[:arguments]) %>

<% end %>
9 changes: 9 additions & 0 deletions lib/graphql-docs/layouts/includes/locations.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<h2 id="locations">Locations</h2>

<ul>

<% locations.each do |location| %>
<li><%= location %></li>
<% end %>

</ul>
14 changes: 14 additions & 0 deletions lib/graphql-docs/layouts/includes/sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,18 @@
<% end %>
</ul>
</li>

<li>
<p><a href="<%= base_url %>/directive">Directives</a></p>
<ul class="menu-root">
<% graphql_directive_types.().each do |type| %>
<% @name = type[:name] %>
<li>
<a href="<%= base_url %>/directive/<%= @name.downcase %>/" class="sidebar-link<% if title == @name %> current<% end %>">
<%= @name %>
</a>
</li>
<% end %>
</ul>
</li>
</ul>
2 changes: 1 addition & 1 deletion lib/graphql-docs/layouts/includes/values.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<h3 id="fields">Values</h3>
<h3 id="values">Values</h3>

<% values.each do |value| %>

Expand Down
29 changes: 22 additions & 7 deletions lib/graphql-docs/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def initialize(schema, options)
union_types: [],
input_object_types: [],
scalar_types: [],
directive_types: [],
}
end

Expand Down Expand Up @@ -133,13 +134,20 @@ def parse
end
end

@processed_schema[:mutation_types].sort_by! { |o| o[:name] }
@processed_schema[:object_types].sort_by! { |o| o[:name] }
@processed_schema[:interface_types].sort_by! { |o| o[:name] }
@processed_schema[:enum_types].sort_by! { |o| o[:name] }
@processed_schema[:union_types].sort_by! { |o| o[:name] }
@processed_schema[:input_object_types].sort_by! { |o| o[:name] }
@processed_schema[:scalar_types].sort_by! { |o| o[:name] }
@schema.directives.each_value do |directive|
data = {}
data[:notices] = @options[:notices].call(directive.name)

data[:name] = directive.name
data[:description] = directive.description
data[:locations] = directive.locations

data[:arguments], _ = fetch_fields(directive.arguments, directive.name)

@processed_schema[:directive_types] << data
end

sort_by_name!

@processed_schema[:interface_types].each do |interface|
interface[:implemented_by] = []
Expand Down Expand Up @@ -229,5 +237,12 @@ def generate_type(type)
def argument?(field)
field.is_a?(::GraphQL::Argument)
end

def sort_by_name!
@processed_schema.each_pair do |key, value|
next if key == :operation_types || key == :root_types
value.sort_by! { |o| o[:name] }
end
end
end
end
3 changes: 2 additions & 1 deletion test/graphql-docs/generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def test_that_it_does_not_require_default

GraphQLDocs::Generator.new(@results, options)
end

focus
def test_that_it_works
options = deep_copy(GraphQLDocs::Configuration::GRAPHQLDOCS_DEFAULTS)
options[:output_dir] = @output_dir
Expand All @@ -69,6 +69,7 @@ def test_that_it_works
assert File.exist? File.join(@output_dir, 'object', 'repository', 'index.html')
assert File.exist? File.join(@output_dir, 'scalar', 'boolean', 'index.html')
assert File.exist? File.join(@output_dir, 'union', 'issuetimelineitem', 'index.html')
assert File.exist? File.join(@output_dir, 'directive', 'deprecated', 'index.html')

# content sanity checks
Dir.glob("#{@output_dir}/**/*.html") do |file|
Expand Down
15 changes: 15 additions & 0 deletions test/graphql-docs/parser_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ def test_groups_items_by_type
assert @gh_results[:enum_types]
assert @gh_results[:union_types]
assert @gh_results[:mutation_types]
assert @gh_results[:directive_types]
end

def test_directives
names = @gh_results[:directive_types].map { |t| t[:name] }
assert_equal %w(deprecated include preview skip), names

preview_directive = @gh_results[:directive_types].find { |t| t[:name] == 'deprecated' }
ap preview_directive
assert_equal %i(FIELD_DEFINITION ENUM_VALUE), preview_directive[:locations]

assert_equal 'Marks an element of a GraphQL schema as no longer supported.', preview_directive[:description]
reason_arg = preview_directive[:arguments].first
assert_equal 'reason', reason_arg[:name]
assert_equal 'Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted in [Markdown](https://daringfireball.net/projects/markdown/).', reason_arg[:description]
end

def test_mutationless_schemas_do_not_explode
Expand Down

0 comments on commit 389cd3f

Please sign in to comment.