Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added partial request printing functions #19

Merged
merged 17 commits into from
Oct 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,13 @@ First, let's see what Kraph provides for you.
* }
*/
```
- `requestQueryString()`, `requestVariableString()` and `requestOperationName()`
provide more fine grained access to the components of the full request string,
which are sometimes necessary depending on your HTTP request builder and
GraphQL server setup. They provide the values for the `query`, `variables`,
and `operationName` parameters, respectively, and so are good for creating
GET requests. Please note that `requestVariableString()` will always return
`null` until variable support is implemented.

### Contributing to Kraph

Expand Down
8 changes: 6 additions & 2 deletions core/src/main/kotlin/me/lazmaid/kraph/Kraph.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ class Kraph(f: Kraph.() -> Unit) {
return set
}

fun toGraphQueryString() = document.operation.print(true, 0)
fun toRequestString() = document.print(false, 0)
fun toGraphQueryString() = document.operation.print(PrintFormat.PRETTY, 0)
fun toRequestString() = document.print(PrintFormat.JSON, 0)

fun requestQueryString() = document.operation.print(PrintFormat.NORMAL, 0)
fun requestVariableString() = document.variables.print()
fun requestOperationName() = document.operation.name

inner open class FieldBuilder {
internal val fields = arrayListOf<Field>()
Expand Down
9 changes: 6 additions & 3 deletions core/src/main/kotlin/me/lazmaid/kraph/lang/Argument.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ package me.lazmaid.kraph.lang
*/

internal open class Argument(internal val args: Map<String, Any> = mapOf()) : GraphQLNode() {
override fun print(prettyFormat: Boolean, previousLevel: Int): String {
return "(${print(args, prettyFormat)})"
override fun print(
format: PrintFormat,
previousLevel: Int
): String {
return "(${print(args, format)})"
}
}
}
43 changes: 14 additions & 29 deletions core/src/main/kotlin/me/lazmaid/kraph/lang/DataEntry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,40 @@ package me.lazmaid.kraph.lang
*/

internal sealed class DataEntry {
abstract fun print(prettyFormat: Boolean): String
abstract fun print(format: PrintFormat): String

class NonDecimalNumberData(private val value: Long) : DataEntry() {
constructor(value: Int) : this(value.toLong())

override fun print(prettyFormat: Boolean) = value.toString()
override fun print(format: PrintFormat) = value.toString()
}

class DecimalNumberData(private val value: Double) : DataEntry() {
override fun print(prettyFormat: Boolean) = value.toString()
override fun print(format: PrintFormat) = value.toString()
}

class BooleanData(private val value: Boolean) : DataEntry() {
override fun print(prettyFormat: Boolean) = value.toString()
override fun print(format: PrintFormat) = value.toString()
}

class StringData(private val value: String) : DataEntry() {
override fun print(prettyFormat: Boolean) =
if (prettyFormat) {
"\"$value\""
} else {
override fun print(format: PrintFormat) =
if (format == PrintFormat.JSON) {
"\\\"$value\\\""
} else {
"\"$value\""
}
}

class ArrayData(private val values: List<DataEntry>) : DataEntry() {
override fun print(prettyFormat: Boolean) =
values.foldIndexed("[") { index, acc, item ->
var newAcc = acc + item.print(prettyFormat)
if (index != values.size - 1) {
newAcc += ", "
} else {
newAcc += "]"
}
newAcc
}
override fun print(format: PrintFormat) =
"[${ values.joinToString(", ") { it.print(format) } }]"
}

class ObjectData(private val values: List<Pair<String, DataEntry>>) : DataEntry() {
override fun print(prettyFormat: Boolean) =
values.foldIndexed("{") { index, acc, (k, v) ->
var newAcc = acc + "${k.wrappedWithQuotes(prettyFormat)}: ${v.print(prettyFormat)}"
if (index != values.size - 1) {
newAcc += ", "
} else {
newAcc += "}"
}
newAcc
}
override fun print(format: PrintFormat) =
"{${ values.joinToString(", ") { (k, v) ->
"${k}: ${v.print(format)}"
} }}"
}
}

16 changes: 9 additions & 7 deletions core/src/main/kotlin/me/lazmaid/kraph/lang/Document.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ package me.lazmaid.kraph.lang
*/

internal class Document(internal val operation: Operation) : GraphQLNode() {
override fun print(prettyFormat: Boolean, previousLevel: Int): String {
val operationNamePart = operation.name?.let {
"\"$it\""
}
val variablesPart = null
return "{\"query\": \"${operation.print(prettyFormat, previousLevel)}\", \"variables\": $variablesPart, \"operationName\": $operationNamePart}"
internal val variables: Variables = Variables()
override fun print(
format: PrintFormat,
previousLevel: Int
): String {
val operationNamePart = operation.name?.let{ "\"$it\"" }
val variablesPart = variables.print()
return "{\"query\": \"${operation.print(PrintFormat.JSON, previousLevel)}\", \"variables\": $variablesPart, \"operationName\": $operationNamePart}"
}
}
}
20 changes: 12 additions & 8 deletions core/src/main/kotlin/me/lazmaid/kraph/lang/Field.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ package me.lazmaid.kraph.lang
* Created by VerachadW on 9/19/2016 AD.
*/

internal open class Field(internal val name: String, internal val arguments: Argument? = null, internal var selectionSet: SelectionSet? = null) : GraphQLNode() {
override fun print(prettyFormat: Boolean, previousLevel: Int): String {
val selectionSetPart = selectionSet?.let { " " + it.print(prettyFormat, previousLevel) } ?: ""
return "$name${arguments?.print(prettyFormat, previousLevel) ?: ""}$selectionSetPart"
internal open class Field(
internal val name: String,
internal val arguments: Argument? = null,
internal var selectionSet: SelectionSet? = null
) : GraphQLNode() {
override fun print(
format: PrintFormat,
previousLevel: Int
): String {
val selectionSetPart = selectionSet?.print(format, previousLevel)?.let{ " $it" } ?: ""
val argumentsPart = arguments?.print(format, previousLevel)?.let{ " $it" } ?: ""
return "$name$argumentsPart$selectionSetPart"
}
}




62 changes: 23 additions & 39 deletions core/src/main/kotlin/me/lazmaid/kraph/lang/GraphQLNode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@ package me.lazmaid.kraph.lang
abstract internal class GraphQLNode {
var level = 0

abstract fun print(prettyFormat: Boolean, previousLevel: Int): String
abstract fun print(format: PrintFormat, previousLevel: Int): String

fun getIndentString(level: Int) = " ".repeat(level)
fun getNewLineString(prettyFormat: Boolean) = if (prettyFormat) "\n" else "\\n"
fun getNewLineString(format: PrintFormat) = if (format == PrintFormat.PRETTY) "\n" else " "

fun print(value: Map<String, Any?>, prettyFormat: Boolean) =
value.entries.foldIndexed("") { index, acc, (k, v)->
var newAcc = acc + "$k: ${convertToDataEntry(v).print(prettyFormat)}"
if (index != value.entries.size - 1) {
newAcc += ", "
}
newAcc
fun print(value: Map<String, Any?>, format: PrintFormat) =
value.entries.joinToString(", ") { (k, v) ->
"$k: ${convertToDataEntry(v).print(format)}"
}

private fun convertToArrayData(value: List<*>): DataEntry.ArrayData = DataEntry.ArrayData(value.map(this::convertToDataEntry))
private fun convertToArrayData(value: List<*>): DataEntry.ArrayData =
DataEntry.ArrayData(value.map(this::convertToDataEntry))

private fun convertToObjectData(map: Map<String, *>): DataEntry.ObjectData =
DataEntry.ObjectData(map.map {
Expand All @@ -27,40 +24,27 @@ abstract internal class GraphQLNode {
@Suppress("UNCHECKED_CAST")
private fun convertToDataEntry(value: Any?) =
when(value) {
is String -> {
DataEntry.StringData(value)
}
is Int -> {
DataEntry.NonDecimalNumberData(value.toLong())
}
is Long -> {
DataEntry.NonDecimalNumberData(value)
}
is Float -> {
DataEntry.DecimalNumberData(value.toDouble())
}
is Boolean -> {
DataEntry.BooleanData(value)
}
is Double -> {
DataEntry.DecimalNumberData(value)
}
is List<*> -> {
convertToArrayData(value)
}
is Map<*, *> -> {
convertToObjectData(value as Map<String, *>)
}
else -> {
throw RuntimeException("Unsupported Type")
}
is String -> DataEntry.StringData(value)
is Int -> DataEntry.NonDecimalNumberData(value.toLong())
is Long -> DataEntry.NonDecimalNumberData(value)
is Float -> DataEntry.DecimalNumberData(value.toDouble())
is Boolean -> DataEntry.BooleanData(value)
is Double -> DataEntry.DecimalNumberData(value)
is List<*> -> convertToArrayData(value)
is Map<*,*> -> convertToObjectData(value as Map<String, *>)
else -> throw RuntimeException("Unsupported Type")
}
}

internal fun String.wrappedWithQuotes(shouldEscaped: Boolean) =
if (shouldEscaped) {
internal fun String.wrappedWithQuotes(shouldBeEscaped: Boolean) =
if (shouldBeEscaped) {
"\"$this\""
} else {
"\\\"$this\\\""
}

internal enum class PrintFormat {
NORMAL,
PRETTY,
JSON
}
22 changes: 14 additions & 8 deletions core/src/main/kotlin/me/lazmaid/kraph/lang/Operation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,23 @@ package me.lazmaid.kraph.lang
* Created by VerachadW on 10/2/2016 AD.
*/

internal class Operation(internal val type: OperationType, internal val selectionSet: SelectionSet,
internal val name: String? = null, internal val arguments: Argument? = null) : GraphQLNode() {

override fun print(prettyFormat: Boolean, previousLevel: Int): String {
val namePart = name?.let { " " + it } ?: ""
val argumentPart = arguments?.print(prettyFormat, previousLevel) ?: ""
return "${type.name.toLowerCase()}$namePart$argumentPart ${selectionSet.print(prettyFormat, previousLevel)}"
internal class Operation(
internal val type: OperationType,
internal val selectionSet: SelectionSet,
internal val name: String? = null,
internal val arguments: Argument? = null
) : GraphQLNode() {
override fun print(
format: PrintFormat,
previousLevel: Int
): String {
val namePart = name?.let{ " $it" } ?: ""
val argumentPart = arguments?.print(format, previousLevel)?.let{ " $it" } ?: ""
return "${type.name.toLowerCase()}$namePart$argumentPart ${selectionSet.print(format, previousLevel)}"
}
}

internal enum class OperationType {
QUERY,
MUTATION
}
}
17 changes: 9 additions & 8 deletions core/src/main/kotlin/me/lazmaid/kraph/lang/SelectionSet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ package me.lazmaid.kraph.lang

internal class SelectionSet(internal val fields: List<Field>) : GraphQLNode() {

override fun print(prettyFormat: Boolean, previousLevel: Int): String {
if (prettyFormat) level = previousLevel + 1 else level = 0
return "{${
getNewLineString(prettyFormat) + fields.fold("") { acc, node ->
acc + getIndentString(level) + node.print(prettyFormat, level) + getNewLineString(prettyFormat)
} + getIndentString(previousLevel)
}}"
override fun print(
format: PrintFormat,
previousLevel: Int
): String {
val nl = getNewLineString(format)
if (format == PrintFormat.PRETTY) level = previousLevel + 1 else level = 0
val fieldStr = fields.joinToString(nl) { getIndentString(level) + it.print(format, level) }
return "{${ nl + fieldStr + nl + getIndentString(previousLevel) }}"
}
}
}
10 changes: 10 additions & 0 deletions core/src/main/kotlin/me/lazmaid/kraph/lang/Variables.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package me.lazmaid.kraph.lang

/**
* Created by OinkIguana on 10/25/2017 AD.
*/

// TODO: implement variables
internal class Variables() {
fun print(): String? = null
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ import me.lazmaid.kraph.lang.SelectionSet
* Created by VerachadW on 10/2/2016 AD.
*/

internal class CursorConnection(name: String, argument: Argument, selectionSet: SelectionSet) : Field(name, arguments = argument, selectionSet = selectionSet)
internal class CursorConnection(
name: String,
argument: Argument,
selectionSet: SelectionSet
) : Field(name, arguments = argument, selectionSet = selectionSet)

internal class Edges(nodeSelectionSet: SelectionSet, additionalField: List<Field> = listOf()) : Field("edges", selectionSet = SelectionSet(listOf(Field("node", selectionSet = nodeSelectionSet)) + additionalField))
internal class Edges(
nodeSelectionSet: SelectionSet,
additionalField: List<Field> = listOf()
) : Field("edges", selectionSet = SelectionSet(listOf(Field("node", selectionSet = nodeSelectionSet)) + additionalField))

internal class PageInfo (pageSelectionSet: SelectionSet) : Field("pageInfo", selectionSet = pageSelectionSet)

Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package me.lazmaid.kraph.lang.relay

import me.lazmaid.kraph.lang.Argument
import me.lazmaid.kraph.lang.PrintFormat

/**
* Created by VerachadW on 10/2/2016 AD.
*/

internal class InputArgument(args: Map<String, Any>) : Argument(args) {
override fun print(prettyFormat: Boolean, previousLevel: Int): String {
return "(input: { ${print(args, prettyFormat)} })"
override fun print(
format: PrintFormat,
previousLevel: Int
): String {
return "(input: { ${print(args, format) } })"
}
}
7 changes: 3 additions & 4 deletions core/src/test/kotlin/me/lazmaid/kraph/test/BuilderSpek.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,17 @@ class BuilderSpek : Spek({
assertThat(query.document.operation.selectionSet.fields[0].selectionSet!!.fields[2].selectionSet!!.fields[1].name, equalTo("email"))
}
it("should be able to print the request for network call") {
assertThat(query.toRequestString(), equalTo("{\"query\": \"query getAllNotes {\\nnotes {\\nid\\ncontent\\nauthor {\\nname\\nemail\\n}\\navatarUrl(size: 100)\\n}\\n}\", \"variables\": null, \"operationName\": \"getAllNotes\"}"))
assertThat(query.toRequestString(), equalTo("{\"query\": \"query getAllNotes { notes { id content author { name email } avatarUrl (size: 100) } }\", \"variables\": null, \"operationName\": \"getAllNotes\"}"))
}
it("should be able to print GraphQL query content with pretty format") {
assertThat(query.toGraphQueryString(), equalTo("query getAllNotes {\n notes {\n id\n content\n author {\n name\n email\n }\n avatarUrl(size: 100)\n }\n}"))
assertThat(query.toGraphQueryString(), equalTo("query getAllNotes {\n notes {\n id\n content\n author {\n name\n email\n }\n avatarUrl (size: 100)\n }\n}"))
}
}
given("sample query with no field in selection set") {
it("should throw NoFieldsInSelectionSetException") {
assertThat({
Kraph {
query {
}
query { }
}
}, throws(noFieldInSelectionSetMessageMatcher("query")))
}
Expand Down
Loading