Skip to content

Commit

Permalink
Handle Arrays in MockResolvers
Browse files Browse the repository at this point in the history
Reviewed By: josephsavona

Differential Revision: D15305221

fbshipit-source-id: f9ca7f1033163686e81d534a5fa59ed51a528fef
  • Loading branch information
alunyov authored and facebook-github-bot committed May 13, 2019
1 parent 763d6cb commit bc7408a
Show file tree
Hide file tree
Showing 3 changed files with 549 additions and 20 deletions.
47 changes: 27 additions & 20 deletions packages/relay-test-utils/RelayMockPayloadGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function valueResolver(
plural: ?boolean = false,
defaultValue?: mixed,
): mixed {
const createValue = () => {
const generateValue = (possibleDefaultValue: mixed) => {
let mockValue;
const mockResolver =
typeName != null && mockResolvers != null
Expand All @@ -125,15 +125,20 @@ function valueResolver(
}
if (mockValue === undefined) {
mockValue =
defaultValue ??
possibleDefaultValue ??
`<mock-value-for-field-"${context.alias ??
context.name ||
'undefined'}">`;
}
return mockValue;
};

return plural === true ? generateMockList(createValue) : createValue();
return plural === true
? generateMockList(
Array.isArray(defaultValue) ? defaultValue : Array(1).fill(),
generateValue,
)
: generateValue(defaultValue);
}

function createValueResolver(mockResolvers: ?MockResolvers): ValueResolver {
Expand All @@ -143,14 +148,13 @@ function createValueResolver(mockResolvers: ?MockResolvers): ValueResolver {
};
}

// This is a super simple implementation (later this should be customizable)
function generateMockList<T>(
generateListItem: (index: number) => T,
howMany: number = 1,
placeholderArray: $ReadOnlyArray<mixed>,
generateListItem: (defaultValue: mixed) => T,
): $ReadOnlyArray<T> {
return Array(howMany)
.fill(null)
.map((_, index) => generateListItem(index));
return placeholderArray.map(possibleDefaultValue =>
generateListItem(possibleDefaultValue),
);
}

class RelayMockPayloadGenerator {
Expand Down Expand Up @@ -327,15 +331,11 @@ class RelayMockPayloadGenerator {
break;
}
case CLIENT_EXTENSION:
case MODULE_IMPORT:
// TODO(T41499100) We're currently not generating ClientExtension nodes
// so we can skip for now
invariant(
false,
'RelayMockPayloadGenerator(): Unexpected ClientExtension node.',
);
// $FlowExpectedError - we need the break; for OSS linter
// TODO(T43369419) generate payloads for 3D in mock payload generator
break;
case MODULE_IMPORT:
case SCALAR_HANDLE:
case LINKED_HANDLE:
break;
Expand Down Expand Up @@ -475,8 +475,11 @@ class RelayMockPayloadGenerator {
const isAbstractType =
field.concreteType === null && typeName === typeFromSelection.type;

const generateDataForField = () =>
this._traverse(
const generateDataForField = possibleDefaultValue => {
if (possibleDefaultValue === null) {
return null;
}
return this._traverse(
{
selections: field.selections,
typeName,
Expand All @@ -495,12 +498,16 @@ class RelayMockPayloadGenerator {
/* $FlowFixMe(>=0.98.0 site=react_native_fb,oss) This comment suppresses an
* error found when Flow v0.98 was deployed. To see the error delete
* this comment and run Flow. */
defaults,
possibleDefaultValue,
);
};

data[applicationName] = field.plural
? generateMockList(generateDataForField)
: generateDataForField();
? generateMockList(
Array.isArray(defaults) ? defaults : Array(1).fill(),
generateDataForField,
)
: generateDataForField(defaults);

return data;
}
Expand Down
207 changes: 207 additions & 0 deletions packages/relay-test-utils/__tests__/RelayMockPayloadGenerator-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -907,4 +907,211 @@ describe('with @relay_test_operation', () => {
},
);
});

test('generate mock with multiple items in arrays for scalar field', () => {
testGeneratedData(
`
query TestQuery @relay_test_operation {
node(id: "my-id") {
... on User {
id
emailAddresses
}
}
}
`,
{
User(_, generateId) {
return {
emailAddresses: Array(5)
.fill(null)
.map((__, idx) => `mock_email-${idx}-${generateId()}@fb.com`),
};
},
},
);
});

test('generate mock with empty array for scalar field ', () => {
testGeneratedData(
`
query TestQuery @relay_test_operation {
node(id: "my-id") {
... on User {
id
emailAddresses
}
}
}
`,
{
User(_, generateId) {
return {
emailAddresses: [],
};
},
},
);
});

test('generate mock with multiple items in arrays for linked field with default data', () => {
testGeneratedData(
`
query TestQuery @relay_test_operation {
node(id: "my-id") {
... on User {
id
friends {
edges {
node {
id
name
profile_picture {
uri
width
height
}
}
}
}
}
}
}
`,
{
FriendsConnection(_, generateId) {
return {
edges: Array(5).fill(),
};
},
},
);
});

test('generate mock with multiple items in arrays including null', () => {
testGeneratedData(
`
query TestQuery @relay_test_operation {
node(id: "my-id") {
... on User {
id
friends {
edges {
node {
id
name
profile_picture {
uri
width
height
}
}
}
}
}
}
}
`,
{
FriendsConnection(_, generateId) {
return {
edges: [null, undefined],
};
},
},
);
});

test('generate mock with multiple items in arrays for linked field with custom data', () => {
testGeneratedData(
`
query TestQuery @relay_test_operation {
node(id: "my-id") {
... on User {
id
friends {
edges {
node {
id
name
profile_picture {
uri
width
height
}
}
}
}
}
}
}
`,
{
FriendsConnection(_, generateId) {
return {
edges: [
{
node: {
id: `friend-id-${generateId()}`,
name: 'Alice',
},
},
{
node: {
id: `friend-id-${generateId()}`,
name: 'Bob',
},
},
],
};
},
},
);
});

test('generate mock with multiple items in arrays for linked field with custom data and additional mock resolver', () => {
testGeneratedData(
`
query TestQuery @relay_test_operation {
node(id: "my-id") {
... on User {
id
friends {
edges {
node {
id
name
profile_picture {
uri
width
height
}
}
}
}
}
}
}
`,
{
Image(_, generateId) {
return {
uri: `/image-url-${generateId()}.jpg`,
};
},
FriendsConnection() {
return {
edges: [
undefined,
{
node: {
name: 'Bob with Image',
},
},
],
};
},
},
);
});
});
Loading

0 comments on commit bc7408a

Please sign in to comment.