Home

intertwining documentation and code?

I'm exploring ways to bridge the documentation-to-code gap. see the before and after. WDYT?

Note: I use Ramda.JS and a function merge (implementation at the end).

// before
are_all_products_of_order_in_stock({order_number}) {
    /**
     * 1) grab all product ids of order
     * 2) query another system to fetch all stocks for each product
     * 3) filter all products from 1) that are not in stock
     * 4) return true if list of out of stock products is zero
     * 5) return false if list of out of stock products is non-zero
     */
    const order = Orders.findOne({orderNumber: order_number})
    const product_ids =  R.compose(
     R.uniq,
     R.pluck('product_id')
    )(order.orderLines)

    const stock_of_products = get_stock_of_products(product_ids)
    const product_names = get_product_names(product_ids)

    const ordered_product_stats = R.pipe(
      () => product_ids,
      R.map(product_id => ({product_id})),
      merge({ values: stock_of_products, key: 'nbr_in_stock'}),
      merge({ values: product_names, key: 'name' }),
    )()

    const products_out_of_stock = ordered_product_stats.filter(
      ({nbr_in_stock}) => nbr_in_stock <= 0
    )

    return {
      is_in_stock: products_out_of_stock.length === 0,
      products_out_of_stock
    }
  }

or this?

// after
are_all_products_of_order_in_stock({order_number}) {
    /**
     * 1) grab all product ids of order
     * 2) query another system to fetch all stocks for each product
     * 3) filter all products from 1) that are not in stock
     * 4) return true if list of out of stock products is zero
     * and return false if list of out of stock products is non-zero
     */
    const _1_get_product_ids = () => {
      const order = Orders.findOne({orderNumber: order_number})
      const product_ids =  R.compose(
        R.uniq,
        R.pluck('product_id')
      )(order.orderLines)
      return product_ids
    }

    const _2_get_stock_and_product_names = product_ids => {
      const stock_of_products = get_stock_of_products(product_ids)
      const product_names = get_product_names(product_ids)

      const ordered_product_stats = R.pipe(
        () => product_ids,
        R.map(product_id => ({product_id})),
        merge({ values: stock_of_products, key: 'nbr_in_stock'}),
        merge({ values: product_names, key: 'name' }),
      )()

      return ordered_product_stats
    }

    const _3_filter_out_of_stock_products = ordered_product_stats => {
      const products_out_of_stock = ordered_product_stats.filter(
        ({nbr_in_stock}) => nbr_in_stock <= 0
      )
      return products_out_of_stock
    }

    const _4_to_expected_output = products_out_of_stock => {
      return {
        is_in_stock: products_out_of_stock.length === 0,
        products_out_of_stock
      }
    }

    return R.pipe(
      _1_get_product_ids,
      _2_get_stock_and_product_names,
      _3_filter_out_of_stock_products,
      _4_to_expected_output
    )()
  }

email me your response at yann.buydens(at)gmail.com or even better tweet me your response (I need moarrr followers on Twitter! seriously 18 followers. that's just pathetic)

Appendix

/**
 * adds to each object an additional property with key "key" and value the corresponding value in values array
 * @precondition: values and objects haves same length
 * @param values
 * @param key
 * @param objects
 * @return {*}
 */
export const merge =
  ({ values, key }) =>
  (objects) => {
    return objects.map((obj, index) => ({ ...obj, [key]: values[index] }));
  };