private mockCachedObj()

in lib/generator/swaggerMocker.ts [188:299]


  private mockCachedObj(
    objName: string,
    schema: any,
    example: any,
    visited: Set<string>,
    isRequest: boolean,
    discriminatorValue: string | undefined = undefined
  ) {
    if (!schema || typeof schema !== "object") {
      log.warn(`invalid schema.`);
      return undefined;
    }
    // use visited set to avoid circular dependency
    if ("$ref" in schema && visited.has(schema.$ref)) {
      return undefined;
    }
    const cache = this.getCache(schema);
    if (cache) {
      return cache;
    }
    const definitionSpec = this.getDefSpec(schema, visited);

    if (util.isObject(definitionSpec)) {
      // circular inherit will not be handled
      const properties = this.getProperties(definitionSpec, visited);
      example = example || {};
      const discriminator = this.getDiscriminator(definitionSpec, visited);
      if (
        discriminator &&
        !discriminatorValue &&
        properties &&
        Object.keys(properties).includes(discriminator)
      ) {
        return (
          this.mockForDiscriminator(definitionSpec, example, discriminator, isRequest, visited) ||
          undefined
        );
      } else {
        Object.keys(properties).forEach((key: string) => {
          // the objName is the discriminator when discriminatorValue is specified.
          if (key === objName && discriminatorValue) {
            example[key] = createLeafItem(discriminatorValue, buildItemOption(properties[key]));
          } else {
            example[key] = this.mockCachedObj(
              key,
              properties[key],
              example[key],
              visited,
              isRequest,
              discriminatorValue
            );
          }
        });
      }
      if ("additionalProperties" in definitionSpec && definitionSpec.additionalProperties) {
        const newKey = util.randomKey();
        if (newKey in properties) {
          console.error(`generate additionalProperties for ${objName} fail`);
        } else {
          example[newKey] = this.mockCachedObj(
            newKey,
            definitionSpec.additionalProperties,
            undefined,
            visited,
            isRequest,
            discriminatorValue
          );
        }
      }
    } else if (definitionSpec.type === "array") {
      example = example || [];
      const arrItem: any = this.mockCachedObj(
        `${objName}'s item`,
        definitionSpec.items,
        example[0],
        visited,
        isRequest
      );
      example = this.mocker.mock(definitionSpec, objName, arrItem);
    } else {
      /** type === number or integer  */
      example = example ? example : this.mocker.mock(definitionSpec, objName);
    }
    // return value for primary type: string, number, integer, boolean
    // "aaaa"
    // removeFromSet: once we try all roads started from present node, we should remove it and backtrack
    this.removeFromSet(schema, visited);

    let cacheItem: CacheItem;
    if (Array.isArray(example)) {
      const cacheChild: CacheItem[] = [];
      for (const item of example) {
        cacheChild.push(item);
      }
      cacheItem = createTrunkItem(cacheChild, buildItemOption(definitionSpec));
    } else if (typeof example === "object") {
      const cacheChild: { [index: string]: CacheItem } = {};
      for (const [key, item] of Object.entries(example)) {
        cacheChild[key] = item as CacheItem;
      }
      cacheItem = createTrunkItem(cacheChild, buildItemOption(definitionSpec));
    } else {
      cacheItem = createLeafItem(example, buildItemOption(definitionSpec));
    }
    cacheItem.isMocked = true;
    const requiredProperties = this.getRequiredProperties(definitionSpec);
    if (requiredProperties && requiredProperties.length > 0) {
      cacheItem.required = requiredProperties;
    }
    this.mockCache.checkAndCache(schema, cacheItem);
    return cacheItem;
  }