Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Fix #4 by making API equal to graphqls #11

Merged
merged 7 commits into from
Jan 22, 2019
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
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";

import graphql from "reactive-graphql";
import { graphql } from "reactive-graphql";

import { makeExecutableSchema } from "graphql-tools";
import gql from "graphql-tag";
import { from, interval, of } from "rxjs";
import { map, merge, scan, combineLatest } from "rxjs/operators";
import { componentFromStream } from "@dcos/data-service";
Expand Down Expand Up @@ -66,7 +65,7 @@ const schema = makeExecutableSchema({
}
});

const query = gql`
const query = `
query {
posts {
title
Expand All @@ -75,7 +74,7 @@ const query = gql`
}
`;

const postStream = graphql(query, schema);
const postStream = graphql(schema, query);
const PostsList = componentFromStream(propsStream =>
propsStream.pipe(
combineLatest(postStream, (props, result) => {
Expand Down Expand Up @@ -108,10 +107,11 @@ ReactDOM.render(<App />, rootElement);

- fragments of all kinds
- subscriptions (as everything is treated as a subscription)
- only one top-level operation is supported

## API

The first argument you pass into `reactive-graphql` is an executable schema, the second one a parsed GraphQL query. You can pass in the root context as an object as a third parameter. The variables can be passed as 4th parameter.
The 1st argument you pass into `reactive-graphql` is an executable schema, the 2nd one a GraphQL query, either parsed or as string. You can pass in the root value as 3rd and the root context as an object as 4th parameter. The variables can be passed as 5th parameter.

The implementation will always return an Observable.
If any of the resolvers returns an error the implementation will emit the error on the stream.
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"name": "reactive-graphql",
"repository": {
"type": "git",
"url": "https://github.com/mesosphere/reactive-graphql"
},
"main": "./dist/index.js",
"typings": "dist/index",
"files": [
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/fieldNotFoundMessageForType-test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GraphQLObjectType, GraphQLString, GraphQLScalarType } from "graphql";
import { fieldNotFoundMessageForType } from "..";
import { fieldNotFoundMessageForType } from "../reactive-graphql";

describe("fieldNotFoundMessageForType", () => {
it("returns a helpful message for null", () => {
Expand Down
134 changes: 105 additions & 29 deletions src/__tests__/graphqlObservable-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { marbles } from "rxjs-marbles/jest";
import { makeExecutableSchema } from "graphql-tools";
import gql from "graphql-tag";

import graphqlObservable from "../";
import { graphql } from "../";

const typeDefs = `
type Shuttle {
Expand All @@ -26,13 +26,24 @@ const typeDefs = `

const mockResolvers = {
Query: {
launched: (_, args, ctx) => {
launched: (parent, args, ctx) => {
const { name } = args;

// act according with the type of filter
if (name === undefined) {
// When no filter is passed
return ctx.query;
if (!parent) {
return ctx.query;
}

return ctx.query.pipe(
map((shuttles: any[]) =>
shuttles.map(shuttle => ({
...shuttle,
name: shuttle.name + parent.shuttleSuffix
}))
)
);
} else if (typeof name === "string") {
// When the filter is a value
return ctx.query.pipe(
Expand Down Expand Up @@ -179,6 +190,10 @@ const itMarbles = (title, test) => {
return it(title, marbles(test));
};

itMarbles.only = (title, test) => {
return it.only(title, marbles(test));
};

describe("graphqlObservable", function() {
describe("Query", function() {
itMarbles("solves listing all fields", function(m) {
Expand All @@ -196,7 +211,27 @@ describe("graphqlObservable", function() {
a: { data: { launched: expectedData } }
});

const result = graphqlObservable(query, schema, { query: dataSource });
const result = graphql(schema, query, null, { query: dataSource });

m.expect(result.pipe(take(1))).toBeObservable(expected);
});

itMarbles("solves listing all fields with string query", function(m) {
const query = `
query {
launched {
name
}
}
`;

const expectedData = [{ name: "discovery" }];
const dataSource = of(expectedData);
const expected = m.cold("(a|)", {
a: { data: { launched: expectedData } }
});

const result = graphql(schema, query, null, { query: dataSource });

m.expect(result.pipe(take(1))).toBeObservable(expected);
});
Expand All @@ -218,11 +253,17 @@ describe("graphqlObservable", function() {
});

const nameFilter = of("apollo11");
const result = graphqlObservable(query, schema, {
query: dataSource
}, {
nameFilter
});
const result = graphql(
schema,
query,
null,
{
query: dataSource
},
{
nameFilter
}
);

m.expect(result.pipe(take(1))).toBeObservable(expected);
});
Expand All @@ -243,7 +284,7 @@ describe("graphqlObservable", function() {
a: { data: { launched: [expectedData[0]] } }
});

const result = graphqlObservable(query, schema, {
const result = graphql(schema, query, null, {
query: dataSource
});

Expand All @@ -265,7 +306,7 @@ describe("graphqlObservable", function() {
a: { data: { launched: [{ name: "discovery" }] } }
});

const result = graphqlObservable(query, schema, {
const result = graphql(schema, query, null, {
query: dataSource
});

Expand All @@ -287,13 +328,42 @@ describe("graphqlObservable", function() {
a: { data: { launched: [{ title: "challenger" }] } }
});

const result = graphqlObservable(query, schema, {
const result = graphql(schema, query, null, {
query: dataSource
});

m.expect(result.pipe(take(1))).toBeObservable(expected);
});

itMarbles.only("resolves using root value", function(m) {
const query = gql`
query {
launched {
name
}
}
`;

const expectedData = [{ name: "challenger", firstFlight: 1984 }];
const dataSource = of(expectedData);
const expected = m.cold("(a|)", {
a: { data: { launched: [{ name: "challenger-nasa" }] } }
});

const result = graphql(
schema,
query,
{
shuttleSuffix: "-nasa"
},
{
query: dataSource
}
);

m.expect(result.pipe(take(1))).toBeObservable(expected);
});

describe("Field Resolvers", function() {
describe("Leafs", function() {
itMarbles("defaults to return the property on the object", function(m) {
Expand All @@ -307,7 +377,7 @@ describe("graphqlObservable", function() {
const expected = m.cold("(a|)", {
a: { data: { plain: { noFieldResolver: "Yes" } } }
});
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
});

Expand All @@ -322,7 +392,7 @@ describe("graphqlObservable", function() {
const expected = m.cold("(a|)", {
a: { data: { plain: { fieldResolver: "I am a field resolver" } } }
});
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
});

Expand All @@ -345,7 +415,7 @@ describe("graphqlObservable", function() {
}
}
});
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
});

Expand All @@ -368,7 +438,7 @@ describe("graphqlObservable", function() {
}
}
});
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
});

Expand All @@ -389,7 +459,7 @@ describe("graphqlObservable", function() {
}
}
});
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
});
});
Expand All @@ -414,7 +484,7 @@ describe("graphqlObservable", function() {
}
}
});
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
});

Expand All @@ -441,7 +511,7 @@ describe("graphqlObservable", function() {
}
}
});
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
});

Expand All @@ -468,7 +538,7 @@ describe("graphqlObservable", function() {
}
}
});
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
});

Expand All @@ -491,7 +561,7 @@ describe("graphqlObservable", function() {
}
}
});
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
});
});
Expand Down Expand Up @@ -521,7 +591,7 @@ describe("graphqlObservable", function() {
}
}
});
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
});
});
Expand All @@ -539,7 +609,7 @@ describe("graphqlObservable", function() {
"reactive-graphql: resolver 'throwingResolver' throws this error: 'Error: my personal error'"
)
);
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
});

