Skip to content

Commit

Permalink
Factor out suggestion quoting utility
Browse files Browse the repository at this point in the history
  • Loading branch information
leebyron committed Apr 27, 2016
1 parent 92923be commit ec05b54
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 35 deletions.
40 changes: 40 additions & 0 deletions src/jsutils/__tests__/quotedOrList-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

import { expect } from 'chai';
import { describe, it } from 'mocha';
import quotedOrList from '../quotedOrList';

describe('quotedOrList', () => {

it('Does not accept an empty list', () => {
expect(() => quotedOrList([])).to.throw(TypeError);
});

it('Returns single quoted item', () => {
expect(quotedOrList([ 'A' ])).to.equal('"A"');
});

it('Returns two item list', () => {
expect(quotedOrList([ 'A', 'B' ])).to.equal('"A" or "B"');
});

it('Returns comma separated many item list', () => {
expect(quotedOrList([ 'A', 'B', 'C' ])).to.equal('"A", "B", or "C"');
});

it('Limits to five items', () => {
expect(
quotedOrList([ 'A', 'B', 'C', 'D', 'E', 'F' ])
).to.equal(
'"A", "B", "C", "D", or "E"'
);
});

});
2 changes: 1 addition & 1 deletion src/jsutils/__tests__/suggestionList-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import { expect } from 'chai';
import { describe, it } from 'mocha';
import { suggestionList } from '../suggestionList';
import suggestionList from '../suggestionList';

describe('suggestionList', () => {

Expand Down
26 changes: 26 additions & 0 deletions src/jsutils/quotedOrList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* @flow */
/**
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

const MAX_LENGTH = 5;

/**
* Given [ A, B, C ] return '"A", "B", or "C"'.
*/
export default function quotedOrList(items: Array<string>): string {
const selected = items.slice(0, MAX_LENGTH);
return selected
.map(item => `"${item}"`)
.reduce((list, quoted, index) =>
list +
(selected.length > 2 ? ', ' : ' ') +
(index === selected.length - 1 ? 'or ' : '') +
quoted
);
}
2 changes: 1 addition & 1 deletion src/jsutils/suggestionList.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* Given an invalid input string and a list of valid options, returns a filtered
* list of valid options sorted based on their similarity with the input.
*/
export function suggestionList(
export default function suggestionList(
input: string,
options: Array<string>
): Array<string> {
Expand Down
21 changes: 4 additions & 17 deletions src/validation/rules/FieldsOnCorrectType.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

import type { ValidationContext } from '../index';
import { GraphQLError } from '../../error';
import { suggestionList } from '../../jsutils/suggestionList';
import suggestionList from '../../jsutils/suggestionList';
import quotedOrList from '../../jsutils/quotedOrList';
import type { Field } from '../../language/ast';
import type { GraphQLSchema } from '../../type/schema';
import type { GraphQLOutputType } from '../../type/definition';
Expand All @@ -28,13 +29,11 @@ export function undefinedFieldMessage(
suggestedFieldNames: Array<string>
): string {
let message = `Cannot query field "${fieldName}" on type "${type}".`;
const MAX_LENGTH = 5;
if (suggestedTypeNames.length !== 0) {
const suggestions = quotedOrList(suggestedTypeNames.slice(0, MAX_LENGTH));
const suggestions = quotedOrList(suggestedTypeNames);
message += ` Did you mean to use an inline fragment on ${suggestions}?`;
} else if (suggestedFieldNames.length !== 0) {
const suggestions = quotedOrList(suggestedFieldNames.slice(0, MAX_LENGTH));
message += ` Did you mean ${suggestions}?`;
message += ` Did you mean ${quotedOrList(suggestedFieldNames)}?`;
}
return message;
}
Expand Down Expand Up @@ -139,15 +138,3 @@ function getSuggestedFieldNames(
// Otherwise, must be a Union type, which does not define fields.
return [];
}

/**
* Given [ A, B, C ] return '"A", "B", or "C"'.
*/
function quotedOrList(items: Array<string>): string {
return items.map(item => `"${item}"`).reduce((list, quoted, index) =>
list +
(items.length > 2 ? ', ' : ' ') +
(index === items.length - 1 ? 'or ' : '') +
quoted
);
}
13 changes: 4 additions & 9 deletions src/validation/rules/KnownArgumentNames.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import type { ValidationContext } from '../index';
import { GraphQLError } from '../../error';
import find from '../../jsutils/find';
import invariant from '../../jsutils/invariant';
import { suggestionList } from '../../jsutils/suggestionList';
import suggestionList from '../../jsutils/suggestionList';
import quotedOrList from '../../jsutils/quotedOrList';
import {
FIELD,
DIRECTIVE
Expand All @@ -29,10 +30,7 @@ export function unknownArgMessage(
let message = `Unknown argument "${argName}" on field "${fieldName}" of ` +
`type "${type}".`;
if (suggestedArgs.length) {
const suggestions = suggestedArgs
.map(t => `"${t}"`)
.join(', ');
message += ` Perhaps you meant ${suggestions}?`;
message += ` Did you mean ${quotedOrList(suggestedArgs)}?`;
}
return message;
}
Expand All @@ -45,10 +43,7 @@ export function unknownDirectiveArgMessage(
let message =
`Unknown argument "${argName}" on directive "@${directiveName}".`;
if (suggestedArgs.length) {
const suggestions = suggestedArgs
.map(t => `"${t}"`)
.join(', ');
message += ` Perhaps you meant ${suggestions}?`;
message += ` Did you mean ${quotedOrList(suggestedArgs)}?`;
}
return message;
}
Expand Down
10 changes: 3 additions & 7 deletions src/validation/rules/KnownTypeNames.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

import type { ValidationContext } from '../index';
import { GraphQLError } from '../../error';
import { suggestionList } from '../../jsutils/suggestionList';
import suggestionList from '../../jsutils/suggestionList';
import quotedOrList from '../../jsutils/quotedOrList';
import type { GraphQLType } from '../../type/definition';


Expand All @@ -19,13 +20,8 @@ export function unknownTypeMessage(
suggestedTypes: Array<string>
): string {
let message = `Unknown type "${type}".`;
const MAX_LENGTH = 5;
if (suggestedTypes.length) {
const suggestions = suggestedTypes
.slice(0, MAX_LENGTH)
.map(t => `"${t}"`)
.join(', ');
message += ` Perhaps you meant one of the following: ${suggestions}.`;
message += ` Did you mean ${quotedOrList(suggestedTypes)}?`;
}
return message;
}
Expand Down

0 comments on commit ec05b54

Please sign in to comment.