tinygql 0.1.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 +7 -0
- data/.github/workflows/ci.yml +46 -0
- data/.gitignore +4 -0
- data/CODE_OF_CONDUCT.md +77 -0
- data/Gemfile +3 -0
- data/LICENSE +201 -0
- data/README.md +71 -0
- data/Rakefile +132 -0
- data/bin/bench.rb +11 -0
- data/lib/tinygql/lexer.rb +256 -0
- data/lib/tinygql/nodes.rb +870 -0
- data/lib/tinygql/nodes.rb.erb +45 -0
- data/lib/tinygql/nodes.yml +205 -0
- data/lib/tinygql/parser.rb +598 -0
- data/lib/tinygql/version.rb +3 -0
- data/lib/tinygql/visitors.rb +442 -0
- data/lib/tinygql/visitors.rb.erb +46 -0
- data/lib/tinygql.rb +10 -0
- data/test/helper.rb +14 -0
- data/test/kitchen-sink.graphql +59 -0
- data/test/lexer_test.rb +93 -0
- data/test/parser_test.rb +144 -0
- data/test/schema-kitchen-sink.graphql +78 -0
- data/tinygql.gemspec +20 -0
- metadata +98 -0
data/test/parser_test.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "tinygql"
|
3
|
+
|
4
|
+
module TinyGQL
|
5
|
+
class ParserTest < Test
|
6
|
+
def test_multi_tok
|
7
|
+
doc = <<-eod
|
8
|
+
mutation aaron($neat: Int = 123) @foo(lol: { lon: 456 }) {
|
9
|
+
}
|
10
|
+
eod
|
11
|
+
parser = Parser.new doc
|
12
|
+
ast = parser.parse
|
13
|
+
assert_equal "mutation", ast.children.first.type
|
14
|
+
mutation = ast.children.first
|
15
|
+
assert_equal "aaron", mutation.name
|
16
|
+
assert_equal 1, mutation.variable_definitions.length
|
17
|
+
|
18
|
+
var_def = mutation.variable_definitions.first
|
19
|
+
variable = var_def.variable
|
20
|
+
assert_equal "neat", variable.name
|
21
|
+
assert_equal "Int", var_def.type.name
|
22
|
+
assert_equal "123", var_def.default_value.value
|
23
|
+
|
24
|
+
assert_equal(["123", "456"], ast.find_all { |node| node.int_value? }.map(&:value))
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_has_things
|
28
|
+
doc = <<-eod
|
29
|
+
mutation {
|
30
|
+
likeStory(storyID: 12345) {
|
31
|
+
story {
|
32
|
+
likeCount
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
eod
|
37
|
+
parser = Parser.new doc
|
38
|
+
ast = parser.parse
|
39
|
+
assert_equal ["likeStory", "story", "likeCount"], ast.find_all(&:field?).map(&:name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_field_alias
|
43
|
+
doc = <<-eod
|
44
|
+
mutation {
|
45
|
+
a: likeStory(storyID: 12345) {
|
46
|
+
b: story {
|
47
|
+
c: likeCount
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
eod
|
52
|
+
parser = Parser.new doc
|
53
|
+
ast = parser.parse
|
54
|
+
assert_equal ["likeStory", "story", "likeCount"], ast.find_all(&:field?).map(&:name)
|
55
|
+
assert_equal ["a", "b", "c"], ast.find_all(&:field?).map(&:aliaz)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_shorthand
|
59
|
+
doc = <<-eod
|
60
|
+
{
|
61
|
+
field
|
62
|
+
}
|
63
|
+
eod
|
64
|
+
parser = Parser.new doc
|
65
|
+
ast = parser.parse
|
66
|
+
assert_predicate ast.children.first, :operation_definition?
|
67
|
+
assert_equal ["field"], ast.find_all(&:field?).map(&:name)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_kitchen_sink
|
71
|
+
parser = Parser.new File.read(File.join(__dir__, "kitchen-sink.graphql"))
|
72
|
+
parser.parse
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_schema_kitchen_sink
|
76
|
+
parser = Parser.new File.read(File.join(__dir__, "schema-kitchen-sink.graphql"))
|
77
|
+
parser.parse
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_visitor
|
81
|
+
doc = <<-eod
|
82
|
+
mutation {
|
83
|
+
a: likeStory(storyID: 12345) {
|
84
|
+
b: story {
|
85
|
+
c: likeCount
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
eod
|
90
|
+
viz = Class.new do
|
91
|
+
include TinyGQL::Visitors::Visitor
|
92
|
+
|
93
|
+
attr_reader :nodes
|
94
|
+
|
95
|
+
def initialize
|
96
|
+
@nodes = []
|
97
|
+
end
|
98
|
+
|
99
|
+
def handle_field obj
|
100
|
+
nodes << obj if obj.name == "likeStory"
|
101
|
+
super
|
102
|
+
end
|
103
|
+
end
|
104
|
+
parser = Parser.new doc
|
105
|
+
ast = parser.parse
|
106
|
+
obj = viz.new
|
107
|
+
ast.accept(obj)
|
108
|
+
assert_equal 1, obj.nodes.length
|
109
|
+
node = obj.nodes.first
|
110
|
+
assert_equal "a", node.aliaz
|
111
|
+
assert_equal 1, node.arguments.length
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_fold
|
115
|
+
doc = <<-eod
|
116
|
+
mutation {
|
117
|
+
a: likeStory(storyID: 12345) {
|
118
|
+
b: story {
|
119
|
+
c: likeCount
|
120
|
+
}
|
121
|
+
}
|
122
|
+
}
|
123
|
+
eod
|
124
|
+
viz = Module.new do
|
125
|
+
extend TinyGQL::Visitors::Fold
|
126
|
+
|
127
|
+
def self.handle_field obj, nodes
|
128
|
+
if obj.name == "likeStory"
|
129
|
+
super(obj, nodes + [obj])
|
130
|
+
else
|
131
|
+
super
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
parser = Parser.new doc
|
136
|
+
ast = parser.parse
|
137
|
+
fields = ast.fold(viz, [])
|
138
|
+
assert_equal 1, fields.length
|
139
|
+
node = fields.first
|
140
|
+
assert_equal "a", node.aliaz
|
141
|
+
assert_equal 1, node.arguments.length
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Copyright 2019-present, GraphQL Foundation
|
2
|
+
#
|
3
|
+
# This source code is licensed under the MIT license found in the
|
4
|
+
# LICENSE file in the root directory of this source tree.
|
5
|
+
|
6
|
+
# (this line is padding to maintain test line numbers)
|
7
|
+
|
8
|
+
schema {
|
9
|
+
query: QueryType
|
10
|
+
mutation: MutationType
|
11
|
+
}
|
12
|
+
|
13
|
+
type Foo implements Bar {
|
14
|
+
one: Type
|
15
|
+
two(argument: InputType!): Type
|
16
|
+
three(argument: InputType, other: String): Int
|
17
|
+
four(argument: String = "string"): String
|
18
|
+
five(argument: [String] = ["string", "string"]): String
|
19
|
+
six(argument: InputType = {key: "value"}): Type
|
20
|
+
seven(argument: Int = null): Type
|
21
|
+
}
|
22
|
+
|
23
|
+
type AnnotatedObject @onObject(arg: "value") {
|
24
|
+
annotatedField(arg: Type = "default" @onArg): Type @onField
|
25
|
+
}
|
26
|
+
|
27
|
+
interface Bar {
|
28
|
+
one: Type
|
29
|
+
four(argument: String = "string"): String
|
30
|
+
}
|
31
|
+
|
32
|
+
interface AnnotatedInterface @onInterface {
|
33
|
+
annotatedField(arg: Type @onArg): Type @onField
|
34
|
+
}
|
35
|
+
|
36
|
+
union Feed = Story | Article | Advert
|
37
|
+
|
38
|
+
union AnnotatedUnion @onUnion = A | B
|
39
|
+
|
40
|
+
scalar CustomScalar
|
41
|
+
|
42
|
+
scalar AnnotatedScalar @onScalar
|
43
|
+
|
44
|
+
enum Site {
|
45
|
+
DESKTOP
|
46
|
+
MOBILE
|
47
|
+
}
|
48
|
+
|
49
|
+
enum AnnotatedEnum @onEnum {
|
50
|
+
ANNOTATED_VALUE @onEnumValue
|
51
|
+
OTHER_VALUE
|
52
|
+
}
|
53
|
+
|
54
|
+
input InputType {
|
55
|
+
key: String!
|
56
|
+
answer: Int = 42
|
57
|
+
}
|
58
|
+
|
59
|
+
input AnnotatedInput @onInputObjectType {
|
60
|
+
annotatedField: Type @onField
|
61
|
+
}
|
62
|
+
|
63
|
+
extend type Foo {
|
64
|
+
seven(argument: [String]): Type
|
65
|
+
}
|
66
|
+
|
67
|
+
# NOTE: out-of-spec test cases commented out until the spec is clarified; see
|
68
|
+
# https://github.com/graphql/graphql-js/issues/650 .
|
69
|
+
# extend type Foo @onType {}
|
70
|
+
|
71
|
+
#type NoFields {}
|
72
|
+
|
73
|
+
directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
74
|
+
|
75
|
+
directive @include(if: Boolean!)
|
76
|
+
on FIELD
|
77
|
+
| FRAGMENT_SPREAD
|
78
|
+
| INLINE_FRAGMENT
|
data/tinygql.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative "lib/tinygql/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "tinygql"
|
5
|
+
s.version = TinyGQL::VERSION
|
6
|
+
s.summary = "A GraphQL parser"
|
7
|
+
s.description = "Yet another GraphQL parser written in Ruby."
|
8
|
+
s.authors = ["Aaron Patterson"]
|
9
|
+
s.email = "tenderlove@ruby-lang.org"
|
10
|
+
s.files = `git ls-files -z`.split("\x0") + [
|
11
|
+
"lib/tinygql/nodes.rb",
|
12
|
+
"lib/tinygql/visitors.rb",
|
13
|
+
]
|
14
|
+
s.test_files = s.files.grep(%r{^test/})
|
15
|
+
s.homepage = "https://github.com/tenderlove/tinygql"
|
16
|
+
s.license = "Apache-2.0"
|
17
|
+
|
18
|
+
s.add_development_dependency("rake", "~> 13.0")
|
19
|
+
s.add_development_dependency("minitest", "~> 5.14")
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tinygql
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aaron Patterson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-08-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '13.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '13.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.14'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.14'
|
41
|
+
description: Yet another GraphQL parser written in Ruby.
|
42
|
+
email: tenderlove@ruby-lang.org
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- ".github/workflows/ci.yml"
|
48
|
+
- ".gitignore"
|
49
|
+
- CODE_OF_CONDUCT.md
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- bin/bench.rb
|
55
|
+
- lib/tinygql.rb
|
56
|
+
- lib/tinygql/lexer.rb
|
57
|
+
- lib/tinygql/nodes.rb
|
58
|
+
- lib/tinygql/nodes.rb.erb
|
59
|
+
- lib/tinygql/nodes.yml
|
60
|
+
- lib/tinygql/parser.rb
|
61
|
+
- lib/tinygql/version.rb
|
62
|
+
- lib/tinygql/visitors.rb
|
63
|
+
- lib/tinygql/visitors.rb.erb
|
64
|
+
- test/helper.rb
|
65
|
+
- test/kitchen-sink.graphql
|
66
|
+
- test/lexer_test.rb
|
67
|
+
- test/parser_test.rb
|
68
|
+
- test/schema-kitchen-sink.graphql
|
69
|
+
- tinygql.gemspec
|
70
|
+
homepage: https://github.com/tenderlove/tinygql
|
71
|
+
licenses:
|
72
|
+
- Apache-2.0
|
73
|
+
metadata: {}
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubygems_version: 3.5.0.dev
|
90
|
+
signing_key:
|
91
|
+
specification_version: 4
|
92
|
+
summary: A GraphQL parser
|
93
|
+
test_files:
|
94
|
+
- test/helper.rb
|
95
|
+
- test/kitchen-sink.graphql
|
96
|
+
- test/lexer_test.rb
|
97
|
+
- test/parser_test.rb
|
98
|
+
- test/schema-kitchen-sink.graphql
|