Expand All @@ -558,7 +628,7 @@ describe("graphqlObservable", function() {
"reactive-graphql: field 'youDontKnowMe' was not found on type 'Query'. The only fields found in this Object are: plain,item,nested,throwingResolver."
)
);
const result = graphqlObservable(query, fieldResolverSchema, {});
const result = graphql(fieldResolverSchema, query, null, {});
m.expect(result.pipe(take(1))).toBeObservable(expected);
}
);
Expand All @@ -577,7 +647,7 @@ describe("graphqlObservable", function() {
const fakeRequest = { name: "RocketShip" };
const commandContext = of(fakeRequest);

const result = graphqlObservable(mutation, schema, {
const result = graphql(schema, mutation, null, {
mutation: commandContext
});

Expand All @@ -601,7 +671,7 @@ describe("graphqlObservable", function() {

const commandContext = of("a request");

const result = graphqlObservable(mutation, schema, {
const result = graphql(schema, mutation, null, {
mutation: commandContext
});

Expand Down Expand Up @@ -634,9 +704,15 @@ describe("graphqlObservable", function() {
const variables = {
name: "RocketShip"
};
const result = graphqlObservable(mutation, schema, {
mutation: commandContext,
}, variables);
const result = graphql(
schema,
mutation,
null,
{
mutation: commandContext
},
variables
);

const expected = m.cold("(a|)", {
a: { data: { shut: { name: "RocketShip" } } }
Expand Down
12 changes: 9 additions & 3 deletions src/__tests__/reference/starWarsQuery-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ import gql from "graphql-tag";
import { take } from "rxjs/operators";

import StarWarsSchema from "./starWarsSchema";
import graphqlObservable from "../../";
import { graphql as graphqlObservable } from "../../";

const graphql = (schema, query, _rootValue?, contextValue?, variableValues?) => {
const graphql = (schema, query, rootValue?, contextValue?, variableValues?) => {
return new Promise(resolve => {
const taggedQuery = gql`
${query}
`;
graphqlObservable(taggedQuery, schema, contextValue, variableValues)
graphqlObservable(
schema,
taggedQuery,
rootValue,
contextValue,
variableValues
)
.pipe(take(1))
.subscribe(resolve);
});
Expand Down
Loading