Skip to content

tests stuck in infinite loop with nested relationships, despite setting terminateCircularRelationships to true #126

@szamanr

Description

@szamanr

hi! i'm using "graphql-codegen-typescript-mock-data": "3.3.1", with setting terminateCircularRelationships: true.
when i run a test using the mocks, it runs for a while and eventually runs out of memory: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory.

if i override the relationship as an empty array, the test completes as expected.

this is my codegen config:

  ./src/@graphql/mocks.ts:
    overwrite: true
    plugins:
      - typescript-mock-data:
          addTypename: true
          terminateCircularRelationships: true
          transformUnderscore: false
          typesFile: './index.ts'

(index.ts is generated by codegen as well)

❌ this breaks:

aCycleCheckins()

✅ this works:

aCycleCheckins({
  checkIns: [],
})

my schema looks like this:

  • CycleCheckins is an object which has checkIns
    • CheckIn has commits
      • Commit has CheckIn

the loop in the generated code looks like this:
aCycleCheckins: checkIns → aCheckIn: commits → aCommitConnection → aCommitEdge → aCommit: checkIn → aCheckIn

this is the generated code:

export const aCycleCheckins = (overrides?: Partial<CycleCheckins>, _relationshipsToOmit: Set<string> = new Set()): { __typename: 'CycleCheckins' } & CycleCheckins => {
    const relationshipsToOmit: Set<string> = new Set(_relationshipsToOmit);
    relationshipsToOmit.add('CycleCheckins');
    return {
        __typename: 'CycleCheckins',
        checkIns: overrides && overrides.hasOwnProperty('checkIns') ? overrides.checkIns! : [relationshipsToOmit.has('CheckIn') ? {} as CheckIn : aCheckIn({}, relationshipsToOmit)],
        start: overrides && overrides.hasOwnProperty('start') ? overrides.start! : 'laboriosam',
        // more non-relationship fields here
    };
};

export const aCheckIn = (overrides?: Partial<CheckIn>, _relationshipsToOmit: Set<string> = new Set()): { __typename: 'checkIn' } & CheckIn => {
    const relationshipsToOmit: Set<string> = new Set(_relationshipsToOmit);
    relationshipsToOmit.add('CheckIn');
    return {
        __typename: 'checkIn',
        commits: overrides && overrides.hasOwnProperty('commits') ? overrides.commits! : relationshipsToOmit.has('CommitConnection') ? {} as CommitConnection : aCommitConnection({}, relationshipsToOmit),
        // more fields here, but not relevant: if i comment out all relationships, test completes. if i have at least 1 relationship uncommented, if freezes.
    };
};

export const aCommitConnection = (overrides?: Partial<CommitConnection>, _relationshipsToOmit: Set<string> = new Set()): { __typename: 'commitConnection' } & CommitConnection => {
    const relationshipsToOmit: Set<string> = new Set(_relationshipsToOmit);
    relationshipsToOmit.add('CommitConnection');
    return {
        __typename: 'commitConnection',
        edges: overrides && overrides.hasOwnProperty('edges') ? overrides.edges! : [relationshipsToOmit.has('CommitEdge') ? {} as CommitEdge : aCommitEdge({}, relationshipsToOmit)],
        pageInfo: overrides && overrides.hasOwnProperty('pageInfo') ? overrides.pageInfo! : relationshipsToOmit.has('PageInfo') ? {} as PageInfo : aPageInfo({}, relationshipsToOmit),
    };
};

export const aCommitEdge = (overrides?: Partial<CommitEdge>, _relationshipsToOmit: Set<string> = new Set()): { __typename: 'commitEdge' } & CommitEdge => {
    const relationshipsToOmit: Set<string> = new Set(_relationshipsToOmit);
    relationshipsToOmit.add('CommitEdge');
    return {
        __typename: 'commitEdge',
        cursor: overrides && overrides.hasOwnProperty('cursor') ? overrides.cursor! : 'autem',
        node: overrides && overrides.hasOwnProperty('node') ? overrides.node! : relationshipsToOmit.has('Commit') ? {} as Commit : aCommit({}, relationshipsToOmit),
    };
};

export const aCommit = (overrides?: Partial<Commit>, _relationshipsToOmit: Set<string> = new Set()): { __typename: 'commit' } & Commit => {
    const relationshipsToOmit: Set<string> = new Set(_relationshipsToOmit);
    relationshipsToOmit.add('Commit');
    return {
        __typename: 'commit',
        checkIn: overrides && overrides.hasOwnProperty('checkIn') ? overrides.checkIn! : relationshipsToOmit.has('CheckIn') ? {} as CheckIn : aCheckIn({}, relationshipsToOmit),
        // ...
    };
};

this is the first test where i tried using this plugin, so i don't know if it works for other models.

is it an issue in my schema that i happened to run into in the first test? or is there something wrong with the plugin and the terminateCircularRelationships option isn't working?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions