Skip to content

Commit

Permalink
List Queries in sidebar (#156)
Browse files Browse the repository at this point in the history
* Queries in sidebar

* Fix tests that broke when generator behavior changed
  • Loading branch information
denisahearn authored Dec 10, 2024
1 parent 222703c commit 2aec020
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 55 deletions.
1 change: 1 addition & 0 deletions lib/graphql-docs/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module Configuration

operations: "#{File.dirname(__FILE__)}/layouts/graphql_operations.html",
objects: "#{File.dirname(__FILE__)}/layouts/graphql_objects.html",
queries: "#{File.dirname(__FILE__)}/layouts/graphql_queries.html",
mutations: "#{File.dirname(__FILE__)}/layouts/graphql_mutations.html",
interfaces: "#{File.dirname(__FILE__)}/layouts/graphql_interfaces.html",
enums: "#{File.dirname(__FILE__)}/layouts/graphql_enums.html",
Expand Down
16 changes: 13 additions & 3 deletions lib/graphql-docs/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def initialize(parsed_schema, options)

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

%i[operations objects mutations interfaces enums unions input_objects scalars directives].each do |sym|
%i[operations objects queries mutations interfaces enums unions input_objects scalars directives].each do |sym|
raise IOError, "`#{sym}` template #{@options[:templates][sym]} was not found" unless File.exist?(@options[:templates][sym])

instance_variable_set("@graphql_#{sym}_template", ERB.new(File.read(@options[:templates][sym])))
Expand Down Expand Up @@ -52,8 +52,9 @@ def initialize(parsed_schema, options)
def generate
FileUtils.rm_rf(@options[:output_dir]) if @options[:delete_output]

has_query = create_graphql_query_pages
has_query = create_graphql_operation_pages
create_graphql_object_pages
create_graphql_query_pages
create_graphql_mutation_pages
create_graphql_interface_pages
create_graphql_enum_pages
Expand Down Expand Up @@ -96,7 +97,7 @@ def generate
true
end

def create_graphql_query_pages
def create_graphql_operation_pages
graphql_operation_types.each do |query_type|
metadata = ''
next unless query_type[:name] == graphql_root_types['query']
Expand Down Expand Up @@ -129,6 +130,15 @@ def create_graphql_object_pages
end
end

def create_graphql_query_pages
graphql_query_types.each do |query|
opts = default_generator_options(type: query)

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

def create_graphql_mutation_pages
graphql_mutation_types.each do |mutation|
opts = default_generator_options(type: mutation)
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 @@ -36,6 +36,10 @@ def graphql_operation_types
@parsed_schema[:operation_types] || []
end

def graphql_query_types
@parsed_schema[:query_types] || []
end

def graphql_mutation_types
@parsed_schema[:mutation_types] || []
end
Expand Down
6 changes: 5 additions & 1 deletion lib/graphql-docs/landing_pages/query.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
---
title: Queries
---
Every GraphQL schema has a root type for both queries and mutations. The [query type](http://spec.graphql.org/draft/#sec-Type-System) defines GraphQL operations that retrieve data from the server.
Every GraphQL schema has a root type for both queries and mutations.

The query type defines GraphQL operations that retrieve data from the server.

For more information, see [the GraphQL spec](http://spec.graphql.org/draft/#sec-Type-System).
16 changes: 0 additions & 16 deletions lib/graphql-docs/layouts/graphql_operations.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
<h1><%= type[:name] %></h1>

<%= type[:description] %>

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

<h2>Connections</h2>

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

<% end %>

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

<h2>Fields</h2>

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

<% end %>
22 changes: 22 additions & 0 deletions lib/graphql-docs/layouts/graphql_queries.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<h1><%= type[:name] %></h1>

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

<%= type[:description] %>

<% if !type[:arguments].empty? %>

<h2>Arguments</h2>

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

<% end %>


<% if !type[:return_fields].empty? %>

<h2>Return fields</h2>

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

<% end %>
24 changes: 19 additions & 5 deletions lib/graphql-docs/layouts/includes/sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</li>

<li>
<p>Queries</p>
<p>Operations</p>
<ul class="menu-root">
<li>
<a href="<%= base_url %>/operation/query/" class="sidebar-link<% if title == "Query" %> current<% end %>">
Expand All @@ -23,12 +23,12 @@
</li>

<li>
<p><a href="<%= base_url %>/object">Objects</a></p>
<p><a href="<%= base_url %>/operation/query">Queries</a></p>
<ul class="menu-root">
<% graphql_object_types.().each do |type| %>
<% @name = type[:name] %>
<% graphql_query_types.().each do |type| %>
<% @name = type[:name] %>
<li>
<a href="<%= base_url %>/object/<%= @name.downcase %>/" class="sidebar-link<% if title == @name %> current<% end %>">
<a href="<%= base_url %>/query/<%= @name.downcase %>/" class="sidebar-link<% if title == @name %> current<% end %>">
<%= @name %>
</a>
</li>
Expand All @@ -50,6 +50,20 @@
</ul>
</li>

<li>
<p><a href="<%= base_url %>/object">Objects</a></p>
<ul class="menu-root">
<% graphql_object_types.().each do |type| %>
<% @name = type[:name] %>
<li>
<a href="<%= base_url %>/object/<%= @name.downcase %>/" class="sidebar-link<% if title == @name %> current<% end %>">
<%= @name %>
</a>
</li>
<% end %>
</ul>
</li>

<li>
<p><a href="<%= base_url %>/interface">Interfaces</a></p>
<ul class="menu-root">
Expand Down
20 changes: 19 additions & 1 deletion lib/graphql-docs/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def initialize(schema, options)

@processed_schema = {
operation_types: [],
query_types: [],
mutation_types: [],
object_types: [],
interface_types: [],
Expand Down Expand Up @@ -51,8 +52,25 @@ def parse
if data[:name] == root_types['query']
data[:interfaces] = object.interfaces.map(&:graphql_name).sort
data[:fields], data[:connections] = fetch_fields(object.fields, object.graphql_name)

@processed_schema[:operation_types] << data

object.fields.each_value do |query|
h = {}

h[:notices] = @options[:notices].call([object.graphql_name, query.graphql_name].join('.'))
h[:name] = query.graphql_name
h[:description] = query.description
h[:arguments], = fetch_fields(query.arguments, [object.graphql_name, query.graphql_name].join('.'))

return_type = query.type
if return_type.unwrap.respond_to?(:fields)
h[:return_fields], = fetch_fields(return_type.unwrap.fields, return_type.graphql_name)
else # it is a scalar return type
h[:return_fields], = fetch_fields({ return_type.graphql_name => query }, return_type.graphql_name)
end

@processed_schema[:query_types] << h
end
elsif data[:name] == root_types['mutation']
@processed_schema[:operation_types] << data

Expand Down
10 changes: 0 additions & 10 deletions test/graphql-docs/fixtures/named-root-schema.graphql

This file was deleted.

24 changes: 5 additions & 19 deletions test/graphql-docs/generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ def setup
@tiny_parser = GraphQLDocs::Parser.new(tiny_schema, {})
@tiny_results = @tiny_parser.parse

named_root_schema = File.read(File.join(fixtures_dir, 'named-root-schema.graphql'))
@named_root_parser = GraphQLDocs::Parser.new(named_root_schema, {})
@named_root_results = @named_root_parser.parse

@output_dir = File.join(fixtures_dir, 'output')
end

Expand Down Expand Up @@ -66,6 +62,7 @@ def test_that_it_works
assert File.exist? File.join(@output_dir, 'enum', 'issuestate', 'index.html')
assert File.exist? File.join(@output_dir, 'input_object', 'projectorder', 'index.html')
assert File.exist? File.join(@output_dir, 'interface', 'reactable', 'index.html')
assert File.exist? File.join(@output_dir, 'query', 'codeofconduct', 'index.html')
assert File.exist? File.join(@output_dir, 'mutation', 'addcomment', 'index.html')
assert File.exist? File.join(@output_dir, 'object', 'repository', 'index.html')
assert File.exist? File.join(@output_dir, 'scalar', 'boolean', 'index.html')
Expand Down Expand Up @@ -136,18 +133,6 @@ def test_that_it_sets_classes
assert_match(/<div class="field-entry my-4">/, object)
end

def test_that_named_query_root_generates_fields
options = deep_copy(GraphQLDocs::Configuration::GRAPHQLDOCS_DEFAULTS)
options[:output_dir] = @output_dir

generator = GraphQLDocs::Generator.new(@named_root_results, options)
generator.generate

object = File.read File.join(@output_dir, 'operation', 'query', 'index.html')

assert_match(/Do a thing/, object)
end

def test_that_missing_landing_pages_are_reported
options = deep_copy(GraphQLDocs::Configuration::GRAPHQLDOCS_DEFAULTS)
options[:landing_pages][:index] = 'BOGUS'
Expand Down Expand Up @@ -202,9 +187,9 @@ def test_that_empty_html_lines_not_interpreted_by_markdown
generator = GraphQLDocs::Generator.new(@tiny_results, options)
generator.generate

contents = File.read File.join(@output_dir, 'operation', 'query', 'index.html')
contents = File.read File.join(@output_dir, 'query', 'codeofconduct', 'index.html')

assert_match(%r{<td>\s+<p>The code of conduct's key</p>\s+</td>}, contents)
assert_match(%r{<p>The code of conduct's key</p>}, contents)
end

def test_that_non_empty_html_lines_not_interpreted_by_markdown
Expand All @@ -216,6 +201,7 @@ def test_that_non_empty_html_lines_not_interpreted_by_markdown

contents = File.read File.join(@output_dir, 'input_object', 'projectorder', 'index.html')

assert_match %r{<div class="description-wrapper">\n <p>The direction in which to order projects by the specified field.</p>\s+</div>}, contents
assert_match %r{<div class="description-wrapper">\n <p>The direction in which to order projects by the specified field.</p>\s+</div>},
contents
end
end

0 comments on commit 2aec020

Please sign in to comment.