apollo-angular
Version:
Use your GraphQL data in your Angular app, with the Apollo Client
276 lines (267 loc) • 12.2 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('apollo-angular'), require('@apollo/client/core'), require('@angular/core'), require('graphql')) :
typeof define === 'function' && define.amd ? define('apollo-angular/testing', ['exports', 'apollo-angular', '@apollo/client/core', '@angular/core', 'graphql'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global['apollo-angular'] = global['apollo-angular'] || {}, global['apollo-angular'].testing = {}), global['apollo-angular'], global.core, global.ng.core, global.graphql));
}(this, (function (exports, apolloAngular, core, core$1, graphql) { 'use strict';
/**
* Controller to be injected into tests, that allows for mocking and flushing
* of operations.
*
*
*/
var ApolloTestingController = /** @class */ (function () {
function ApolloTestingController() {
}
return ApolloTestingController;
}());
var isApolloError = function (err) { return err && err.hasOwnProperty('graphQLErrors'); };
var ɵ0 = isApolloError;
var TestOperation = /** @class */ (function () {
function TestOperation(operation, observer) {
this.operation = operation;
this.observer = observer;
}
TestOperation.prototype.flush = function (result) {
if (isApolloError(result)) {
this.observer.error(result);
}
else {
var fetchResult = result ? Object.assign({}, result) : result;
this.observer.next(fetchResult);
this.observer.complete();
}
};
TestOperation.prototype.flushData = function (data) {
this.flush({
data: data,
});
};
TestOperation.prototype.networkError = function (error) {
var apolloError = new core.ApolloError({
networkError: error,
});
this.flush(apolloError);
};
TestOperation.prototype.graphqlErrors = function (errors) {
this.flush({
errors: errors,
});
};
return TestOperation;
}());
/**
* A testing backend for `Apollo`.
*
* `ApolloTestingBackend` works by keeping a list of all open operations.
* As operations come in, they're added to the list. Users can assert that specific
* operations were made and then flush them. In the end, a verify() method asserts
* that no unexpected operations were made.
*/
var ApolloTestingBackend = /** @class */ (function () {
function ApolloTestingBackend() {
/**
* List of pending operations which have not yet been expected.
*/
this.open = [];
}
/**
* Handle an incoming operation by queueing it in the list of open operations.
*/
ApolloTestingBackend.prototype.handle = function (op) {
var _this = this;
return new core.Observable(function (observer) {
var testOp = new TestOperation(op, observer);
_this.open.push(testOp);
});
};
/**
* Helper function to search for operations in the list of open operations.
*/
ApolloTestingBackend.prototype._match = function (match) {
var _this = this;
if (typeof match === 'string') {
return this.open.filter(function (testOp) { return testOp.operation.operationName === match; });
}
else if (typeof match === 'function') {
return this.open.filter(function (testOp) { return match(testOp.operation); });
}
else {
if (this.isDocumentNode(match)) {
return this.open.filter(function (testOp) { return graphql.print(testOp.operation.query) === graphql.print(match); });
}
return this.open.filter(function (testOp) { return _this.matchOp(match, testOp); });
}
};
ApolloTestingBackend.prototype.matchOp = function (match, testOp) {
var variables = JSON.stringify(match.variables);
var extensions = JSON.stringify(match.extensions);
var sameName = this.compare(match.operationName, testOp.operation.operationName);
var sameVariables = this.compare(variables, testOp.operation.variables);
var sameQuery = graphql.print(testOp.operation.query) === graphql.print(match.query);
var sameExtensions = this.compare(extensions, testOp.operation.extensions);
return sameName && sameVariables && sameQuery && sameExtensions;
};
ApolloTestingBackend.prototype.compare = function (expected, value) {
var prepare = function (val) { return typeof val === 'string' ? val : JSON.stringify(val); };
var received = prepare(value);
return !expected || received === expected;
};
/**
* Search for operations in the list of open operations, and return all that match
* without asserting anything about the number of matches.
*/
ApolloTestingBackend.prototype.match = function (match) {
var _this = this;
var results = this._match(match);
results.forEach(function (result) {
var index = _this.open.indexOf(result);
if (index !== -1) {
_this.open.splice(index, 1);
}
});
return results;
};
/**
* Expect that a single outstanding request matches the given matcher, and return
* it.
*
* operations returned through this API will no longer be in the list of open operations,
* and thus will not match twice.
*/
ApolloTestingBackend.prototype.expectOne = function (match, description) {
description = description || this.descriptionFromMatcher(match);
var matches = this.match(match);
if (matches.length > 1) {
throw new Error("Expected one matching operation for criteria \"" + description + "\", found " + matches.length + " operations.");
}
if (matches.length === 0) {
throw new Error("Expected one matching operation for criteria \"" + description + "\", found none.");
}
return matches[0];
};
/**
* Expect that no outstanding operations match the given matcher, and throw an error
* if any do.
*/
ApolloTestingBackend.prototype.expectNone = function (match, description) {
description = description || this.descriptionFromMatcher(match);
var matches = this.match(match);
if (matches.length > 0) {
throw new Error("Expected zero matching operations for criteria \"" + description + "\", found " + matches.length + ".");
}
};
/**
* Validate that there are no outstanding operations.
*/
ApolloTestingBackend.prototype.verify = function () {
var open = this.open;
if (open.length > 0) {
// Show the methods and URLs of open operations in the error, for convenience.
var operations = open
.map(function (testOp) { return testOp.operation.operationName; })
.join(', ');
throw new Error("Expected no open operations, found " + open.length + ": " + operations);
}
};
ApolloTestingBackend.prototype.isDocumentNode = function (docOrOp) {
return !docOrOp.operationName;
};
ApolloTestingBackend.prototype.descriptionFromMatcher = function (matcher) {
if (typeof matcher === 'string') {
return "Match operationName: " + matcher;
}
else if (typeof matcher === 'object') {
if (this.isDocumentNode(matcher)) {
return "Match DocumentNode";
}
var name = matcher.operationName || '(any)';
var variables = JSON.stringify(matcher.variables) || '(any)';
return "Match operation: " + name + ", variables: " + variables;
}
else {
return "Match by function: " + matcher.name;
}
};
return ApolloTestingBackend;
}());
ApolloTestingBackend.decorators = [
{ type: core$1.Injectable }
];
var APOLLO_TESTING_CACHE = new core$1.InjectionToken('apollo-angular/testing cache');
var APOLLO_TESTING_NAMED_CACHE = new core$1.InjectionToken('apollo-angular/testing named cache');
var APOLLO_TESTING_CLIENTS = new core$1.InjectionToken('apollo-angular/testing named clients');
function addClient(name, op) {
op.clientName = name;
return op;
}
var ApolloTestingModuleCore = /** @class */ (function () {
function ApolloTestingModuleCore(apollo, backend, namedClients, cache, namedCaches) {
function createOptions(name, c) {
return {
link: new core.ApolloLink(function (operation) { return backend.handle(addClient(name, operation)); }),
cache: c ||
new core.InMemoryCache({
addTypename: false,
}),
};
}
apollo.create(createOptions('default', cache));
if (namedClients && namedClients.length) {
namedClients.forEach(function (name) {
var caches = namedCaches && typeof namedCaches === 'object' ? namedCaches : {};
apollo.createNamed(name, createOptions(name, caches[name]));
});
}
}
return ApolloTestingModuleCore;
}());
ApolloTestingModuleCore.decorators = [
{ type: core$1.NgModule, args: [{
providers: [
ApolloTestingBackend,
{ provide: ApolloTestingController, useExisting: ApolloTestingBackend },
],
},] }
];
ApolloTestingModuleCore.ctorParameters = function () { return [
{ type: apolloAngular.Apollo },
{ type: ApolloTestingBackend },
{ type: Array, decorators: [{ type: core$1.Optional }, { type: core$1.Inject, args: [APOLLO_TESTING_CLIENTS,] }] },
{ type: core.ApolloCache, decorators: [{ type: core$1.Optional }, { type: core$1.Inject, args: [APOLLO_TESTING_CACHE,] }] },
{ type: undefined, decorators: [{ type: core$1.Optional }, { type: core$1.Inject, args: [APOLLO_TESTING_NAMED_CACHE,] }] }
]; };
var ApolloTestingModule = /** @class */ (function () {
function ApolloTestingModule() {
}
ApolloTestingModule.withClients = function (names) {
return {
ngModule: ApolloTestingModuleCore,
providers: [
{
provide: APOLLO_TESTING_CLIENTS,
useValue: names,
},
],
};
};
return ApolloTestingModule;
}());
ApolloTestingModule.decorators = [
{ type: core$1.NgModule, args: [{
imports: [ApolloTestingModuleCore],
},] }
];
/**
* Generated bundle index. Do not edit.
*/
exports.APOLLO_TESTING_CACHE = APOLLO_TESTING_CACHE;
exports.APOLLO_TESTING_NAMED_CACHE = APOLLO_TESTING_NAMED_CACHE;
exports.ApolloTestingController = ApolloTestingController;
exports.ApolloTestingModule = ApolloTestingModule;
exports.TestOperation = TestOperation;
exports.ɵa = APOLLO_TESTING_CLIENTS;
exports.ɵb = ApolloTestingModuleCore;
exports.ɵc = ApolloTestingBackend;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=ngApolloTesting.umd.js.map