Best JavaScript code snippet using chai
calculations.ts
Source:calculations.ts  
1import BigNumber from 'bignumber.js';2import { ONE_YEAR, RAY, MAX_UINT_AMOUNT, PERCENTAGE_FACTOR } from '../../../../helpers/constants';3import {4  IReserveParams,5  iLpPoolAssets,6  RateMode,7  tEthereumAddress,8} from '../../../../helpers/types';9import './math';10import { ReserveData, UserReserveData } from './interfaces';11export const strToBN = (amount: string): BigNumber => new BigNumber(amount);12interface Configuration {13  reservesParams: iLpPoolAssets<IReserveParams>;14}15export const configuration: Configuration = <Configuration>{};16export const calcExpectedUserDataAfterDeposit = (17  amountDeposited: string,18  reserveDataBeforeAction: ReserveData,19  reserveDataAfterAction: ReserveData,20  userDataBeforeAction: UserReserveData,21  txTimestamp: BigNumber,22  currentTimestamp: BigNumber,23  txCost: BigNumber24): UserReserveData => {25  const expectedUserData = <UserReserveData>{};26  expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(27    userDataBeforeAction.principalStableDebt,28    userDataBeforeAction.stableBorrowRate,29    userDataBeforeAction.stableRateLastUpdated,30    txTimestamp31  );32  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(33    reserveDataBeforeAction,34    userDataBeforeAction,35    txTimestamp36  );37  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;38  expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;39  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;40  expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;41  expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;42  expectedUserData.liquidityRate = reserveDataAfterAction.liquidityRate;43  expectedUserData.scaledATokenBalance = calcExpectedScaledATokenBalance(44    userDataBeforeAction,45    reserveDataAfterAction.liquidityIndex,46    new BigNumber(amountDeposited),47    new BigNumber(0)48  );49  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(50    reserveDataBeforeAction,51    userDataBeforeAction,52    txTimestamp53  ).plus(amountDeposited);54  if (userDataBeforeAction.currentATokenBalance.eq(0)) {55    expectedUserData.usageAsCollateralEnabled = true;56  } else {57    expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;58  }59  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;60  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(amountDeposited);61  expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = calcExpectedStableDebtTokenBalance(62    userDataBeforeAction.principalStableDebt,63    userDataBeforeAction.stableBorrowRate,64    userDataBeforeAction.stableRateLastUpdated,65    txTimestamp66  );67  expectedUserData.currentVariableDebt = expectedUserData.principalStableDebt = calcExpectedVariableDebtTokenBalance(68    reserveDataBeforeAction,69    userDataBeforeAction,70    txTimestamp71  );72  return expectedUserData;73};74export const calcExpectedUserDataAfterWithdraw = (75  amountWithdrawn: string,76  reserveDataBeforeAction: ReserveData,77  reserveDataAfterAction: ReserveData,78  userDataBeforeAction: UserReserveData,79  txTimestamp: BigNumber,80  currentTimestamp: BigNumber,81  txCost: BigNumber82): UserReserveData => {83  const expectedUserData = <UserReserveData>{};84  const aTokenBalance = calcExpectedATokenBalance(85    reserveDataBeforeAction,86    userDataBeforeAction,87    txTimestamp88  );89  if (amountWithdrawn == MAX_UINT_AMOUNT) {90    amountWithdrawn = aTokenBalance.toFixed(0);91  }92  expectedUserData.scaledATokenBalance = calcExpectedScaledATokenBalance(93    userDataBeforeAction,94    reserveDataAfterAction.liquidityIndex,95    new BigNumber(0),96    new BigNumber(amountWithdrawn)97  );98  expectedUserData.currentATokenBalance = aTokenBalance.minus(amountWithdrawn);99  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;100  expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;101  expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(102    userDataBeforeAction.principalStableDebt,103    userDataBeforeAction.stableBorrowRate,104    userDataBeforeAction.stableRateLastUpdated,105    txTimestamp106  );107  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(108    reserveDataBeforeAction,109    userDataBeforeAction,110    txTimestamp111  );112  expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex;113  expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;114  expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;115  expectedUserData.liquidityRate = reserveDataAfterAction.liquidityRate;116  if (userDataBeforeAction.currentATokenBalance.eq(0)) {117    expectedUserData.usageAsCollateralEnabled = true;118  } else {119    //if the user is withdrawing everything, usageAsCollateralEnabled must be false120    if (expectedUserData.currentATokenBalance.eq(0)) {121      expectedUserData.usageAsCollateralEnabled = false;122    } else {123      expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;124    }125  }126  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountWithdrawn);127  return expectedUserData;128};129export const calcExpectedReserveDataAfterDeposit = (130  amountDeposited: string,131  reserveDataBeforeAction: ReserveData,132  txTimestamp: BigNumber133): ReserveData => {134  const expectedReserveData: ReserveData = <ReserveData>{};135  expectedReserveData.address = reserveDataBeforeAction.address;136  expectedReserveData.totalLiquidity = new BigNumber(reserveDataBeforeAction.totalLiquidity).plus(137    amountDeposited138  );139  expectedReserveData.availableLiquidity = new BigNumber(140    reserveDataBeforeAction.availableLiquidity141  ).plus(amountDeposited);142  expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;143  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(144    reserveDataBeforeAction,145    txTimestamp146  );147  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(148    reserveDataBeforeAction,149    txTimestamp150  );151  expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(152    reserveDataBeforeAction.principalStableDebt,153    reserveDataBeforeAction.averageStableBorrowRate,154    reserveDataBeforeAction.totalStableDebtLastUpdated,155    txTimestamp156  );157  expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt(158    reserveDataBeforeAction,159    expectedReserveData.variableBorrowIndex160  );161  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;162  expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;163  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(164    expectedReserveData.totalStableDebt,165    expectedReserveData.totalVariableDebt,166    expectedReserveData.totalLiquidity167  );168  const rates = calcExpectedInterestRates(169    reserveDataBeforeAction.symbol,170    reserveDataBeforeAction.marketStableRate,171    expectedReserveData.utilizationRate,172    expectedReserveData.totalStableDebt,173    expectedReserveData.totalVariableDebt,174    expectedReserveData.averageStableBorrowRate175  );176  expectedReserveData.liquidityRate = rates[0];177  expectedReserveData.stableBorrowRate = rates[1];178  expectedReserveData.variableBorrowRate = rates[2];179  return expectedReserveData;180};181export const calcExpectedReserveDataAfterWithdraw = (182  amountWithdrawn: string,183  reserveDataBeforeAction: ReserveData,184  userDataBeforeAction: UserReserveData,185  txTimestamp: BigNumber186): ReserveData => {187  const expectedReserveData: ReserveData = <ReserveData>{};188  expectedReserveData.address = reserveDataBeforeAction.address;189  if (amountWithdrawn == MAX_UINT_AMOUNT) {190    amountWithdrawn = calcExpectedATokenBalance(191      reserveDataBeforeAction,192      userDataBeforeAction,193      txTimestamp194    ).toFixed();195  }196  expectedReserveData.availableLiquidity = new BigNumber(197    reserveDataBeforeAction.availableLiquidity198  ).minus(amountWithdrawn);199  expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;200  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;201  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(202    reserveDataBeforeAction,203    txTimestamp204  );205  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(206    reserveDataBeforeAction,207    txTimestamp208  );209  expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(210    reserveDataBeforeAction.principalStableDebt,211    reserveDataBeforeAction.averageStableBorrowRate,212    reserveDataBeforeAction.totalStableDebtLastUpdated,213    txTimestamp214  );215  expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(216    expectedReserveData.variableBorrowIndex217  );218  expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;219  expectedReserveData.totalLiquidity = new BigNumber(reserveDataBeforeAction.availableLiquidity)220    .minus(amountWithdrawn)221    .plus(expectedReserveData.totalVariableDebt)222    .plus(expectedReserveData.totalStableDebt);223  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(224    expectedReserveData.totalStableDebt,225    expectedReserveData.totalVariableDebt,226    expectedReserveData.totalLiquidity227  );228  const rates = calcExpectedInterestRates(229    reserveDataBeforeAction.symbol,230    reserveDataBeforeAction.marketStableRate,231    expectedReserveData.utilizationRate,232    expectedReserveData.totalStableDebt,233    expectedReserveData.totalVariableDebt,234    expectedReserveData.averageStableBorrowRate235  );236  expectedReserveData.liquidityRate = rates[0];237  expectedReserveData.stableBorrowRate = rates[1];238  expectedReserveData.variableBorrowRate = rates[2];239  return expectedReserveData;240};241export const calcExpectedReserveDataAfterBorrow = (242  amountBorrowed: string,243  borrowRateMode: string,244  reserveDataBeforeAction: ReserveData,245  userDataBeforeAction: UserReserveData,246  txTimestamp: BigNumber,247  currentTimestamp: BigNumber248): ReserveData => {249  const expectedReserveData = <ReserveData>{};250  expectedReserveData.address = reserveDataBeforeAction.address;251  const amountBorrowedBN = new BigNumber(amountBorrowed);252  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(253    reserveDataBeforeAction,254    txTimestamp255  );256  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(257    reserveDataBeforeAction,258    txTimestamp259  );260  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.minus(261    amountBorrowedBN262  );263  expectedReserveData.lastUpdateTimestamp = txTimestamp;264  if (borrowRateMode == RateMode.Stable) {265    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;266    const expectedVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul(267      expectedReserveData.variableBorrowIndex268    );269    const expectedStableDebtUntilTx = calcExpectedTotalStableDebt(270      reserveDataBeforeAction.principalStableDebt,271      reserveDataBeforeAction.averageStableBorrowRate,272      reserveDataBeforeAction.totalStableDebtLastUpdated,273      txTimestamp274    );275    expectedReserveData.principalStableDebt = expectedStableDebtUntilTx.plus(amountBorrowedBN);276    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(277      reserveDataBeforeAction.averageStableBorrowRate,278      expectedStableDebtUntilTx,279      amountBorrowedBN,280      reserveDataBeforeAction.stableBorrowRate281    );282    const totalLiquidityAfterTx = expectedReserveData.availableLiquidity283      .plus(expectedReserveData.principalStableDebt)284      .plus(expectedVariableDebtAfterTx);285    const utilizationRateAfterTx = calcExpectedUtilizationRate(286      expectedReserveData.principalStableDebt, //the expected principal debt is the total debt immediately after the tx287      expectedVariableDebtAfterTx,288      totalLiquidityAfterTx289    );290    const ratesAfterTx = calcExpectedInterestRates(291      reserveDataBeforeAction.symbol,292      reserveDataBeforeAction.marketStableRate,293      utilizationRateAfterTx,294      expectedReserveData.principalStableDebt,295      expectedVariableDebtAfterTx,296      expectedReserveData.averageStableBorrowRate297    );298    expectedReserveData.liquidityRate = ratesAfterTx[0];299    expectedReserveData.stableBorrowRate = ratesAfterTx[1];300    expectedReserveData.variableBorrowRate = ratesAfterTx[2];301    expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(302      expectedReserveData.principalStableDebt,303      expectedReserveData.averageStableBorrowRate,304      txTimestamp,305      currentTimestamp306    );307    expectedReserveData.totalVariableDebt = reserveDataBeforeAction.scaledVariableDebt.rayMul(308      calcExpectedReserveNormalizedDebt(309        expectedReserveData.variableBorrowRate,310        expectedReserveData.variableBorrowIndex,311        txTimestamp,312        currentTimestamp313      )314    );315    expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity316      .plus(expectedReserveData.totalVariableDebt)317      .plus(expectedReserveData.totalStableDebt);318    expectedReserveData.utilizationRate = calcExpectedUtilizationRate(319      expectedReserveData.totalStableDebt,320      expectedReserveData.totalVariableDebt,321      expectedReserveData.totalLiquidity322    );323  } else {324    expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;325    const totalStableDebtAfterTx = calcExpectedStableDebtTokenBalance(326      reserveDataBeforeAction.principalStableDebt,327      reserveDataBeforeAction.averageStableBorrowRate,328      reserveDataBeforeAction.totalStableDebtLastUpdated,329      txTimestamp330    );331    expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(332      reserveDataBeforeAction.principalStableDebt,333      reserveDataBeforeAction.averageStableBorrowRate,334      reserveDataBeforeAction.totalStableDebtLastUpdated,335      currentTimestamp336    );337    expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;338    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(339      amountBorrowedBN.rayDiv(expectedReserveData.variableBorrowIndex)340    );341    const totalVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul(342      expectedReserveData.variableBorrowIndex343    );344    const utilizationRateAfterTx = calcExpectedUtilizationRate(345      totalStableDebtAfterTx,346      totalVariableDebtAfterTx,347      expectedReserveData.availableLiquidity348        .plus(totalStableDebtAfterTx)349        .plus(totalVariableDebtAfterTx)350    );351    const rates = calcExpectedInterestRates(352      reserveDataBeforeAction.symbol,353      reserveDataBeforeAction.marketStableRate,354      utilizationRateAfterTx,355      totalStableDebtAfterTx,356      totalVariableDebtAfterTx,357      expectedReserveData.averageStableBorrowRate358    );359    expectedReserveData.liquidityRate = rates[0];360    expectedReserveData.stableBorrowRate = rates[1];361    expectedReserveData.variableBorrowRate = rates[2];362    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(363      calcExpectedReserveNormalizedDebt(364        expectedReserveData.variableBorrowRate,365        expectedReserveData.variableBorrowIndex,366        txTimestamp,367        currentTimestamp368      )369    );370    expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity371      .plus(expectedReserveData.totalStableDebt)372      .plus(expectedReserveData.totalVariableDebt);373    expectedReserveData.utilizationRate = calcExpectedUtilizationRate(374      expectedReserveData.totalStableDebt,375      expectedReserveData.totalVariableDebt,376      expectedReserveData.totalLiquidity377    );378  }379  return expectedReserveData;380};381export const calcExpectedReserveDataAfterRepay = (382  amountRepaid: string,383  borrowRateMode: RateMode,384  reserveDataBeforeAction: ReserveData,385  userDataBeforeAction: UserReserveData,386  txTimestamp: BigNumber,387  currentTimestamp: BigNumber388): ReserveData => {389  const expectedReserveData: ReserveData = <ReserveData>{};390  expectedReserveData.address = reserveDataBeforeAction.address;391  let amountRepaidBN = new BigNumber(amountRepaid);392  const userStableDebt = calcExpectedStableDebtTokenBalance(393    userDataBeforeAction.principalStableDebt,394    userDataBeforeAction.stableBorrowRate,395    userDataBeforeAction.stableRateLastUpdated,396    txTimestamp397  );398  const userVariableDebt = calcExpectedVariableDebtTokenBalance(399    reserveDataBeforeAction,400    userDataBeforeAction,401    txTimestamp402  );403  //if amount repaid == MAX_UINT_AMOUNT, user is repaying everything404  if (amountRepaidBN.abs().eq(MAX_UINT_AMOUNT)) {405    if (borrowRateMode == RateMode.Stable) {406      amountRepaidBN = userStableDebt;407    } else {408      amountRepaidBN = userVariableDebt;409    }410  }411  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(412    reserveDataBeforeAction,413    txTimestamp414  );415  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(416    reserveDataBeforeAction,417    txTimestamp418  );419  if (borrowRateMode == RateMode.Stable) {420    const expectedDebt = calcExpectedTotalStableDebt(421      reserveDataBeforeAction.principalStableDebt,422      reserveDataBeforeAction.averageStableBorrowRate,423      reserveDataBeforeAction.totalStableDebtLastUpdated,424      txTimestamp425    );426    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedDebt.minus(427      amountRepaidBN428    );429    //due to accumulation errors, the total stable debt might be smaller than the last user debt.430    //in this case we simply set the total supply and avg stable rate to 0.431    if (expectedReserveData.totalStableDebt.lt(0)) {432      expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedReserveData.averageStableBorrowRate = new BigNumber(433        0434      );435    } else {436      expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(437        reserveDataBeforeAction.averageStableBorrowRate,438        expectedDebt,439        amountRepaidBN.negated(),440        userDataBeforeAction.stableBorrowRate441      );442      //also due to accumulation errors, the final avg stable rate when the last user repays might be negative.443      //if that is the case, it means a small leftover of total stable debt is left, which can be erased.444      if (expectedReserveData.averageStableBorrowRate.lt(0)) {445        expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedReserveData.averageStableBorrowRate = new BigNumber(446          0447        );448      }449    }450    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;451    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(452      expectedReserveData.variableBorrowIndex453    );454  } else {455    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.minus(456      amountRepaidBN.rayDiv(expectedReserveData.variableBorrowIndex)457    );458    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(459      expectedReserveData.variableBorrowIndex460    );461    expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;462    expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt;463    expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate;464  }465  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.plus(466    amountRepaidBN467  );468  expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity469    .plus(expectedReserveData.totalStableDebt)470    .plus(expectedReserveData.totalVariableDebt);471  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(472    expectedReserveData.totalStableDebt,473    expectedReserveData.totalVariableDebt,474    expectedReserveData.totalLiquidity475  );476  const rates = calcExpectedInterestRates(477    reserveDataBeforeAction.symbol,478    reserveDataBeforeAction.marketStableRate,479    expectedReserveData.utilizationRate,480    expectedReserveData.totalStableDebt,481    expectedReserveData.totalVariableDebt,482    expectedReserveData.averageStableBorrowRate483  );484  expectedReserveData.liquidityRate = rates[0];485  expectedReserveData.stableBorrowRate = rates[1];486  expectedReserveData.variableBorrowRate = rates[2];487  expectedReserveData.lastUpdateTimestamp = txTimestamp;488  return expectedReserveData;489};490export const calcExpectedUserDataAfterBorrow = (491  amountBorrowed: string,492  interestRateMode: string,493  reserveDataBeforeAction: ReserveData,494  expectedDataAfterAction: ReserveData,495  userDataBeforeAction: UserReserveData,496  txTimestamp: BigNumber,497  currentTimestamp: BigNumber498): UserReserveData => {499  const expectedUserData = <UserReserveData>{};500  const amountBorrowedBN = new BigNumber(amountBorrowed);501  if (interestRateMode == RateMode.Stable) {502    const stableDebtUntilTx = calcExpectedStableDebtTokenBalance(503      userDataBeforeAction.principalStableDebt,504      userDataBeforeAction.stableBorrowRate,505      userDataBeforeAction.stableRateLastUpdated,506      txTimestamp507    );508    expectedUserData.principalStableDebt = stableDebtUntilTx.plus(amountBorrowed);509    expectedUserData.stableRateLastUpdated = txTimestamp;510    expectedUserData.stableBorrowRate = calcExpectedUserStableRate(511      stableDebtUntilTx,512      userDataBeforeAction.stableBorrowRate,513      amountBorrowedBN,514      reserveDataBeforeAction.stableBorrowRate515    );516    expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(517      expectedUserData.principalStableDebt,518      expectedUserData.stableBorrowRate,519      txTimestamp,520      currentTimestamp521    );522    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;523  } else {524    expectedUserData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(525      amountBorrowedBN.rayDiv(expectedDataAfterAction.variableBorrowIndex)526    );527    expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;528    expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;529    expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;530    expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance(531      userDataBeforeAction.principalStableDebt,532      userDataBeforeAction.stableBorrowRate,533      userDataBeforeAction.stableRateLastUpdated,534      currentTimestamp535    );536  }537  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(538    expectedDataAfterAction,539    expectedUserData,540    currentTimestamp541  );542  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;543  expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;544  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(545    expectedDataAfterAction,546    userDataBeforeAction,547    currentTimestamp548  );549  expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance;550  expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountBorrowed);551  return expectedUserData;552};553export const calcExpectedUserDataAfterRepay = (554  totalRepaid: string,555  rateMode: RateMode,556  reserveDataBeforeAction: ReserveData,557  expectedDataAfterAction: ReserveData,558  userDataBeforeAction: UserReserveData,559  user: string,560  onBehalfOf: string,561  txTimestamp: BigNumber,562  currentTimestamp: BigNumber563): UserReserveData => {564  const expectedUserData = <UserReserveData>{};565  const variableDebt = calcExpectedVariableDebtTokenBalance(566    reserveDataBeforeAction,567    userDataBeforeAction,568    currentTimestamp569  );570  const stableDebt = calcExpectedStableDebtTokenBalance(571    userDataBeforeAction.principalStableDebt,572    userDataBeforeAction.stableBorrowRate,573    userDataBeforeAction.stableRateLastUpdated,574    currentTimestamp575  );576  let totalRepaidBN = new BigNumber(totalRepaid);577  if (totalRepaidBN.abs().eq(MAX_UINT_AMOUNT)) {578    totalRepaidBN = rateMode == RateMode.Stable ? stableDebt : variableDebt;579  }580  if (rateMode == RateMode.Stable) {581    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;582    expectedUserData.currentVariableDebt = variableDebt;583    expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = stableDebt.minus(584      totalRepaidBN585    );586    if (expectedUserData.currentStableDebt.eq('0')) {587      //user repaid everything588      expectedUserData.stableBorrowRate = expectedUserData.stableRateLastUpdated = new BigNumber(589        '0'590      );591    } else {592      expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;593      expectedUserData.stableRateLastUpdated = txTimestamp;594    }595  } else {596    expectedUserData.currentStableDebt = userDataBeforeAction.principalStableDebt;597    expectedUserData.principalStableDebt = stableDebt;598    expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate;599    expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated;600    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.minus(601      totalRepaidBN.rayDiv(expectedDataAfterAction.variableBorrowIndex)602    );603    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul(604      expectedDataAfterAction.variableBorrowIndex605    );606  }607  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;608  expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled;609  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(610    reserveDataBeforeAction,611    userDataBeforeAction,612    txTimestamp613  );614  expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance;615  if (user === onBehalfOf) {616    expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(totalRepaidBN);617  } else {618    //wallet balance didn't change619    expectedUserData.walletBalance = userDataBeforeAction.walletBalance;620  }621  return expectedUserData;622};623export const calcExpectedUserDataAfterSetUseAsCollateral = (624  useAsCollateral: boolean,625  reserveDataBeforeAction: ReserveData,626  userDataBeforeAction: UserReserveData,627  txCost: BigNumber628): UserReserveData => {629  const expectedUserData = { ...userDataBeforeAction };630  expectedUserData.usageAsCollateralEnabled = useAsCollateral;631  return expectedUserData;632};633export const calcExpectedReserveDataAfterSwapRateMode = (634  reserveDataBeforeAction: ReserveData,635  userDataBeforeAction: UserReserveData,636  rateMode: string,637  txTimestamp: BigNumber638): ReserveData => {639  const expectedReserveData: ReserveData = <ReserveData>{};640  expectedReserveData.address = reserveDataBeforeAction.address;641  const variableDebt = calcExpectedVariableDebtTokenBalance(642    reserveDataBeforeAction,643    userDataBeforeAction,644    txTimestamp645  );646  const stableDebt = calcExpectedStableDebtTokenBalance(647    userDataBeforeAction.principalStableDebt,648    userDataBeforeAction.stableBorrowRate,649    userDataBeforeAction.stableRateLastUpdated,650    txTimestamp651  );652  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(653    reserveDataBeforeAction,654    txTimestamp655  );656  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(657    reserveDataBeforeAction,658    txTimestamp659  );660  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity;661  const totalStableDebtUntilTx = calcExpectedTotalStableDebt(662    reserveDataBeforeAction.principalStableDebt,663    reserveDataBeforeAction.averageStableBorrowRate,664    reserveDataBeforeAction.totalStableDebtLastUpdated,665    txTimestamp666  );667  if (rateMode === RateMode.Stable) {668    //swap user stable debt to variable669    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(670      stableDebt.rayDiv(expectedReserveData.variableBorrowIndex)671    );672    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(673      expectedReserveData.variableBorrowIndex674    );675    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.minus(676      stableDebt677    );678    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(679      reserveDataBeforeAction.averageStableBorrowRate,680      expectedReserveData.principalStableDebt.plus(stableDebt),681      stableDebt.negated(),682      userDataBeforeAction.stableBorrowRate683    );684  } else {685    //swap variable to stable686    expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.plus(687      variableDebt688    );689    expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.minus(690      variableDebt.rayDiv(expectedReserveData.variableBorrowIndex)691    );692    expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(693      expectedReserveData.variableBorrowIndex694    );695    expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(696      reserveDataBeforeAction.averageStableBorrowRate,697      reserveDataBeforeAction.totalStableDebt,698      variableDebt,699      reserveDataBeforeAction.stableBorrowRate700    );701  }702  expectedReserveData.totalLiquidity = reserveDataBeforeAction.availableLiquidity703    .plus(expectedReserveData.totalStableDebt)704    .plus(expectedReserveData.totalVariableDebt);705  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(706    expectedReserveData.totalStableDebt,707    expectedReserveData.totalVariableDebt,708    expectedReserveData.totalLiquidity709  );710  const rates = calcExpectedInterestRates(711    reserveDataBeforeAction.symbol,712    reserveDataBeforeAction.marketStableRate,713    expectedReserveData.utilizationRate,714    expectedReserveData.totalStableDebt,715    expectedReserveData.totalVariableDebt,716    expectedReserveData.averageStableBorrowRate717  );718  expectedReserveData.liquidityRate = rates[0];719  expectedReserveData.stableBorrowRate = rates[1];720  expectedReserveData.variableBorrowRate = rates[2];721  return expectedReserveData;722};723export const calcExpectedUserDataAfterSwapRateMode = (724  reserveDataBeforeAction: ReserveData,725  expectedDataAfterAction: ReserveData,726  userDataBeforeAction: UserReserveData,727  rateMode: string,728  txCost: BigNumber,729  txTimestamp: BigNumber730): UserReserveData => {731  const expectedUserData = { ...userDataBeforeAction };732  const stableDebtBalance = calcExpectedStableDebtTokenBalance(733    userDataBeforeAction.principalStableDebt,734    userDataBeforeAction.stableBorrowRate,735    userDataBeforeAction.stableRateLastUpdated,736    txTimestamp737  );738  const variableDebtBalance = calcExpectedVariableDebtTokenBalance(739    reserveDataBeforeAction,740    userDataBeforeAction,741    txTimestamp742  );743  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(744    reserveDataBeforeAction,745    userDataBeforeAction,746    txTimestamp747  );748  if (rateMode === RateMode.Stable) {749    // swap to variable750    expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = new BigNumber(0);751    expectedUserData.stableBorrowRate = new BigNumber(0);752    expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.plus(753      stableDebtBalance.rayDiv(expectedDataAfterAction.variableBorrowIndex)754    );755    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul(756      expectedDataAfterAction.variableBorrowIndex757    );758    expectedUserData.stableRateLastUpdated = new BigNumber(0);759  } else {760    expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = userDataBeforeAction.currentStableDebt.plus(761      variableDebtBalance762    );763    //weighted average of the previous and the current764    expectedUserData.stableBorrowRate = calcExpectedUserStableRate(765      stableDebtBalance,766      userDataBeforeAction.stableBorrowRate,767      variableDebtBalance,768      reserveDataBeforeAction.stableBorrowRate769    );770    expectedUserData.stableRateLastUpdated = txTimestamp;771    expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt = new BigNumber(0);772  }773  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;774  return expectedUserData;775};776export const calcExpectedReserveDataAfterStableRateRebalance = (777  reserveDataBeforeAction: ReserveData,778  userDataBeforeAction: UserReserveData,779  txTimestamp: BigNumber780): ReserveData => {781  const expectedReserveData: ReserveData = <ReserveData>{};782  expectedReserveData.address = reserveDataBeforeAction.address;783  const userStableDebt = calcExpectedStableDebtTokenBalance(784    userDataBeforeAction.principalStableDebt,785    userDataBeforeAction.stableBorrowRate,786    userDataBeforeAction.stableRateLastUpdated,787    txTimestamp788  );789  expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex(790    reserveDataBeforeAction,791    txTimestamp792  );793  expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex(794    reserveDataBeforeAction,795    txTimestamp796  );797  expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;798  expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul(799    expectedReserveData.variableBorrowIndex800  );801  expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(802    reserveDataBeforeAction.principalStableDebt,803    reserveDataBeforeAction.averageStableBorrowRate,804    reserveDataBeforeAction.totalStableDebtLastUpdated,805    txTimestamp806  );807  expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity;808  expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity809    .plus(expectedReserveData.totalStableDebt)810    .plus(expectedReserveData.totalVariableDebt);811  //removing the stable liquidity at the old rate812  const avgRateBefore = calcExpectedAverageStableBorrowRateRebalance(813    reserveDataBeforeAction.averageStableBorrowRate,814    expectedReserveData.totalStableDebt,815    userStableDebt.negated(),816    userDataBeforeAction.stableBorrowRate817  );818  // adding it again at the new rate819  expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRateRebalance(820    avgRateBefore,821    expectedReserveData.totalStableDebt.minus(userStableDebt),822    userStableDebt,823    reserveDataBeforeAction.stableBorrowRate824  );825  expectedReserveData.utilizationRate = calcExpectedUtilizationRate(826    expectedReserveData.totalStableDebt,827    expectedReserveData.totalVariableDebt,828    expectedReserveData.totalLiquidity829  );830  const rates = calcExpectedInterestRates(831    reserveDataBeforeAction.symbol,832    reserveDataBeforeAction.marketStableRate,833    expectedReserveData.utilizationRate,834    expectedReserveData.totalStableDebt,835    expectedReserveData.totalVariableDebt,836    expectedReserveData.averageStableBorrowRate837  );838  expectedReserveData.liquidityRate = rates[0];839  expectedReserveData.stableBorrowRate = rates[1];840  expectedReserveData.variableBorrowRate = rates[2];841  return expectedReserveData;842};843export const calcExpectedUserDataAfterStableRateRebalance = (844  reserveDataBeforeAction: ReserveData,845  expectedDataAfterAction: ReserveData,846  userDataBeforeAction: UserReserveData,847  txCost: BigNumber,848  txTimestamp: BigNumber849): UserReserveData => {850  const expectedUserData = { ...userDataBeforeAction };851  expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt;852  expectedUserData.principalVariableDebt = calcExpectedVariableDebtTokenBalance(853    reserveDataBeforeAction,854    userDataBeforeAction,855    txTimestamp856  );857  expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = calcExpectedStableDebtTokenBalance(858    userDataBeforeAction.principalStableDebt,859    userDataBeforeAction.stableBorrowRate,860    userDataBeforeAction.stableRateLastUpdated,861    txTimestamp862  );863  expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance(864    reserveDataBeforeAction,865    userDataBeforeAction,866    txTimestamp867  );868  expectedUserData.stableRateLastUpdated = txTimestamp;869  expectedUserData.principalVariableDebt = userDataBeforeAction.principalVariableDebt;870  // Stable rate after burn871  expectedUserData.stableBorrowRate = expectedDataAfterAction.averageStableBorrowRate;872  expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate;873  expectedUserData.currentATokenBalance = calcExpectedATokenBalance(874    reserveDataBeforeAction,875    userDataBeforeAction,876    txTimestamp877  );878  return expectedUserData;879};880const calcExpectedScaledATokenBalance = (881  userDataBeforeAction: UserReserveData,882  index: BigNumber,883  amountAdded: BigNumber,884  amountTaken: BigNumber885) => {886  return userDataBeforeAction.scaledATokenBalance887    .plus(amountAdded.rayDiv(index))888    .minus(amountTaken.rayDiv(index));889};890export const calcExpectedATokenBalance = (891  reserveData: ReserveData,892  userData: UserReserveData,893  currentTimestamp: BigNumber894) => {895  const index = calcExpectedReserveNormalizedIncome(reserveData, currentTimestamp);896  const { scaledATokenBalance: scaledBalanceBeforeAction } = userData;897  return scaledBalanceBeforeAction.rayMul(index);898};899const calcExpectedAverageStableBorrowRate = (900  avgStableRateBefore: BigNumber,901  totalStableDebtBefore: BigNumber,902  amountChanged: string | BigNumber,903  rate: BigNumber904) => {905  const weightedTotalBorrows = avgStableRateBefore.multipliedBy(totalStableDebtBefore);906  const weightedAmountBorrowed = rate.multipliedBy(amountChanged);907  const totalBorrowedStable = totalStableDebtBefore.plus(amountChanged);908  if (totalBorrowedStable.eq(0)) return new BigNumber('0');909  return weightedTotalBorrows910    .plus(weightedAmountBorrowed)911    .div(totalBorrowedStable)912    .decimalPlaces(0, BigNumber.ROUND_DOWN);913};914const calcExpectedAverageStableBorrowRateRebalance = (915  avgStableRateBefore: BigNumber,916  totalStableDebtBefore: BigNumber,917  amountChanged: BigNumber,918  rate: BigNumber919) => {920  const weightedTotalBorrows = avgStableRateBefore.rayMul(totalStableDebtBefore);921  const weightedAmountBorrowed = rate.rayMul(amountChanged.wadToRay());922  const totalBorrowedStable = totalStableDebtBefore.plus(amountChanged.wadToRay());923  if (totalBorrowedStable.eq(0)) return new BigNumber('0');924  return weightedTotalBorrows925    .plus(weightedAmountBorrowed)926    .rayDiv(totalBorrowedStable)927    .decimalPlaces(0, BigNumber.ROUND_DOWN);928};929export const calcExpectedVariableDebtTokenBalance = (930  reserveData: ReserveData,931  userData: UserReserveData,932  currentTimestamp: BigNumber933) => {934  const normalizedDebt = calcExpectedReserveNormalizedDebt(935    reserveData.variableBorrowRate,936    reserveData.variableBorrowIndex,937    reserveData.lastUpdateTimestamp,938    currentTimestamp939  );940  const { scaledVariableDebt } = userData;941  return scaledVariableDebt.rayMul(normalizedDebt);942};943export const calcExpectedStableDebtTokenBalance = (944  principalStableDebt: BigNumber,945  stableBorrowRate: BigNumber,946  stableRateLastUpdated: BigNumber,947  currentTimestamp: BigNumber948) => {949  if (950    stableBorrowRate.eq(0) ||951    currentTimestamp.eq(stableRateLastUpdated) ||952    stableRateLastUpdated.eq(0)953  ) {954    return principalStableDebt;955  }956  const cumulatedInterest = calcCompoundedInterest(957    stableBorrowRate,958    currentTimestamp,959    stableRateLastUpdated960  );961  return principalStableDebt.rayMul(cumulatedInterest);962};963const calcLinearInterest = (964  rate: BigNumber,965  currentTimestamp: BigNumber,966  lastUpdateTimestamp: BigNumber967) => {968  const timeDifference = currentTimestamp.minus(lastUpdateTimestamp);969  const cumulatedInterest = rate970    .multipliedBy(timeDifference)971    .dividedBy(new BigNumber(ONE_YEAR))972    .plus(RAY);973  return cumulatedInterest;974};975const calcCompoundedInterest = (976  rate: BigNumber,977  currentTimestamp: BigNumber,978  lastUpdateTimestamp: BigNumber979) => {980  const timeDifference = currentTimestamp.minus(lastUpdateTimestamp);981  if (timeDifference.eq(0)) {982    return new BigNumber(RAY);983  }984  const expMinusOne = timeDifference.minus(1);985  const expMinusTwo = timeDifference.gt(2) ? timeDifference.minus(2) : 0;986  const ratePerSecond = rate.div(ONE_YEAR);987  const basePowerTwo = ratePerSecond.rayMul(ratePerSecond);988  const basePowerThree = basePowerTwo.rayMul(ratePerSecond);989  const secondTerm = timeDifference.times(expMinusOne).times(basePowerTwo).div(2);990  const thirdTerm = timeDifference991    .times(expMinusOne)992    .times(expMinusTwo)993    .times(basePowerThree)994    .div(6);995  return new BigNumber(RAY)996    .plus(ratePerSecond.times(timeDifference))997    .plus(secondTerm)998    .plus(thirdTerm);999};1000export const calcExpectedInterestRates = (1001  reserveSymbol: string,1002  marketStableRate: BigNumber,1003  utilizationRate: BigNumber,1004  totalStableDebt: BigNumber,1005  totalVariableDebt: BigNumber,1006  averageStableBorrowRate: BigNumber1007): BigNumber[] => {1008  const { reservesParams } = configuration;1009  // Fixes WETH - LpWETH mock token symbol mismatch 1010  // if(reserveSymbol === 'WETH') {1011  //   reserveSymbol = 'LpWETH';1012  // }1013  const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol);1014  const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[1015    reserveIndex1016  ];1017  let stableBorrowRate: BigNumber = marketStableRate;1018  let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.strategy.baseVariableBorrowRate);1019  const optimalRate = new BigNumber(reserveConfiguration.strategy.optimalUtilizationRate);1020  const excessRate = new BigNumber(RAY).minus(optimalRate);1021  if (utilizationRate.gt(optimalRate)) {1022    const excessUtilizationRateRatio = utilizationRate1023      .minus(reserveConfiguration.strategy.optimalUtilizationRate)1024      .rayDiv(excessRate);1025    stableBorrowRate = stableBorrowRate1026      .plus(reserveConfiguration.strategy.stableRateSlope1)1027      .plus(1028        new BigNumber(reserveConfiguration.strategy.stableRateSlope2).rayMul(excessUtilizationRateRatio)1029      );1030    variableBorrowRate = variableBorrowRate1031      .plus(reserveConfiguration.strategy.variableRateSlope1)1032      .plus(1033        new BigNumber(reserveConfiguration.strategy.variableRateSlope2).rayMul(excessUtilizationRateRatio)1034      );1035  } else {1036    stableBorrowRate = stableBorrowRate.plus(1037      new BigNumber(reserveConfiguration.strategy.stableRateSlope1).rayMul(1038        utilizationRate.rayDiv(new BigNumber(optimalRate))1039      )1040    );1041    variableBorrowRate = variableBorrowRate.plus(1042      utilizationRate1043        .rayDiv(optimalRate)1044        .rayMul(new BigNumber(reserveConfiguration.strategy.variableRateSlope1))1045    );1046  }1047  const expectedOverallRate = calcExpectedOverallBorrowRate(1048    totalStableDebt,1049    totalVariableDebt,1050    variableBorrowRate,1051    averageStableBorrowRate1052  );1053  const liquidityRate = expectedOverallRate1054    .rayMul(utilizationRate)1055    .percentMul(new BigNumber(PERCENTAGE_FACTOR).minus(reserveConfiguration.reserveFactor));1056  return [liquidityRate, stableBorrowRate, variableBorrowRate];1057};1058export const calcExpectedOverallBorrowRate = (1059  totalStableDebt: BigNumber,1060  totalVariableDebt: BigNumber,1061  currentVariableBorrowRate: BigNumber,1062  currentAverageStableBorrowRate: BigNumber1063): BigNumber => {1064  const totalBorrows = totalStableDebt.plus(totalVariableDebt);1065  if (totalBorrows.eq(0)) return strToBN('0');1066  const weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate);1067  const weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate);1068  const overallBorrowRate = weightedVariableRate1069    .plus(weightedStableRate)1070    .rayDiv(totalBorrows.wadToRay());1071  return overallBorrowRate;1072};1073export const calcExpectedUtilizationRate = (1074  totalStableDebt: BigNumber,1075  totalVariableDebt: BigNumber,1076  totalLiquidity: BigNumber1077): BigNumber => {1078  if (totalStableDebt.eq('0') && totalVariableDebt.eq('0')) {1079    return strToBN('0');1080  }1081  const utilization = totalStableDebt.plus(totalVariableDebt).rayDiv(totalLiquidity);1082  return utilization;1083};1084const calcExpectedReserveNormalizedIncome = (1085  reserveData: ReserveData,1086  currentTimestamp: BigNumber1087) => {1088  const { liquidityRate, liquidityIndex, lastUpdateTimestamp } = reserveData;1089  //if utilization rate is 0, nothing to compound1090  if (liquidityRate.eq('0')) {1091    return liquidityIndex;1092  }1093  const cumulatedInterest = calcLinearInterest(1094    liquidityRate,1095    currentTimestamp,1096    lastUpdateTimestamp1097  );1098  const income = cumulatedInterest.rayMul(liquidityIndex);1099  return income;1100};1101const calcExpectedReserveNormalizedDebt = (1102  variableBorrowRate: BigNumber,1103  variableBorrowIndex: BigNumber,1104  lastUpdateTimestamp: BigNumber,1105  currentTimestamp: BigNumber1106) => {1107  //if utilization rate is 0, nothing to compound1108  if (variableBorrowRate.eq('0')) {1109    return variableBorrowIndex;1110  }1111  const cumulatedInterest = calcCompoundedInterest(1112    variableBorrowRate,1113    currentTimestamp,1114    lastUpdateTimestamp1115  );1116  const debt = cumulatedInterest.rayMul(variableBorrowIndex);1117  return debt;1118};1119const calcExpectedUserStableRate = (1120  balanceBefore: BigNumber,1121  rateBefore: BigNumber,1122  amount: BigNumber,1123  rateNew: BigNumber1124) => {1125  return balanceBefore1126    .times(rateBefore)1127    .plus(amount.times(rateNew))1128    .div(balanceBefore.plus(amount));1129};1130const calcExpectedLiquidityIndex = (reserveData: ReserveData, timestamp: BigNumber) => {1131  //if utilization rate is 0, nothing to compound1132  if (reserveData.utilizationRate.eq('0')) {1133    return reserveData.liquidityIndex;1134  }1135  const cumulatedInterest = calcLinearInterest(1136    reserveData.liquidityRate,1137    timestamp,1138    reserveData.lastUpdateTimestamp1139  );1140  return cumulatedInterest.rayMul(reserveData.liquidityIndex);1141};1142const calcExpectedVariableBorrowIndex = (reserveData: ReserveData, timestamp: BigNumber) => {1143  //if totalVariableDebt is 0, nothing to compound1144  if (reserveData.totalVariableDebt.eq('0')) {1145    return reserveData.variableBorrowIndex;1146  }1147  const cumulatedInterest = calcCompoundedInterest(1148    reserveData.variableBorrowRate,1149    timestamp,1150    reserveData.lastUpdateTimestamp1151  );1152  return cumulatedInterest.rayMul(reserveData.variableBorrowIndex);1153};1154const calcExpectedTotalStableDebt = (1155  principalStableDebt: BigNumber,1156  averageStableBorrowRate: BigNumber,1157  lastUpdateTimestamp: BigNumber,1158  currentTimestamp: BigNumber1159) => {1160  const cumulatedInterest = calcCompoundedInterest(1161    averageStableBorrowRate,1162    currentTimestamp,1163    lastUpdateTimestamp1164  );1165  return cumulatedInterest.rayMul(principalStableDebt);1166};1167const calcExpectedTotalVariableDebt = (1168  reserveData: ReserveData,1169  expectedVariableDebtIndex: BigNumber1170) => {1171  return reserveData.scaledVariableDebt.rayMul(expectedVariableDebtIndex);...matchers.js
Source:matchers.js  
1'use strict';2Object.defineProperty(exports, '__esModule', {3  value: true4});5exports.default = void 0;6var _jestGetType = _interopRequireWildcard(require('jest-get-type'));7var _jestMatcherUtils = require('jest-matcher-utils');8var _print = require('./print');9var _utils = require('./utils');10var _jasmineUtils = require('./jasmineUtils');11function _interopRequireWildcard(obj) {12  if (obj && obj.__esModule) {13    return obj;14  } else {15    var newObj = {};16    if (obj != null) {17      for (var key in obj) {18        if (Object.prototype.hasOwnProperty.call(obj, key)) {19          var desc =20            Object.defineProperty && Object.getOwnPropertyDescriptor21              ? Object.getOwnPropertyDescriptor(obj, key)22              : {};23          if (desc.get || desc.set) {24            Object.defineProperty(newObj, key, desc);25          } else {26            newObj[key] = obj[key];27          }28        }29      }30    }31    newObj.default = obj;32    return newObj;33  }34}35/**36 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.37 *38 * This source code is licensed under the MIT license found in the39 * LICENSE file in the root directory of this source tree.40 *41 */42// Omit colon and one or more spaces, so can call getLabelPrinter.43const EXPECTED_LABEL = 'Expected';44const RECEIVED_LABEL = 'Received';45const EXPECTED_VALUE_LABEL = 'Expected value';46const RECEIVED_VALUE_LABEL = 'Received value'; // The optional property of matcher context is true if undefined.47const isExpand = expand => expand !== false;48const toStrictEqualTesters = [49  _utils.iterableEquality,50  _utils.typeEquality,51  _utils.sparseArrayEquality52];53const matchers = {54  toBe(received, expected) {55    const matcherName = 'toBe';56    const options = {57      comment: 'Object.is equality',58      isNot: this.isNot,59      promise: this.promise60    };61    const pass = Object.is(received, expected);62    const message = pass63      ? () =>64          (0, _jestMatcherUtils.matcherHint)(65            matcherName,66            undefined,67            undefined,68            options69          ) +70          '\n\n' +71          `Expected: not ${(0, _jestMatcherUtils.printExpected)(expected)}`72      : () => {73          const expectedType = (0, _jestGetType.default)(expected);74          let deepEqualityName = null;75          if (expectedType !== 'map' && expectedType !== 'set') {76            // If deep equality passes when referential identity fails,77            // but exclude map and set until review of their equality logic.78            if (79              (0, _jasmineUtils.equals)(80                received,81                expected,82                toStrictEqualTesters,83                true84              )85            ) {86              deepEqualityName = 'toStrictEqual';87            } else if (88              (0, _jasmineUtils.equals)(received, expected, [89                _utils.iterableEquality90              ])91            ) {92              deepEqualityName = 'toEqual';93            }94          }95          return (96            (0, _jestMatcherUtils.matcherHint)(97              matcherName,98              undefined,99              undefined,100              options101            ) +102            '\n\n' +103            (deepEqualityName !== null104              ? (0, _jestMatcherUtils.DIM_COLOR)(105                  `If it should pass with deep equality, replace "${matcherName}" with "${deepEqualityName}"`106                ) + '\n\n'107              : '') +108            (0, _jestMatcherUtils.printDiffOrStringify)(109              expected,110              received,111              EXPECTED_LABEL,112              RECEIVED_LABEL,113              isExpand(this.expand)114            )115          );116        }; // Passing the actual and expected objects so that a custom reporter117    // could access them, for example in order to display a custom visual diff,118    // or create a different error message119    return {120      actual: received,121      expected,122      message,123      name: matcherName,124      pass125    };126  },127  toBeCloseTo(received, expected, precision = 2) {128    const matcherName = 'toBeCloseTo';129    const secondArgument = arguments.length === 3 ? 'precision' : undefined;130    const options = {131      isNot: this.isNot,132      promise: this.promise,133      secondArgument,134      secondArgumentColor: arg => arg135    };136    (0, _jestMatcherUtils.ensureNumbers)(137      received,138      expected,139      matcherName,140      options141    );142    let pass = false;143    let expectedDiff = 0;144    let receivedDiff = 0;145    if (received === Infinity && expected === Infinity) {146      pass = true; // Infinity - Infinity is NaN147    } else if (received === -Infinity && expected === -Infinity) {148      pass = true; // -Infinity - -Infinity is NaN149    } else {150      expectedDiff = Math.pow(10, -precision) / 2;151      receivedDiff = Math.abs(expected - received);152      pass = receivedDiff < expectedDiff;153    }154    const message = pass155      ? () =>156          (0, _jestMatcherUtils.matcherHint)(157            matcherName,158            undefined,159            undefined,160            options161          ) +162          '\n\n' +163          `Expected: not ${(0, _jestMatcherUtils.printExpected)(expected)}\n` +164          (receivedDiff === 0165            ? ''166            : `Received:     ${(0, _jestMatcherUtils.printReceived)(167                received168              )}\n` +169              '\n' +170              `Expected precision:        ${(0, _jestMatcherUtils.stringify)(171                precision172              )}\n` +173              `Expected difference: not < ${(0,174              _jestMatcherUtils.printExpected)(expectedDiff)}\n` +175              `Received difference:       ${(0,176              _jestMatcherUtils.printReceived)(receivedDiff)}`)177      : () =>178          (0, _jestMatcherUtils.matcherHint)(179            matcherName,180            undefined,181            undefined,182            options183          ) +184          '\n\n' +185          `Expected: ${(0, _jestMatcherUtils.printExpected)(expected)}\n` +186          `Received: ${(0, _jestMatcherUtils.printReceived)(received)}\n` +187          '\n' +188          `Expected precision:    ${(0, _jestMatcherUtils.stringify)(189            precision190          )}\n` +191          `Expected difference: < ${(0, _jestMatcherUtils.printExpected)(192            expectedDiff193          )}\n` +194          `Received difference:   ${(0, _jestMatcherUtils.printReceived)(195            receivedDiff196          )}`;197    return {198      message,199      pass200    };201  },202  toBeDefined(received, expected) {203    const matcherName = 'toBeDefined';204    const options = {205      isNot: this.isNot,206      promise: this.promise207    };208    (0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);209    const pass = received !== void 0;210    const message = () =>211      (0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) +212      '\n\n' +213      `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;214    return {215      message,216      pass217    };218  },219  toBeFalsy(received, expected) {220    const matcherName = 'toBeFalsy';221    const options = {222      isNot: this.isNot,223      promise: this.promise224    };225    (0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);226    const pass = !received;227    const message = () =>228      (0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) +229      '\n\n' +230      `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;231    return {232      message,233      pass234    };235  },236  toBeGreaterThan(received, expected) {237    const matcherName = 'toBeGreaterThan';238    const isNot = this.isNot;239    const options = {240      isNot,241      promise: this.promise242    };243    (0, _jestMatcherUtils.ensureNumbers)(244      received,245      expected,246      matcherName,247      options248    );249    const pass = received > expected;250    const message = () =>251      (0, _jestMatcherUtils.matcherHint)(252        matcherName,253        undefined,254        undefined,255        options256      ) +257      '\n\n' +258      `Expected:${isNot ? ' not' : ''} > ${(0, _jestMatcherUtils.printExpected)(259        expected260      )}\n` +261      `Received:${isNot ? '    ' : ''}   ${(0, _jestMatcherUtils.printReceived)(262        received263      )}`;264    return {265      message,266      pass267    };268  },269  toBeGreaterThanOrEqual(received, expected) {270    const matcherName = 'toBeGreaterThanOrEqual';271    const isNot = this.isNot;272    const options = {273      isNot,274      promise: this.promise275    };276    (0, _jestMatcherUtils.ensureNumbers)(277      received,278      expected,279      matcherName,280      options281    );282    const pass = received >= expected;283    const message = () =>284      (0, _jestMatcherUtils.matcherHint)(285        matcherName,286        undefined,287        undefined,288        options289      ) +290      '\n\n' +291      `Expected:${isNot ? ' not' : ''} >= ${(0,292      _jestMatcherUtils.printExpected)(expected)}\n` +293      `Received:${isNot ? '    ' : ''}    ${(0,294      _jestMatcherUtils.printReceived)(received)}`;295    return {296      message,297      pass298    };299  },300  toBeInstanceOf(received, expected) {301    const matcherName = 'toBeInstanceOf';302    const options = {303      isNot: this.isNot,304      promise: this.promise305    };306    if (typeof expected !== 'function') {307      throw new Error(308        (0, _jestMatcherUtils.matcherErrorMessage)(309          (0, _jestMatcherUtils.matcherHint)(310            matcherName,311            undefined,312            undefined,313            options314          ),315          `${(0, _jestMatcherUtils.EXPECTED_COLOR)(316            'expected'317          )} value must be a function`,318          (0, _jestMatcherUtils.printWithType)(319            'Expected',320            expected,321            _jestMatcherUtils.printExpected322          )323        )324      );325    }326    const pass = received instanceof expected;327    const message = pass328      ? () =>329          (0, _jestMatcherUtils.matcherHint)(330            matcherName,331            undefined,332            undefined,333            options334          ) +335          '\n\n' +336          (0, _print.printExpectedConstructorNameNot)(337            'Expected constructor',338            expected339          ) +340          (typeof received.constructor === 'function' &&341          received.constructor !== expected342            ? (0, _print.printReceivedConstructorNameNot)(343                'Received constructor',344                received.constructor,345                expected346              )347            : '')348      : () =>349          (0, _jestMatcherUtils.matcherHint)(350            matcherName,351            undefined,352            undefined,353            options354          ) +355          '\n\n' +356          (0, _print.printExpectedConstructorName)(357            'Expected constructor',358            expected359          ) +360          ((0, _jestGetType.isPrimitive)(received) ||361          Object.getPrototypeOf(received) === null362            ? `\nReceived value has no prototype\nReceived value: ${(0,363              _jestMatcherUtils.printReceived)(received)}`364            : typeof received.constructor !== 'function'365            ? `\nReceived value: ${(0, _jestMatcherUtils.printReceived)(366                received367              )}`368            : (0, _print.printReceivedConstructorName)(369                'Received constructor',370                received.constructor371              ));372    return {373      message,374      pass375    };376  },377  toBeLessThan(received, expected) {378    const matcherName = 'toBeLessThan';379    const isNot = this.isNot;380    const options = {381      isNot,382      promise: this.promise383    };384    (0, _jestMatcherUtils.ensureNumbers)(385      received,386      expected,387      matcherName,388      options389    );390    const pass = received < expected;391    const message = () =>392      (0, _jestMatcherUtils.matcherHint)(393        matcherName,394        undefined,395        undefined,396        options397      ) +398      '\n\n' +399      `Expected:${isNot ? ' not' : ''} < ${(0, _jestMatcherUtils.printExpected)(400        expected401      )}\n` +402      `Received:${isNot ? '    ' : ''}   ${(0, _jestMatcherUtils.printReceived)(403        received404      )}`;405    return {406      message,407      pass408    };409  },410  toBeLessThanOrEqual(received, expected) {411    const matcherName = 'toBeLessThanOrEqual';412    const isNot = this.isNot;413    const options = {414      isNot,415      promise: this.promise416    };417    (0, _jestMatcherUtils.ensureNumbers)(418      received,419      expected,420      matcherName,421      options422    );423    const pass = received <= expected;424    const message = () =>425      (0, _jestMatcherUtils.matcherHint)(426        matcherName,427        undefined,428        undefined,429        options430      ) +431      '\n\n' +432      `Expected:${isNot ? ' not' : ''} <= ${(0,433      _jestMatcherUtils.printExpected)(expected)}\n` +434      `Received:${isNot ? '    ' : ''}    ${(0,435      _jestMatcherUtils.printReceived)(received)}`;436    return {437      message,438      pass439    };440  },441  toBeNaN(received, expected) {442    const matcherName = 'toBeNaN';443    const options = {444      isNot: this.isNot,445      promise: this.promise446    };447    (0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);448    const pass = Number.isNaN(received);449    const message = () =>450      (0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) +451      '\n\n' +452      `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;453    return {454      message,455      pass456    };457  },458  toBeNull(received, expected) {459    const matcherName = 'toBeNull';460    const options = {461      isNot: this.isNot,462      promise: this.promise463    };464    (0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);465    const pass = received === null;466    const message = () =>467      (0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) +468      '\n\n' +469      `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;470    return {471      message,472      pass473    };474  },475  toBeTruthy(received, expected) {476    const matcherName = 'toBeTruthy';477    const options = {478      isNot: this.isNot,479      promise: this.promise480    };481    (0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);482    const pass = !!received;483    const message = () =>484      (0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) +485      '\n\n' +486      `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;487    return {488      message,489      pass490    };491  },492  toBeUndefined(received, expected) {493    const matcherName = 'toBeUndefined';494    const options = {495      isNot: this.isNot,496      promise: this.promise497    };498    (0, _jestMatcherUtils.ensureNoExpected)(expected, matcherName, options);499    const pass = received === void 0;500    const message = () =>501      (0, _jestMatcherUtils.matcherHint)(matcherName, undefined, '', options) +502      '\n\n' +503      `Received: ${(0, _jestMatcherUtils.printReceived)(received)}`;504    return {505      message,506      pass507    };508  },509  toContain(received, expected) {510    const matcherName = 'toContain';511    const isNot = this.isNot;512    const options = {513      comment: 'indexOf',514      isNot,515      promise: this.promise516    };517    if (received == null) {518      throw new Error(519        (0, _jestMatcherUtils.matcherErrorMessage)(520          (0, _jestMatcherUtils.matcherHint)(521            matcherName,522            undefined,523            undefined,524            options525          ),526          `${(0, _jestMatcherUtils.RECEIVED_COLOR)(527            'received'528          )} value must not be null nor undefined`,529          (0, _jestMatcherUtils.printWithType)(530            'Received',531            received,532            _jestMatcherUtils.printReceived533          )534        )535      );536    }537    if (typeof received === 'string') {538      const index = received.indexOf(String(expected));539      const pass = index !== -1;540      const message = () => {541        const labelExpected = `Expected ${542          typeof expected === 'string' ? 'substring' : 'value'543        }`;544        const labelReceived = 'Received string';545        const printLabel = (0, _jestMatcherUtils.getLabelPrinter)(546          labelExpected,547          labelReceived548        );549        return (550          (0, _jestMatcherUtils.matcherHint)(551            matcherName,552            undefined,553            undefined,554            options555          ) +556          '\n\n' +557          `${printLabel(labelExpected)}${isNot ? 'not ' : ''}${(0,558          _jestMatcherUtils.printExpected)(expected)}\n` +559          `${printLabel(labelReceived)}${isNot ? '    ' : ''}${560            isNot561              ? (0, _print.printReceivedStringContainExpectedSubstring)(562                  received,563                  index,564                  String(expected).length565                )566              : (0, _jestMatcherUtils.printReceived)(received)567          }`568        );569      };570      return {571        message,572        pass573      };574    }575    const indexable = Array.from(received);576    const index = indexable.indexOf(expected);577    const pass = index !== -1;578    const message = () => {579      const labelExpected = 'Expected value';580      const labelReceived = `Received ${(0, _jestGetType.default)(received)}`;581      const printLabel = (0, _jestMatcherUtils.getLabelPrinter)(582        labelExpected,583        labelReceived584      );585      return (586        (0, _jestMatcherUtils.matcherHint)(587          matcherName,588          undefined,589          undefined,590          options591        ) +592        '\n\n' +593        `${printLabel(labelExpected)}${isNot ? 'not ' : ''}${(0,594        _jestMatcherUtils.printExpected)(expected)}\n` +595        `${printLabel(labelReceived)}${isNot ? '    ' : ''}${596          isNot && Array.isArray(received)597            ? (0, _print.printReceivedArrayContainExpectedItem)(received, index)598            : (0, _jestMatcherUtils.printReceived)(received)599        }` +600        (!isNot &&601        indexable.findIndex(item =>602          (0, _jasmineUtils.equals)(item, expected, [_utils.iterableEquality])603        ) !== -1604          ? `\n\n${_jestMatcherUtils.SUGGEST_TO_CONTAIN_EQUAL}`605          : '')606      );607    };608    return {609      message,610      pass611    };612  },613  toContainEqual(received, expected) {614    const matcherName = 'toContainEqual';615    const isNot = this.isNot;616    const options = {617      comment: 'deep equality',618      isNot,619      promise: this.promise620    };621    if (received == null) {622      throw new Error(623        (0, _jestMatcherUtils.matcherErrorMessage)(624          (0, _jestMatcherUtils.matcherHint)(625            matcherName,626            undefined,627            undefined,628            options629          ),630          `${(0, _jestMatcherUtils.RECEIVED_COLOR)(631            'received'632          )} value must not be null nor undefined`,633          (0, _jestMatcherUtils.printWithType)(634            'Received',635            received,636            _jestMatcherUtils.printReceived637          )638        )639      );640    }641    const index = Array.from(received).findIndex(item =>642      (0, _jasmineUtils.equals)(item, expected, [_utils.iterableEquality])643    );644    const pass = index !== -1;645    const message = () => {646      const labelExpected = 'Expected value';647      const labelReceived = `Received ${(0, _jestGetType.default)(received)}`;648      const printLabel = (0, _jestMatcherUtils.getLabelPrinter)(649        labelExpected,650        labelReceived651      );652      return (653        (0, _jestMatcherUtils.matcherHint)(654          matcherName,655          undefined,656          undefined,657          options658        ) +659        '\n\n' +660        `${printLabel(labelExpected)}${isNot ? 'not ' : ''}${(0,661        _jestMatcherUtils.printExpected)(expected)}\n` +662        `${printLabel(labelReceived)}${isNot ? '    ' : ''}${663          isNot && Array.isArray(received)664            ? (0, _print.printReceivedArrayContainExpectedItem)(received, index)665            : (0, _jestMatcherUtils.printReceived)(received)666        }`667      );668    };669    return {670      message,671      pass672    };673  },674  toEqual(received, expected) {675    const matcherName = 'toEqual';676    const options = {677      comment: 'deep equality',678      isNot: this.isNot,679      promise: this.promise680    };681    const pass = (0, _jasmineUtils.equals)(received, expected, [682      _utils.iterableEquality683    ]);684    const message = pass685      ? () =>686          (0, _jestMatcherUtils.matcherHint)(687            matcherName,688            undefined,689            undefined,690            options691          ) +692          '\n\n' +693          `Expected: not ${(0, _jestMatcherUtils.printExpected)(expected)}\n` +694          ((0, _jestMatcherUtils.stringify)(expected) !==695          (0, _jestMatcherUtils.stringify)(received)696            ? `Received:     ${(0, _jestMatcherUtils.printReceived)(received)}`697            : '')698      : () =>699          (0, _jestMatcherUtils.matcherHint)(700            matcherName,701            undefined,702            undefined,703            options704          ) +705          '\n\n' +706          (0, _jestMatcherUtils.printDiffOrStringify)(707            expected,708            received,709            EXPECTED_LABEL,710            RECEIVED_LABEL,711            isExpand(this.expand)712          ); // Passing the actual and expected objects so that a custom reporter713    // could access them, for example in order to display a custom visual diff,714    // or create a different error message715    return {716      actual: received,717      expected,718      message,719      name: matcherName,720      pass721    };722  },723  toHaveLength(received, expected) {724    const matcherName = 'toHaveLength';725    const isNot = this.isNot;726    const options = {727      isNot,728      promise: this.promise729    };730    if (731      typeof received !== 'string' &&732      (!received || typeof received.length !== 'number')733    ) {734      throw new Error(735        (0, _jestMatcherUtils.matcherErrorMessage)(736          (0, _jestMatcherUtils.matcherHint)(737            matcherName,738            undefined,739            undefined,740            options741          ),742          `${(0, _jestMatcherUtils.RECEIVED_COLOR)(743            'received'744          )} value must have a length property whose value must be a number`,745          (0, _jestMatcherUtils.printWithType)(746            'Received',747            received,748            _jestMatcherUtils.printReceived749          )750        )751      );752    }753    (0, _jestMatcherUtils.ensureExpectedIsNonNegativeInteger)(754      expected,755      matcherName,756      options757    );758    const pass = received.length === expected;759    const message = () => {760      const labelExpected = 'Expected length';761      const labelReceivedLength = 'Received length';762      const labelReceivedValue = `Received ${(0, _jestGetType.default)(763        received764      )}`;765      const printLabel = (0, _jestMatcherUtils.getLabelPrinter)(766        labelExpected,767        labelReceivedLength,768        labelReceivedValue769      );770      return (771        (0, _jestMatcherUtils.matcherHint)(772          matcherName,773          undefined,774          undefined,775          options776        ) +777        '\n\n' +778        `${printLabel(labelExpected)}${isNot ? 'not ' : ''}${(0,779        _jestMatcherUtils.printExpected)(expected)}\n` +780        (isNot781          ? ''782          : `${printLabel(labelReceivedLength)}${(0,783            _jestMatcherUtils.printReceived)(received.length)}\n`) +784        `${printLabel(labelReceivedValue)}${isNot ? '    ' : ''}${(0,785        _jestMatcherUtils.printReceived)(received)}`786      );787    };788    return {789      message,790      pass791    };792  },793  toHaveProperty(received, expectedPath, expectedValue) {794    const matcherName = 'toHaveProperty';795    const expectedArgument = 'path';796    const hasValue = arguments.length === 3;797    const options = {798      isNot: this.isNot,799      promise: this.promise,800      secondArgument: hasValue ? 'value' : ''801    };802    if (received === null || received === undefined) {803      throw new Error(804        (0, _jestMatcherUtils.matcherErrorMessage)(805          (0, _jestMatcherUtils.matcherHint)(806            matcherName,807            undefined,808            expectedArgument,809            options810          ),811          `${(0, _jestMatcherUtils.RECEIVED_COLOR)(812            'received'813          )} value must not be null nor undefined`,814          (0, _jestMatcherUtils.printWithType)(815            'Received',816            received,817            _jestMatcherUtils.printReceived818          )819        )820      );821    }822    const expectedPathType = (0, _jestGetType.default)(expectedPath);823    if (expectedPathType !== 'string' && expectedPathType !== 'array') {824      throw new Error(825        (0, _jestMatcherUtils.matcherErrorMessage)(826          (0, _jestMatcherUtils.matcherHint)(827            matcherName,828            undefined,829            expectedArgument,830            options831          ),832          `${(0, _jestMatcherUtils.EXPECTED_COLOR)(833            'expected'834          )} path must be a string or array`,835          (0, _jestMatcherUtils.printWithType)(836            'Expected',837            expectedPath,838            _jestMatcherUtils.printExpected839          )840        )841      );842    }843    const expectedPathLength =844      typeof expectedPath === 'string'845        ? expectedPath.split('.').length846        : expectedPath.length;847    if (expectedPathType === 'array' && expectedPathLength === 0) {848      throw new Error(849        (0, _jestMatcherUtils.matcherErrorMessage)(850          (0, _jestMatcherUtils.matcherHint)(851            matcherName,852            undefined,853            expectedArgument,854            options855          ),856          `${(0, _jestMatcherUtils.EXPECTED_COLOR)(857            'expected'858          )} path must not be an empty array`,859          (0, _jestMatcherUtils.printWithType)(860            'Expected',861            expectedPath,862            _jestMatcherUtils.printExpected863          )864        )865      );866    }867    const result = (0, _utils.getPath)(received, expectedPath);868    const lastTraversedObject = result.lastTraversedObject,869      hasEndProp = result.hasEndProp;870    const receivedPath = result.traversedPath;871    const hasCompletePath = receivedPath.length === expectedPathLength;872    const receivedValue = hasCompletePath ? result.value : lastTraversedObject;873    const pass = hasValue874      ? (0, _jasmineUtils.equals)(result.value, expectedValue, [875          _utils.iterableEquality876        ])877      : Boolean(hasEndProp); // theoretically undefined if empty path878    // Remove type cast if we rewrite getPath as iterative algorithm.879    // Delete this unique report if future breaking change880    // removes the edge case that expected value undefined881    // also matches absence of a property with the key path.882    if (pass && !hasCompletePath) {883      const message = () =>884        (0, _jestMatcherUtils.matcherHint)(885          matcherName,886          undefined,887          expectedArgument,888          options889        ) +890        '\n\n' +891        `Expected path: ${(0, _jestMatcherUtils.printExpected)(892          expectedPath893        )}\n` +894        `Received path: ${(0, _jestMatcherUtils.printReceived)(895          expectedPathType === 'array' || receivedPath.length === 0896            ? receivedPath897            : receivedPath.join('.')898        )}\n\n` +899        `Expected value: not ${(0, _jestMatcherUtils.printExpected)(900          expectedValue901        )}\n` +902        `Received value:     ${(0, _jestMatcherUtils.printReceived)(903          receivedValue904        )}\n\n` +905        (0, _jestMatcherUtils.DIM_COLOR)(906          'Because a positive assertion passes for expected value undefined if the property does not exist, this negative assertion fails unless the property does exist and has a defined value'907        );908      return {909        message,910        pass911      };912    }913    const message = pass914      ? () =>915          (0, _jestMatcherUtils.matcherHint)(916            matcherName,917            undefined,918            expectedArgument,919            options920          ) +921          '\n\n' +922          (hasValue923            ? `Expected path: ${(0, _jestMatcherUtils.printExpected)(924                expectedPath925              )}\n\n` +926              `Expected value: not ${(0, _jestMatcherUtils.printExpected)(927                expectedValue928              )}` +929              ((0, _jestMatcherUtils.stringify)(expectedValue) !==930              (0, _jestMatcherUtils.stringify)(receivedValue)931                ? `\nReceived value:     ${(0, _jestMatcherUtils.printReceived)(932                    receivedValue933                  )}`934                : '')935            : `Expected path: not ${(0, _jestMatcherUtils.printExpected)(936                expectedPath937              )}\n\n` +938              `Received value: ${(0, _jestMatcherUtils.printReceived)(939                receivedValue940              )}`)941      : () =>942          (0, _jestMatcherUtils.matcherHint)(943            matcherName,944            undefined,945            expectedArgument,946            options947          ) +948          '\n\n' +949          `Expected path: ${(0, _jestMatcherUtils.printExpected)(950            expectedPath951          )}\n` +952          (hasCompletePath953            ? '\n' +954              (0, _jestMatcherUtils.printDiffOrStringify)(955                expectedValue,956                receivedValue,957                EXPECTED_VALUE_LABEL,958                RECEIVED_VALUE_LABEL,959                isExpand(this.expand)960              )961            : `Received path: ${(0, _jestMatcherUtils.printReceived)(962                expectedPathType === 'array' || receivedPath.length === 0963                  ? receivedPath964                  : receivedPath.join('.')965              )}\n\n` +966              (hasValue967                ? `Expected value: ${(0, _jestMatcherUtils.printExpected)(968                    expectedValue969                  )}\n`970                : '') +971              `Received value: ${(0, _jestMatcherUtils.printReceived)(972                receivedValue973              )}`);974    return {975      message,976      pass977    };978  },979  toMatch(received, expected) {980    const matcherName = 'toMatch';981    const options = {982      isNot: this.isNot,983      promise: this.promise984    };985    if (typeof received !== 'string') {986      throw new Error(987        (0, _jestMatcherUtils.matcherErrorMessage)(988          (0, _jestMatcherUtils.matcherHint)(989            matcherName,990            undefined,991            undefined,992            options993          ),994          `${(0, _jestMatcherUtils.RECEIVED_COLOR)(995            'received'996          )} value must be a string`,997          (0, _jestMatcherUtils.printWithType)(998            'Received',999            received,1000            _jestMatcherUtils.printReceived1001          )1002        )1003      );1004    }1005    if (1006      !(typeof expected === 'string') &&1007      !(expected && typeof expected.test === 'function')1008    ) {1009      throw new Error(1010        (0, _jestMatcherUtils.matcherErrorMessage)(1011          (0, _jestMatcherUtils.matcherHint)(1012            matcherName,1013            undefined,1014            undefined,1015            options1016          ),1017          `${(0, _jestMatcherUtils.EXPECTED_COLOR)(1018            'expected'1019          )} value must be a string or regular expression`,1020          (0, _jestMatcherUtils.printWithType)(1021            'Expected',1022            expected,1023            _jestMatcherUtils.printExpected1024          )1025        )1026      );1027    }1028    const pass =1029      typeof expected === 'string'1030        ? received.includes(expected)1031        : expected.test(received);1032    const message = pass1033      ? () =>1034          typeof expected === 'string'1035            ? (0, _jestMatcherUtils.matcherHint)(1036                matcherName,1037                undefined,1038                undefined,1039                options1040              ) +1041              '\n\n' +1042              `Expected substring: not ${(0, _jestMatcherUtils.printExpected)(1043                expected1044              )}\n` +1045              `Received string:        ${(0,1046              _print.printReceivedStringContainExpectedSubstring)(1047                received,1048                received.indexOf(expected),1049                expected.length1050              )}`1051            : (0, _jestMatcherUtils.matcherHint)(1052                matcherName,1053                undefined,1054                undefined,1055                options1056              ) +1057              '\n\n' +1058              `Expected pattern: not ${(0, _jestMatcherUtils.printExpected)(1059                expected1060              )}\n` +1061              `Received string:      ${(0,1062              _print.printReceivedStringContainExpectedResult)(1063                received,1064                typeof expected.exec === 'function'1065                  ? expected.exec(received)1066                  : null1067              )}`1068      : () => {1069          const labelExpected = `Expected ${1070            typeof expected === 'string' ? 'substring' : 'pattern'1071          }`;1072          const labelReceived = 'Received string';1073          const printLabel = (0, _jestMatcherUtils.getLabelPrinter)(1074            labelExpected,1075            labelReceived1076          );1077          return (1078            (0, _jestMatcherUtils.matcherHint)(1079              matcherName,1080              undefined,1081              undefined,1082              options1083            ) +1084            '\n\n' +1085            `${printLabel(labelExpected)}${(0, _jestMatcherUtils.printExpected)(1086              expected1087            )}\n` +1088            `${printLabel(labelReceived)}${(0, _jestMatcherUtils.printReceived)(1089              received1090            )}`1091          );1092        };1093    return {1094      message,1095      pass1096    };1097  },1098  toMatchObject(received, expected) {1099    const matcherName = 'toMatchObject';1100    const options = {1101      isNot: this.isNot,1102      promise: this.promise1103    };1104    if (typeof received !== 'object' || received === null) {1105      throw new Error(1106        (0, _jestMatcherUtils.matcherErrorMessage)(1107          (0, _jestMatcherUtils.matcherHint)(1108            matcherName,1109            undefined,1110            undefined,1111            options1112          ),1113          `${(0, _jestMatcherUtils.RECEIVED_COLOR)(1114            'received'1115          )} value must be a non-null object`,1116          (0, _jestMatcherUtils.printWithType)(1117            'Received',1118            received,1119            _jestMatcherUtils.printReceived1120          )1121        )1122      );1123    }1124    if (typeof expected !== 'object' || expected === null) {1125      throw new Error(1126        (0, _jestMatcherUtils.matcherErrorMessage)(1127          (0, _jestMatcherUtils.matcherHint)(1128            matcherName,1129            undefined,1130            undefined,1131            options1132          ),1133          `${(0, _jestMatcherUtils.EXPECTED_COLOR)(1134            'expected'1135          )} value must be a non-null object`,1136          (0, _jestMatcherUtils.printWithType)(1137            'Expected',1138            expected,1139            _jestMatcherUtils.printExpected1140          )1141        )1142      );1143    }1144    const pass = (0, _jasmineUtils.equals)(received, expected, [1145      _utils.iterableEquality,1146      _utils.subsetEquality1147    ]);1148    const message = pass1149      ? () =>1150          (0, _jestMatcherUtils.matcherHint)(1151            matcherName,1152            undefined,1153            undefined,1154            options1155          ) +1156          '\n\n' +1157          `Expected: not ${(0, _jestMatcherUtils.printExpected)(expected)}` +1158          ((0, _jestMatcherUtils.stringify)(expected) !==1159          (0, _jestMatcherUtils.stringify)(received)1160            ? `\nReceived:     ${(0, _jestMatcherUtils.printReceived)(1161                received1162              )}`1163            : '')1164      : () =>1165          (0, _jestMatcherUtils.matcherHint)(1166            matcherName,1167            undefined,1168            undefined,1169            options1170          ) +1171          '\n\n' +1172          (0, _jestMatcherUtils.printDiffOrStringify)(1173            expected,1174            (0, _utils.getObjectSubset)(received, expected),1175            EXPECTED_LABEL,1176            RECEIVED_LABEL,1177            isExpand(this.expand)1178          );1179    return {1180      message,1181      pass1182    };1183  },1184  toStrictEqual(received, expected) {1185    const matcherName = 'toStrictEqual';1186    const options = {1187      comment: 'deep equality',1188      isNot: this.isNot,1189      promise: this.promise1190    };1191    const pass = (0, _jasmineUtils.equals)(1192      received,1193      expected,1194      toStrictEqualTesters,1195      true1196    );1197    const message = pass1198      ? () =>1199          (0, _jestMatcherUtils.matcherHint)(1200            matcherName,1201            undefined,1202            undefined,1203            options1204          ) +1205          '\n\n' +1206          `Expected: not ${(0, _jestMatcherUtils.printExpected)(expected)}\n` +1207          ((0, _jestMatcherUtils.stringify)(expected) !==1208          (0, _jestMatcherUtils.stringify)(received)1209            ? `Received:     ${(0, _jestMatcherUtils.printReceived)(received)}`1210            : '')1211      : () =>1212          (0, _jestMatcherUtils.matcherHint)(1213            matcherName,1214            undefined,1215            undefined,1216            options1217          ) +1218          '\n\n' +1219          (0, _jestMatcherUtils.printDiffOrStringify)(1220            expected,1221            received,1222            EXPECTED_LABEL,1223            RECEIVED_LABEL,1224            isExpand(this.expand)1225          ); // Passing the actual and expected objects so that a custom reporter1226    // could access them, for example in order to display a custom visual diff,1227    // or create a different error message1228    return {1229      actual: received,1230      expected,1231      message,1232      name: matcherName,1233      pass1234    };1235  }1236};1237var _default = matchers;...boolean.spec.ts
Source:boolean.spec.ts  
1import { ZBoolean, ZFalse, ZTrue } from '../_internals'2import { generateBaseSpec } from '../spec-utils'3generateBaseSpec('ZBoolean', ZBoolean, {4  expectedTypeName: 'ZBoolean',5  expectedHints: {6    default: 'boolean',7    optional: 'boolean | undefined',8    nullable: 'boolean | null',9    nullish: 'boolean | null | undefined',10  },11  should: {12    true: { parse: true },13    false: { parse: true },14    // NOT15    undefined: {16      parse: false,17      expectedIssue: { code: 'any.required', message: '"value" is required' },18    },19    null: {20      parse: false,21      expectedIssue: {22        code: 'boolean.base',23        message: '"value" must be a boolean',24      },25    },26    'BigInt(-100)': {27      parse: false,28      expectedIssue: {29        code: 'boolean.base',30        message: '"value" must be a boolean',31      },32    },33    'BigInt(0)': {34      parse: false,35      expectedIssue: {36        code: 'boolean.base',37        message: '"value" must be a boolean',38      },39    },40    'BigInt(100)': {41      parse: false,42      expectedIssue: {43        code: 'boolean.base',44        message: '"value" must be a boolean',45      },46    },47    NaN: {48      parse: false,49      expectedIssue: {50        code: 'boolean.base',51        message: '"value" must be a boolean',52      },53    },54    A: {55      parse: false,56      expectedIssue: {57        code: 'boolean.base',58        message: '"value" must be a boolean',59      },60    },61    B: {62      parse: false,63      expectedIssue: {64        code: 'boolean.base',65        message: '"value" must be a boolean',66      },67    },68    C: {69      parse: false,70      expectedIssue: {71        code: 'boolean.base',72        message: '"value" must be a boolean',73      },74    },75    '-100.123': {76      parse: false,77      expectedIssue: {78        code: 'boolean.base',79        message: '"value" must be a boolean',80      },81    },82    '-100': {83      parse: false,84      expectedIssue: {85        code: 'boolean.base',86        message: '"value" must be a boolean',87      },88    },89    '-10': {90      parse: false,91      expectedIssue: {92        code: 'boolean.base',93        message: '"value" must be a boolean',94      },95    },96    '-1': {97      parse: false,98      expectedIssue: {99        code: 'boolean.base',100        message: '"value" must be a boolean',101      },102    },103    '0': {104      parse: false,105      expectedIssue: {106        code: 'boolean.base',107        message: '"value" must be a boolean',108      },109    },110    '1': {111      parse: false,112      expectedIssue: {113        code: 'boolean.base',114        message: '"value" must be a boolean',115      },116    },117    '10': {118      parse: false,119      expectedIssue: {120        code: 'boolean.base',121        message: '"value" must be a boolean',122      },123    },124    '100': {125      parse: false,126      expectedIssue: {127        code: 'boolean.base',128        message: '"value" must be a boolean',129      },130    },131    '100.123': {132      parse: false,133      expectedIssue: {134        code: 'boolean.base',135        message: '"value" must be a boolean',136      },137    },138    yesterday: {139      parse: false,140      expectedIssue: {141        code: 'boolean.base',142        message: '"value" must be a boolean',143      },144    },145    now: {146      parse: false,147      expectedIssue: {148        code: 'boolean.base',149        message: '"value" must be a boolean',150      },151    },152    tomorrow: {153      parse: false,154      expectedIssue: {155        code: 'boolean.base',156        message: '"value" must be a boolean',157      },158    },159    isostring: {160      parse: false,161      expectedIssue: {162        code: 'boolean.base',163        message: '"value" must be a boolean',164      },165    },166  },167  additionalSpecs: [168    {169      title: 'should have .true() evaluate to a ZTrue instance',170      spec: z => expect(z.true()).toBeInstanceOf(ZTrue),171    },172    {173      title: 'should have .false() evaluate to a ZFalse instance',174      spec: z => expect(z.false()).toBeInstanceOf(ZFalse),175    },176  ],177  baseMethodsConfig: {178    nonnullable: {179      expectedHint: 'boolean',180      expectedIssues: {181        undefined: {182          code: 'any.required',183          message: '"value" is required',184        },185        null: {186          code: 'any.invalid',187          message: '"value" contains an invalid value',188        },189      },190    },191  },192})193generateBaseSpec('ZTrue', ZTrue, {194  expectedTypeName: 'ZTrue',195  expectedHints: {196    default: 'true',197    optional: 'true | undefined',198    nullable: 'true | null',199    nullish: 'true | null | undefined',200  },201  should: {202    true: { parse: true },203    // NOT204    undefined: {205      parse: false,206      expectedIssue: { code: 'any.required', message: '"value" is required' },207    },208    null: {209      parse: false,210      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },211    },212    false: {213      parse: false,214      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },215      when: {216        nullable: {217          expectedIssue: {218            code: 'any.only',219            message: '"value" must be one of [true, null]',220          },221        },222        nullish: {223          expectedIssue: {224            code: 'any.only',225            message: '"value" must be one of [true, null]',226          },227        },228      },229    },230    'BigInt(-100)': {231      parse: false,232      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },233      when: {234        nullable: {235          expectedIssue: {236            code: 'any.only',237            message: '"value" must be one of [true, null]',238          },239        },240        nullish: {241          expectedIssue: {242            code: 'any.only',243            message: '"value" must be one of [true, null]',244          },245        },246      },247    },248    'BigInt(0)': {249      parse: false,250      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },251      when: {252        nullable: {253          expectedIssue: {254            code: 'any.only',255            message: '"value" must be one of [true, null]',256          },257        },258        nullish: {259          expectedIssue: {260            code: 'any.only',261            message: '"value" must be one of [true, null]',262          },263        },264      },265    },266    'BigInt(100)': {267      parse: false,268      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },269      when: {270        nullable: {271          expectedIssue: {272            code: 'any.only',273            message: '"value" must be one of [true, null]',274          },275        },276        nullish: {277          expectedIssue: {278            code: 'any.only',279            message: '"value" must be one of [true, null]',280          },281        },282      },283    },284    NaN: {285      parse: false,286      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },287      when: {288        nullable: {289          expectedIssue: {290            code: 'any.only',291            message: '"value" must be one of [true, null]',292          },293        },294        nullish: {295          expectedIssue: {296            code: 'any.only',297            message: '"value" must be one of [true, null]',298          },299        },300      },301    },302    A: {303      parse: false,304      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },305      when: {306        nullable: {307          expectedIssue: {308            code: 'any.only',309            message: '"value" must be one of [true, null]',310          },311        },312        nullish: {313          expectedIssue: {314            code: 'any.only',315            message: '"value" must be one of [true, null]',316          },317        },318      },319    },320    B: {321      parse: false,322      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },323      when: {324        nullable: {325          expectedIssue: {326            code: 'any.only',327            message: '"value" must be one of [true, null]',328          },329        },330        nullish: {331          expectedIssue: {332            code: 'any.only',333            message: '"value" must be one of [true, null]',334          },335        },336      },337    },338    C: {339      parse: false,340      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },341      when: {342        nullable: {343          expectedIssue: {344            code: 'any.only',345            message: '"value" must be one of [true, null]',346          },347        },348        nullish: {349          expectedIssue: {350            code: 'any.only',351            message: '"value" must be one of [true, null]',352          },353        },354      },355    },356    '-100.123': {357      parse: false,358      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },359      when: {360        nullable: {361          expectedIssue: {362            code: 'any.only',363            message: '"value" must be one of [true, null]',364          },365        },366        nullish: {367          expectedIssue: {368            code: 'any.only',369            message: '"value" must be one of [true, null]',370          },371        },372      },373    },374    '-100': {375      parse: false,376      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },377      when: {378        nullable: {379          expectedIssue: {380            code: 'any.only',381            message: '"value" must be one of [true, null]',382          },383        },384        nullish: {385          expectedIssue: {386            code: 'any.only',387            message: '"value" must be one of [true, null]',388          },389        },390      },391    },392    '-10': {393      parse: false,394      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },395      when: {396        nullable: {397          expectedIssue: {398            code: 'any.only',399            message: '"value" must be one of [true, null]',400          },401        },402        nullish: {403          expectedIssue: {404            code: 'any.only',405            message: '"value" must be one of [true, null]',406          },407        },408      },409    },410    '-1': {411      parse: false,412      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },413      when: {414        nullable: {415          expectedIssue: {416            code: 'any.only',417            message: '"value" must be one of [true, null]',418          },419        },420        nullish: {421          expectedIssue: {422            code: 'any.only',423            message: '"value" must be one of [true, null]',424          },425        },426      },427    },428    '0': {429      parse: false,430      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },431      when: {432        nullable: {433          expectedIssue: {434            code: 'any.only',435            message: '"value" must be one of [true, null]',436          },437        },438        nullish: {439          expectedIssue: {440            code: 'any.only',441            message: '"value" must be one of [true, null]',442          },443        },444      },445    },446    '1': {447      parse: false,448      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },449      when: {450        nullable: {451          expectedIssue: {452            code: 'any.only',453            message: '"value" must be one of [true, null]',454          },455        },456        nullish: {457          expectedIssue: {458            code: 'any.only',459            message: '"value" must be one of [true, null]',460          },461        },462      },463    },464    '10': {465      parse: false,466      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },467      when: {468        nullable: {469          expectedIssue: {470            code: 'any.only',471            message: '"value" must be one of [true, null]',472          },473        },474        nullish: {475          expectedIssue: {476            code: 'any.only',477            message: '"value" must be one of [true, null]',478          },479        },480      },481    },482    '100': {483      parse: false,484      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },485      when: {486        nullable: {487          expectedIssue: {488            code: 'any.only',489            message: '"value" must be one of [true, null]',490          },491        },492        nullish: {493          expectedIssue: {494            code: 'any.only',495            message: '"value" must be one of [true, null]',496          },497        },498      },499    },500    '100.123': {501      parse: false,502      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },503      when: {504        nullable: {505          expectedIssue: {506            code: 'any.only',507            message: '"value" must be one of [true, null]',508          },509        },510        nullish: {511          expectedIssue: {512            code: 'any.only',513            message: '"value" must be one of [true, null]',514          },515        },516      },517    },518    yesterday: {519      parse: false,520      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },521      when: {522        nullable: {523          expectedIssue: {524            code: 'any.only',525            message: '"value" must be one of [true, null]',526          },527        },528        nullish: {529          expectedIssue: {530            code: 'any.only',531            message: '"value" must be one of [true, null]',532          },533        },534      },535    },536    now: {537      parse: false,538      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },539      when: {540        nullable: {541          expectedIssue: {542            code: 'any.only',543            message: '"value" must be one of [true, null]',544          },545        },546        nullish: {547          expectedIssue: {548            code: 'any.only',549            message: '"value" must be one of [true, null]',550          },551        },552      },553    },554    tomorrow: {555      parse: false,556      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },557      when: {558        nullable: {559          expectedIssue: {560            code: 'any.only',561            message: '"value" must be one of [true, null]',562          },563        },564        nullish: {565          expectedIssue: {566            code: 'any.only',567            message: '"value" must be one of [true, null]',568          },569        },570      },571    },572    isostring: {573      parse: false,574      expectedIssue: { code: 'any.only', message: '"value" must be [true]' },575      when: {576        nullable: {577          expectedIssue: {578            code: 'any.only',579            message: '"value" must be one of [true, null]',580          },581        },582        nullish: {583          expectedIssue: {584            code: 'any.only',585            message: '"value" must be one of [true, null]',586          },587        },588      },589    },590  },591  baseMethodsConfig: {592    nonnullable: {593      expectedHint: 'true',594      expectedIssues: {595        undefined: {596          code: 'any.required',597          message: '"value" is required',598        },599        null: {600          code: 'any.only',601          message: '"value" must be [true]',602        },603      },604    },605  },606})607generateBaseSpec('ZFalse', ZFalse, {608  expectedTypeName: 'ZFalse',609  expectedHints: {610    default: 'false',611    optional: 'false | undefined',612    nullable: 'false | null',613    nullish: 'false | null | undefined',614  },615  should: {616    false: { parse: true },617    // NOT618    undefined: {619      parse: false,620      expectedIssue: { code: 'any.required', message: '"value" is required' },621    },622    null: {623      parse: false,624      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },625    },626    true: {627      parse: false,628      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },629      when: {630        nullable: {631          expectedIssue: {632            code: 'any.only',633            message: '"value" must be one of [false, null]',634          },635        },636        nullish: {637          expectedIssue: {638            code: 'any.only',639            message: '"value" must be one of [false, null]',640          },641        },642      },643    },644    'BigInt(-100)': {645      parse: false,646      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },647      when: {648        nullable: {649          expectedIssue: {650            code: 'any.only',651            message: '"value" must be one of [false, null]',652          },653        },654        nullish: {655          expectedIssue: {656            code: 'any.only',657            message: '"value" must be one of [false, null]',658          },659        },660      },661    },662    'BigInt(0)': {663      parse: false,664      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },665      when: {666        nullable: {667          expectedIssue: {668            code: 'any.only',669            message: '"value" must be one of [false, null]',670          },671        },672        nullish: {673          expectedIssue: {674            code: 'any.only',675            message: '"value" must be one of [false, null]',676          },677        },678      },679    },680    'BigInt(100)': {681      parse: false,682      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },683      when: {684        nullable: {685          expectedIssue: {686            code: 'any.only',687            message: '"value" must be one of [false, null]',688          },689        },690        nullish: {691          expectedIssue: {692            code: 'any.only',693            message: '"value" must be one of [false, null]',694          },695        },696      },697    },698    NaN: {699      parse: false,700      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },701      when: {702        nullable: {703          expectedIssue: {704            code: 'any.only',705            message: '"value" must be one of [false, null]',706          },707        },708        nullish: {709          expectedIssue: {710            code: 'any.only',711            message: '"value" must be one of [false, null]',712          },713        },714      },715    },716    A: {717      parse: false,718      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },719      when: {720        nullable: {721          expectedIssue: {722            code: 'any.only',723            message: '"value" must be one of [false, null]',724          },725        },726        nullish: {727          expectedIssue: {728            code: 'any.only',729            message: '"value" must be one of [false, null]',730          },731        },732      },733    },734    B: {735      parse: false,736      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },737      when: {738        nullable: {739          expectedIssue: {740            code: 'any.only',741            message: '"value" must be one of [false, null]',742          },743        },744        nullish: {745          expectedIssue: {746            code: 'any.only',747            message: '"value" must be one of [false, null]',748          },749        },750      },751    },752    C: {753      parse: false,754      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },755      when: {756        nullable: {757          expectedIssue: {758            code: 'any.only',759            message: '"value" must be one of [false, null]',760          },761        },762        nullish: {763          expectedIssue: {764            code: 'any.only',765            message: '"value" must be one of [false, null]',766          },767        },768      },769    },770    '-100.123': {771      parse: false,772      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },773      when: {774        nullable: {775          expectedIssue: {776            code: 'any.only',777            message: '"value" must be one of [false, null]',778          },779        },780        nullish: {781          expectedIssue: {782            code: 'any.only',783            message: '"value" must be one of [false, null]',784          },785        },786      },787    },788    '-100': {789      parse: false,790      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },791      when: {792        nullable: {793          expectedIssue: {794            code: 'any.only',795            message: '"value" must be one of [false, null]',796          },797        },798        nullish: {799          expectedIssue: {800            code: 'any.only',801            message: '"value" must be one of [false, null]',802          },803        },804      },805    },806    '-10': {807      parse: false,808      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },809      when: {810        nullable: {811          expectedIssue: {812            code: 'any.only',813            message: '"value" must be one of [false, null]',814          },815        },816        nullish: {817          expectedIssue: {818            code: 'any.only',819            message: '"value" must be one of [false, null]',820          },821        },822      },823    },824    '-1': {825      parse: false,826      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },827      when: {828        nullable: {829          expectedIssue: {830            code: 'any.only',831            message: '"value" must be one of [false, null]',832          },833        },834        nullish: {835          expectedIssue: {836            code: 'any.only',837            message: '"value" must be one of [false, null]',838          },839        },840      },841    },842    '0': {843      parse: false,844      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },845      when: {846        nullable: {847          expectedIssue: {848            code: 'any.only',849            message: '"value" must be one of [false, null]',850          },851        },852        nullish: {853          expectedIssue: {854            code: 'any.only',855            message: '"value" must be one of [false, null]',856          },857        },858      },859    },860    '1': {861      parse: false,862      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },863      when: {864        nullable: {865          expectedIssue: {866            code: 'any.only',867            message: '"value" must be one of [false, null]',868          },869        },870        nullish: {871          expectedIssue: {872            code: 'any.only',873            message: '"value" must be one of [false, null]',874          },875        },876      },877    },878    '10': {879      parse: false,880      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },881      when: {882        nullable: {883          expectedIssue: {884            code: 'any.only',885            message: '"value" must be one of [false, null]',886          },887        },888        nullish: {889          expectedIssue: {890            code: 'any.only',891            message: '"value" must be one of [false, null]',892          },893        },894      },895    },896    '100': {897      parse: false,898      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },899      when: {900        nullable: {901          expectedIssue: {902            code: 'any.only',903            message: '"value" must be one of [false, null]',904          },905        },906        nullish: {907          expectedIssue: {908            code: 'any.only',909            message: '"value" must be one of [false, null]',910          },911        },912      },913    },914    '100.123': {915      parse: false,916      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },917      when: {918        nullable: {919          expectedIssue: {920            code: 'any.only',921            message: '"value" must be one of [false, null]',922          },923        },924        nullish: {925          expectedIssue: {926            code: 'any.only',927            message: '"value" must be one of [false, null]',928          },929        },930      },931    },932    yesterday: {933      parse: false,934      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },935      when: {936        nullable: {937          expectedIssue: {938            code: 'any.only',939            message: '"value" must be one of [false, null]',940          },941        },942        nullish: {943          expectedIssue: {944            code: 'any.only',945            message: '"value" must be one of [false, null]',946          },947        },948      },949    },950    now: {951      parse: false,952      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },953      when: {954        nullable: {955          expectedIssue: {956            code: 'any.only',957            message: '"value" must be one of [false, null]',958          },959        },960        nullish: {961          expectedIssue: {962            code: 'any.only',963            message: '"value" must be one of [false, null]',964          },965        },966      },967    },968    tomorrow: {969      parse: false,970      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },971      when: {972        nullable: {973          expectedIssue: {974            code: 'any.only',975            message: '"value" must be one of [false, null]',976          },977        },978        nullish: {979          expectedIssue: {980            code: 'any.only',981            message: '"value" must be one of [false, null]',982          },983        },984      },985    },986    isostring: {987      parse: false,988      expectedIssue: { code: 'any.only', message: '"value" must be [false]' },989      when: {990        nullable: {991          expectedIssue: {992            code: 'any.only',993            message: '"value" must be one of [false, null]',994          },995        },996        nullish: {997          expectedIssue: {998            code: 'any.only',999            message: '"value" must be one of [false, null]',1000          },1001        },1002      },1003    },1004  },1005  baseMethodsConfig: {1006    nonnullable: {1007      expectedHint: 'false',1008      expectedIssues: {1009        undefined: {1010          code: 'any.required',1011          message: '"value" is required',1012        },1013        null: {1014          code: 'any.only',1015          message: '"value" must be [false]',1016        },1017      },1018    },1019  },...function_spec.js
Source:function_spec.js  
1/* globals expect, it, describe, beforeEach, isArray, StringStream,2           PostScriptParser, PostScriptLexer, PostScriptEvaluator,3           PostScriptCompiler*/4'use strict';5describe('function', function() {6  beforeEach(function() {7    this.addMatchers({8      toMatchArray: function(expected) {9        var actual = this.actual;10        if (actual.length !== expected.length) {11          return false;12        }13        for (var i = 0; i < expected.length; i++) {14          var a = actual[i], b = expected[i];15          if (isArray(b)) {16            if (a.length !== b.length) {17              return false;18            }19            for (var j = 0; j < a.length; j++) {20              var suba = a[j], subb = b[j];21              if (suba !== subb) {22                return false;23              }24            }25          } else {26            if (a !== b) {27              return false;28            }29          }30        }31        return true;32      }33    });34  });35  describe('PostScriptParser', function() {36    function parse(program) {37      var stream = new StringStream(program);38      var parser = new PostScriptParser(new PostScriptLexer(stream));39      return parser.parse();40    }41    it('parses empty programs', function() {42      var output = parse('{}');43      expect(output.length).toEqual(0);44    });45    it('parses positive numbers', function() {46      var number = 999;47      var program = parse('{ ' + number + ' }');48      var expectedProgram = [number];49      expect(program).toMatchArray(expectedProgram);50    });51    it('parses negative numbers', function() {52      var number = -999;53      var program = parse('{ ' + number + ' }');54      var expectedProgram = [number];55      expect(program).toMatchArray(expectedProgram);56    });57    it('parses negative floats', function() {58      var number = 3.3;59      var program = parse('{ ' + number + ' }');60      var expectedProgram = [number];61      expect(program).toMatchArray(expectedProgram);62    });63    it('parses operators', function() {64      var program = parse('{ sub }');65      var expectedProgram = ['sub'];66      expect(program).toMatchArray(expectedProgram);67    });68    it('parses if statements', function() {69      var program = parse('{ { 99 } if }');70      var expectedProgram = [3, 'jz', 99];71      expect(program).toMatchArray(expectedProgram);72    });73    it('parses ifelse statements', function() {74      var program = parse('{ { 99 } { 44 } ifelse }');75      var expectedProgram = [5, 'jz', 99, 6, 'j', 44];76      expect(program).toMatchArray(expectedProgram);77    });78    it('handles missing brackets', function() {79      expect(function() { parse('{'); }).toThrow(80        new Error('Unexpected symbol: found undefined expected 1.'));81    });82    it('handles junk after the end', function() {83      var number = 3.3;84      var program = parse('{ ' + number + ' }#');85      var expectedProgram = [number];86      expect(program).toMatchArray(expectedProgram);87    });88  });89  describe('PostScriptEvaluator', function() {90    function evaluate(program) {91      var stream = new StringStream(program);92      var parser = new PostScriptParser(new PostScriptLexer(stream));93      var code = parser.parse();94      var evaluator = new PostScriptEvaluator(code);95      var output = evaluator.execute();96      return output;97    }98    it('pushes stack', function() {99      var stack = evaluate('{ 99 }');100      var expectedStack = [99];101      expect(stack).toMatchArray(expectedStack);102    });103    it('handles if with true', function() {104      var stack = evaluate('{ 1 {99} if }');105      var expectedStack = [99];106      expect(stack).toMatchArray(expectedStack);107    });108    it('handles if with false', function() {109      var stack = evaluate('{ 0 {99} if }');110      var expectedStack = [];111      expect(stack).toMatchArray(expectedStack);112    });113    it('handles ifelse with true', function() {114      var stack = evaluate('{ 1 {99} {77} ifelse }');115      var expectedStack = [99];116      expect(stack).toMatchArray(expectedStack);117    });118    it('handles ifelse with false', function() {119      var stack = evaluate('{ 0 {99} {77} ifelse }');120      var expectedStack = [77];121      expect(stack).toMatchArray(expectedStack);122    });123    it('handles nested if', function() {124      var stack = evaluate('{ 1 {1 {77} if} if }');125      var expectedStack = [77];126      expect(stack).toMatchArray(expectedStack);127    });128    it('abs', function() {129      var stack = evaluate('{ -2 abs }');130      var expectedStack = [2];131      expect(stack).toMatchArray(expectedStack);132    });133    it('adds', function() {134      var stack = evaluate('{ 1 2 add }');135      var expectedStack = [3];136      expect(stack).toMatchArray(expectedStack);137    });138    it('boolean and', function() {139      var stack = evaluate('{ true false and }');140      var expectedStack = [false];141      expect(stack).toMatchArray(expectedStack);142    });143    it('bitwise and', function() {144      var stack = evaluate('{ 254 1 and }');145      var expectedStack = [254 & 1];146      expect(stack).toMatchArray(expectedStack);147    });148    it('calculates the inverse tangent of a number', function() {149      var stack = evaluate('{ 90 atan }');150      var expectedStack = [Math.atan(90)];151      expect(stack).toMatchArray(expectedStack);152    });153    it('handles bitshifting ', function() {154      var stack = evaluate('{ 50 2 bitshift }');155      var expectedStack = [200];156      expect(stack).toMatchArray(expectedStack);157    });158    it('calculates the ceiling value', function() {159      var stack = evaluate('{ 9.9 ceiling }');160      var expectedStack = [10];161      expect(stack).toMatchArray(expectedStack);162    });163    it('copies', function() {164      var stack = evaluate('{ 99 98 2 copy }');165      var expectedStack = [99, 98, 99, 98];166      expect(stack).toMatchArray(expectedStack);167    });168    it('calculates the cosine of a number', function() {169      var stack = evaluate('{ 90 cos }');170      var expectedStack = [Math.cos(90)];171      expect(stack).toMatchArray(expectedStack);172    });173    it('converts to int', function() {174      var stack = evaluate('{ 9.9 cvi }');175      var expectedStack = [9];176      expect(stack).toMatchArray(expectedStack);177    });178    it('converts negatives to int', function() {179      var stack = evaluate('{ -9.9 cvi }');180      var expectedStack = [-9];181      expect(stack).toMatchArray(expectedStack);182    });183    it('converts to real', function() {184      var stack = evaluate('{ 55.34 cvr }');185      var expectedStack = [55.34];186      expect(stack).toMatchArray(expectedStack);187    });188    it('divides', function() {189      var stack = evaluate('{ 6 5 div }');190      var expectedStack = [1.2];191      expect(stack).toMatchArray(expectedStack);192    });193    it('maps division by zero to infinity', function() {194      var stack = evaluate('{ 6 0 div }');195      var expectedStack = [Infinity];196      expect(stack).toMatchArray(expectedStack);197    });198    it('duplicates', function() {199      var stack = evaluate('{ 99 dup }');200      var expectedStack = [99, 99];201      expect(stack).toMatchArray(expectedStack);202    });203    it('accepts an equality', function() {204      var stack = evaluate('{ 9 9 eq }');205      var expectedStack = [true];206      expect(stack).toMatchArray(expectedStack);207    });208    it('rejects an inequality', function() {209      var stack = evaluate('{ 9 8 eq }');210      var expectedStack = [false];211      expect(stack).toMatchArray(expectedStack);212    });213    it('exchanges', function() {214      var stack = evaluate('{ 44 99 exch }');215      var expectedStack = [99, 44];216      expect(stack).toMatchArray(expectedStack);217    });218    it('handles exponentiation', function() {219      var stack = evaluate('{ 10 2 exp }');220      var expectedStack = [100];221      expect(stack).toMatchArray(expectedStack);222    });223    it('pushes false onto the stack', function() {224      var stack = evaluate('{ false }');225      var expectedStack = [false];226      expect(stack).toMatchArray(expectedStack);227    });228    it('calculates the floor value', function() {229      var stack = evaluate('{ 9.9 floor }');230      var expectedStack = [9];231      expect(stack).toMatchArray(expectedStack);232    });233    it('handles greater than or equal to', function() {234      var stack = evaluate('{ 10 9 ge }');235      var expectedStack = [true];236      expect(stack).toMatchArray(expectedStack);237    });238    it('rejects less than for greater than or equal to', function() {239      var stack = evaluate('{ 8 9 ge }');240      var expectedStack = [false];241      expect(stack).toMatchArray(expectedStack);242    });243    it('handles greater than', function() {244      var stack = evaluate('{ 10 9 gt }');245      var expectedStack = [true];246      expect(stack).toMatchArray(expectedStack);247    });248    it('rejects less than or equal for greater than', function() {249      var stack = evaluate('{ 9 9 gt }');250      var expectedStack = [false];251      expect(stack).toMatchArray(expectedStack);252    });253    it('divides to integer', function() {254      var stack = evaluate('{ 2 3 idiv }');255      var expectedStack = [0];256      expect(stack).toMatchArray(expectedStack);257    });258    it('divides to negative integer', function() {259      var stack = evaluate('{ -2 3 idiv }');260      var expectedStack = [0];261      expect(stack).toMatchArray(expectedStack);262    });263    it('duplicates index', function() {264      var stack = evaluate('{ 4 3 2 1 2 index }');265      var expectedStack = [4, 3, 2, 1, 3];266      expect(stack).toMatchArray(expectedStack);267    });268    it('handles less than or equal to', function() {269      var stack = evaluate('{ 9 10 le }');270      var expectedStack = [true];271      expect(stack).toMatchArray(expectedStack);272    });273    it('rejects greater than for less than or equal to', function() {274      var stack = evaluate('{ 10 9 le }');275      var expectedStack = [false];276      expect(stack).toMatchArray(expectedStack);277    });278    it('calculates the natural logarithm', function() {279      var stack = evaluate('{ 10 ln }');280      var expectedStack = [Math.log(10)];281      expect(stack).toMatchArray(expectedStack);282    });283    it('calculates the base 10 logarithm', function() {284      var stack = evaluate('{ 100 log }');285      var expectedStack = [2];286      expect(stack).toMatchArray(expectedStack);287    });288    it('handles less than', function() {289      var stack = evaluate('{ 9 10 lt }');290      var expectedStack = [true];291      expect(stack).toMatchArray(expectedStack);292    });293    it('rejects greater than or equal to for less than', function() {294      var stack = evaluate('{ 10 9 lt }');295      var expectedStack = [false];296      expect(stack).toMatchArray(expectedStack);297    });298    it('performs the modulo operation', function() {299      var stack = evaluate('{ 4 3 mod }');300      var expectedStack = [1];301      expect(stack).toMatchArray(expectedStack);302    });303    it('multiplies two numbers (positive result)', function() {304      var stack = evaluate('{ 9 8 mul }');305      var expectedStack = [72];306      expect(stack).toMatchArray(expectedStack);307    });308    it('multiplies two numbers (negative result)', function() {309      var stack = evaluate('{ 9 -8 mul }');310      var expectedStack = [-72];311      expect(stack).toMatchArray(expectedStack);312    });313    it('accepts an inequality', function() {314      var stack = evaluate('{ 9 8 ne }');315      var expectedStack = [true];316      expect(stack).toMatchArray(expectedStack);317    });318    it('rejects an equality', function() {319      var stack = evaluate('{ 9 9 ne }');320      var expectedStack = [false];321      expect(stack).toMatchArray(expectedStack);322    });323    it('negates', function() {324      var stack = evaluate('{ 4.5 neg }');325      var expectedStack = [-4.5];326      expect(stack).toMatchArray(expectedStack);327    });328    it('boolean not', function() {329      var stack = evaluate('{ true not }');330      var expectedStack = [false];331      expect(stack).toMatchArray(expectedStack);332    });333    it('bitwise not', function() {334      var stack = evaluate('{ 12 not }');335      var expectedStack = [-13];336      expect(stack).toMatchArray(expectedStack);337    });338    it('boolean or', function() {339      var stack = evaluate('{ true false or }');340      var expectedStack = [true];341      expect(stack).toMatchArray(expectedStack);342    });343    it('bitwise or', function() {344      var stack = evaluate('{ 254 1 or }');345      var expectedStack = [254 | 1];346      expect(stack).toMatchArray(expectedStack);347    });348    it('pops stack', function() {349      var stack = evaluate('{ 1 2 pop }');350      var expectedStack = [1];351      expect(stack).toMatchArray(expectedStack);352    });353    it('rolls stack right', function() {354      var stack = evaluate('{ 1 3 2 2 4 1 roll }');355      var expectedStack = [2, 1, 3, 2];356      expect(stack).toMatchArray(expectedStack);357    });358    it('rolls stack left', function() {359      var stack = evaluate('{ 1 3 2 2 4 -1 roll }');360      var expectedStack = [3, 2, 2, 1];361      expect(stack).toMatchArray(expectedStack);362    });363    it('rounds a number', function() {364      var stack = evaluate('{ 9.52 round }');365      var expectedStack = [10];366      expect(stack).toMatchArray(expectedStack);367    });368    it('calculates the sine of a number', function() {369      var stack = evaluate('{ 90 sin }');370      var expectedStack = [Math.sin(90)];371      expect(stack).toMatchArray(expectedStack);372    });373    it('calculates a square root (integer)', function() {374      var stack = evaluate('{ 100 sqrt }');375      var expectedStack = [10];376      expect(stack).toMatchArray(expectedStack);377    });378    it('calculates a square root (float)', function() {379      var stack = evaluate('{ 99 sqrt }');380      var expectedStack = [Math.sqrt(99)];381      expect(stack).toMatchArray(expectedStack);382    });383    it('subtracts (positive result)', function() {384      var stack = evaluate('{ 6 4 sub }');385      var expectedStack = [2];386      expect(stack).toMatchArray(expectedStack);387    });388    it('subtracts (negative result)', function() {389      var stack = evaluate('{ 4 6 sub }');390      var expectedStack = [-2];391      expect(stack).toMatchArray(expectedStack);392    });393    it('pushes true onto the stack', function() {394      var stack = evaluate('{ true }');395      var expectedStack = [true];396      expect(stack).toMatchArray(expectedStack);397    });398    it('truncates a number', function() {399      var stack = evaluate('{ 35.004 truncate }');400      var expectedStack = [35];401      expect(stack).toMatchArray(expectedStack);402    });403    it('calculates an exclusive or value', function() {404      var stack = evaluate('{ 3 9 xor }');405      var expectedStack = [10];406      expect(stack).toMatchArray(expectedStack);407    });408  });409  describe('PostScriptCompiler', function() {410    function check(code, domain, range, samples) {411      var compiler = new PostScriptCompiler();412      var compiledCode = compiler.compile(code, domain, range);413      if (samples === null) {414        expect(compiledCode).toBeNull();415      } else {416        expect(compiledCode).not.toBeNull();417        /*jshint -W054 */418        var fn = new Function('src', 'srcOffset', 'dest', 'destOffset',419                              compiledCode);420        for (var i = 0; i < samples.length; i++) {421          var out = new Float32Array(samples[i].output.length);422          fn(samples[i].input, 0, out, 0);423          expect(Array.prototype.slice.call(out, 0)).424            toMatchArray(samples[i].output);425        }426      }427    }428    it('check compiled add', function() {429      check([0.25, 0.5, 'add'], [], [0, 1], [{input: [], output: [0.75]}]);430      check([0, 'add'], [0, 1], [0, 1], [{input: [0.25], output: [0.25]}]);431      check([0.5, 'add'], [0, 1], [0, 1], [{input: [0.25], output: [0.75]}]);432      check([0, 'exch', 'add'], [0, 1], [0, 1],433            [{input: [0.25], output: [0.25]}]);434      check([0.5, 'exch', 'add'], [0, 1], [0, 1],435            [{input: [0.25], output: [0.75]}]);436      check(['add'], [0, 1, 0, 1], [0, 1],437            [{input: [0.25, 0.5], output: [0.75]}]);438      check(['add'], [0, 1], [0, 1], null);439    });440    it('check compiled sub', function() {441      check([0.5, 0.25, 'sub'], [], [0, 1], [{input: [], output: [0.25]}]);442      check([0, 'sub'], [0, 1], [0, 1], [{input: [0.25], output: [0.25]}]);443      check([0.5, 'sub'], [0, 1], [0, 1], [{input: [0.75], output: [0.25]}]);444      check([0, 'exch', 'sub'], [0, 1], [-1, 1],445            [{input: [0.25], output: [-0.25]}]);446      check([0.75, 'exch', 'sub'], [0, 1], [-1, 1],447            [{input: [0.25], output: [0.5]}]);448      check(['sub'], [0, 1, 0, 1], [-1, 1],449            [{input: [0.25, 0.5], output: [-0.25]}]);450      check(['sub'], [0, 1], [0, 1], null);451      check([1, 'dup', 3, 2, 'roll', 'sub', 'sub'], [0, 1], [0, 1],452            [{input: [0.75], output: [0.75]}]);453    });454    it('check compiled mul', function() {455      check([0.25, 0.5, 'mul'], [], [0, 1], [{input: [], output: [0.125]}]);456      check([0, 'mul'], [0, 1], [0, 1], [{input: [0.25], output: [0]}]);457      check([0.5, 'mul'], [0, 1], [0, 1], [{input: [0.25], output: [0.125]}]);458      check([1, 'mul'], [0, 1], [0, 1], [{input: [0.25], output: [0.25]}]);459      check([0, 'exch', 'mul'], [0, 1], [0, 1], [{input: [0.25], output: [0]}]);460      check([0.5, 'exch', 'mul'], [0, 1], [0, 1],461            [{input: [0.25], output: [0.125]}]);462      check([1, 'exch', 'mul'], [0, 1], [0, 1],463            [{input: [0.25], output: [0.25]}]);464      check(['mul'], [0, 1, 0, 1], [0, 1],465            [{input: [0.25, 0.5], output: [0.125]}]);466      check(['mul'], [0, 1], [0, 1], null);467    });468    it('check compiled max', function() {469      check(['dup', 0.75, 'gt', 7, 'jz', 'pop', 0.75], [0, 1], [0, 1],470            [{input: [0.5], output: [0.5]}]);471      check(['dup', 0.75, 'gt', 7, 'jz', 'pop', 0.75], [0, 1], [0, 1],472            [{input: [1], output: [0.75]}]);473      check(['dup', 0.75, 'gt', 5, 'jz', 'pop', 0.75], [0, 1], [0, 1], null);474    });475    it('check pop/roll/index', function() {476      check([1, 'pop'], [0, 1], [0, 1], [{input: [0.5], output: [0.5]}]);477      check([1, 3, -1, 'roll'], [0, 1, 0, 1], [0, 1, 0, 1, 0, 1],478            [{input: [0.25, 0.5], output: [0.5, 1, 0.25]}]);479      check([1, 3, 1, 'roll'], [0, 1, 0, 1], [0, 1, 0, 1, 0, 1],480            [{input: [0.25, 0.5], output: [1, 0.25, 0.5]}]);481      check([1, 3, 1.5, 'roll'], [0, 1, 0, 1], [0, 1, 0, 1, 0, 1], null);482      check([1, 1, 'index'], [0, 1], [0, 1, 0, 1, 0, 1],483            [{input: [0.5], output: [0.5, 1, 0.5]}]);484      check([1, 3, 'index', 'pop'], [0, 1], [0, 1], null);485      check([1, 0.5, 'index', 'pop'], [0, 1], [0, 1], null);486    });487    it('check input boundaries', function () {488      check([], [0, 0.5], [0, 1], [{input: [1], output: [0.5]}]);489      check([], [0.5, 1], [0, 1], [{input: [0], output: [0.5]}]);490      check(['dup'], [0.5, 0.75], [0, 1, 0, 1],491            [{input: [0], output: [0.5, 0.5]}]);492      check([], [100, 1001], [0, 10000], [{input: [1000], output: [1000]}]);493    });494    it('check output boundaries', function () {495      check([], [0, 1], [0, 0.5], [{input: [1], output: [0.5]}]);496      check([], [0, 1], [0.5, 1], [{input: [0], output: [0.5]}]);497      check(['dup'], [0, 1], [0.5, 1, 0.75, 1],498            [{input: [0], output: [0.5, 0.75]}]);499      check([], [0, 10000], [100, 1001], [{input: [1000], output: [1000]}]);500    });501    it('compile optimized', function () {502      var compiler = new PostScriptCompiler();503      var code = [0, 'add', 1, 1, 3, -1, 'roll', 'sub', 'sub', 1, 'mul'];504      var compiledCode = compiler.compile(code, [0, 1], [0, 1]);505      expect(compiledCode).toEqual(506        'dest[destOffset + 0] = Math.max(0, Math.min(1, src[srcOffset + 0]));');507    });508  });...check-layout-th.js
Source:check-layout-th.js  
1(function() {2// Test is initiated from body.onload, so explicit done() call is required.3setup({ explicit_done: true });4function checkSubtreeExpectedValues(t, parent, prefix)5{6    var checkedLayout = checkExpectedValues(t, parent, prefix);7    Array.prototype.forEach.call(parent.childNodes, function(node) {8        checkedLayout |= checkSubtreeExpectedValues(t, node, prefix);9    });10    return checkedLayout;11}12function checkAttribute(output, node, attribute)13{14    var result = node.getAttribute && node.getAttribute(attribute);15    output.checked |= !!result;16    return result;17}18function assert_tolerance(actual, expected, message)19{20    if (isNaN(expected) || Math.abs(actual - expected) >= 1) {21        assert_equals(actual, Number(expected), message);22    }23}24function checkDataKeys(node) {25    var validData = new Set([26        "data-expected-width",27        "data-expected-height",28        "data-offset-x",29        "data-offset-y",30        "data-expected-client-width",31        "data-expected-client-height",32        "data-expected-scroll-width",33        "data-expected-scroll-height",34        "data-expected-bounding-client-rect-width",35        "data-total-x",36        "data-total-y",37        "data-expected-display",38        "data-expected-padding-top",39        "data-expected-padding-bottom",40        "data-expected-padding-left",41        "data-expected-padding-right",42        "data-expected-margin-top",43        "data-expected-margin-bottom",44        "data-expected-margin-left",45        "data-expected-margin-right"46    ]);47    if (!node || !node.getAttributeNames)48        return;49    // Use "data-test" prefix if you need custom-named data elements.50    for (let name of node.getAttributeNames()) {51        if (name.startsWith("data-") && !name.startsWith("data-test"))52            assert_true(validData.has(name), name + " is a valid data attribute");53    }54}55function checkExpectedValues(t, node, prefix)56{57    checkDataKeys(node);58    var output = { checked: false };59    var expectedWidth = checkAttribute(output, node, "data-expected-width");60    if (expectedWidth) {61        assert_tolerance(node.offsetWidth, expectedWidth, prefix + "width");62    }63    var expectedHeight = checkAttribute(output, node, "data-expected-height");64    if (expectedHeight) {65        assert_tolerance(node.offsetHeight, expectedHeight, prefix + "height");66    }67    var expectedOffset = checkAttribute(output, node, "data-offset-x");68    if (expectedOffset) {69        assert_tolerance(node.offsetLeft, expectedOffset, prefix + "offsetLeft");70    }71    var expectedOffset = checkAttribute(output, node, "data-offset-y");72    if (expectedOffset) {73        assert_tolerance(node.offsetTop, expectedOffset, prefix + "offsetTop");74    }75    var expectedWidth = checkAttribute(output, node, "data-expected-client-width");76    if (expectedWidth) {77        assert_tolerance(node.clientWidth, expectedWidth, prefix + "clientWidth");78    }79    var expectedHeight = checkAttribute(output, node, "data-expected-client-height");80    if (expectedHeight) {81        assert_tolerance(node.clientHeight, expectedHeight, prefix + "clientHeight");82    }83    var expectedWidth = checkAttribute(output, node, "data-expected-scroll-width");84    if (expectedWidth) {85        assert_tolerance(node.scrollWidth, expectedWidth, prefix + "scrollWidth");86    }87    var expectedHeight = checkAttribute(output, node, "data-expected-scroll-height");88    if (expectedHeight) {89        assert_tolerance(node.scrollHeight, expectedHeight, prefix + "scrollHeight");90    }91    var expectedWidth = checkAttribute(output, node, "data-expected-bounding-client-rect-width");92    if (expectedWidth) {93        assert_tolerance(node.getBoundingClientRect().width, expectedWidth, prefix + "getBoundingClientRect().width");94    }95    var expectedOffset = checkAttribute(output, node, "data-total-x");96    if (expectedOffset) {97        var totalLeft = node.clientLeft + node.offsetLeft;98        assert_tolerance(totalLeft, expectedOffset, prefix +99                         "clientLeft+offsetLeft (" + node.clientLeft + " + " + node.offsetLeft + ")");100    }101    var expectedOffset = checkAttribute(output, node, "data-total-y");102    if (expectedOffset) {103        var totalTop = node.clientTop + node.offsetTop;104        assert_tolerance(totalTop, expectedOffset, prefix +105                         "clientTop+offsetTop (" + node.clientTop + " + " + node.offsetTop + ")");106    }107    var expectedDisplay = checkAttribute(output, node, "data-expected-display");108    if (expectedDisplay) {109        var actualDisplay = getComputedStyle(node).display;110        assert_equals(actualDisplay, expectedDisplay, prefix + "display");111    }112    var expectedPaddingTop = checkAttribute(output, node, "data-expected-padding-top");113    if (expectedPaddingTop) {114        var actualPaddingTop = getComputedStyle(node).paddingTop;115        // Trim the unit "px" from the output.116        actualPaddingTop = actualPaddingTop.slice(0, -2);117        assert_equals(actualPaddingTop, expectedPaddingTop, prefix + "padding-top");118    }119    var expectedPaddingBottom = checkAttribute(output, node, "data-expected-padding-bottom");120    if (expectedPaddingBottom) {121        var actualPaddingBottom = getComputedStyle(node).paddingBottom;122        // Trim the unit "px" from the output.123        actualPaddingBottom = actualPaddingBottom.slice(0, -2);124        assert_equals(actualPaddingBottom, expectedPaddingBottom, prefix + "padding-bottom");125    }126    var expectedPaddingLeft = checkAttribute(output, node, "data-expected-padding-left");127    if (expectedPaddingLeft) {128        var actualPaddingLeft = getComputedStyle(node).paddingLeft;129        // Trim the unit "px" from the output.130        actualPaddingLeft = actualPaddingLeft.slice(0, -2);131        assert_equals(actualPaddingLeft, expectedPaddingLeft, prefix + "padding-left");132    }133    var expectedPaddingRight = checkAttribute(output, node, "data-expected-padding-right");134    if (expectedPaddingRight) {135        var actualPaddingRight = getComputedStyle(node).paddingRight;136        // Trim the unit "px" from the output.137        actualPaddingRight = actualPaddingRight.slice(0, -2);138        assert_equals(actualPaddingRight, expectedPaddingRight, prefix + "padding-right");139    }140    var expectedMarginTop = checkAttribute(output, node, "data-expected-margin-top");141    if (expectedMarginTop) {142        var actualMarginTop = getComputedStyle(node).marginTop;143        // Trim the unit "px" from the output.144        actualMarginTop = actualMarginTop.slice(0, -2);145        assert_equals(actualMarginTop, expectedMarginTop, prefix + "margin-top");146    }147    var expectedMarginBottom = checkAttribute(output, node, "data-expected-margin-bottom");148    if (expectedMarginBottom) {149        var actualMarginBottom = getComputedStyle(node).marginBottom;150        // Trim the unit "px" from the output.151        actualMarginBottom = actualMarginBottom.slice(0, -2);152        assert_equals(actualMarginBottom, expectedMarginBottom, prefix + "margin-bottom");153    }154    var expectedMarginLeft = checkAttribute(output, node, "data-expected-margin-left");155    if (expectedMarginLeft) {156        var actualMarginLeft = getComputedStyle(node).marginLeft;157        // Trim the unit "px" from the output.158        actualMarginLeft = actualMarginLeft.slice(0, -2);159        assert_equals(actualMarginLeft, expectedMarginLeft, prefix + "margin-left");160    }161    var expectedMarginRight = checkAttribute(output, node, "data-expected-margin-right");162    if (expectedMarginRight) {163        var actualMarginRight = getComputedStyle(node).marginRight;164        // Trim the unit "px" from the output.165        actualMarginRight = actualMarginRight.slice(0, -2);166        assert_equals(actualMarginRight, expectedMarginRight, prefix + "margin-right");167    }168    return output.checked;169}170var testNumber = 0;171var highlightError = false; // displays outline around failed test element.172var printDomOnError = true; // prints dom when test fails.173window.checkLayout = function(selectorList, callDone = true)174{175    if (!selectorList) {176        console.error("You must provide a CSS selector of nodes to check.");177        return;178    }179    var nodes = document.querySelectorAll(selectorList);180    nodes = Array.prototype.slice.call(nodes);181    var checkedLayout = false;182    Array.prototype.forEach.call(nodes, function(node) {183        test(function(t) {184            var container = node.parentNode.className == 'container' ? node.parentNode : node;185            var prefix =186                printDomOnError ? '\n' + container.outerHTML + '\n' : '';187            var passed = false;188            try {189                checkedLayout |= checkExpectedValues(t, node.parentNode, prefix);190                checkedLayout |= checkSubtreeExpectedValues(t, node, prefix);191                passed = true;192            } finally {193              if (!passed && highlightError) {194                if (!document.getElementById('testharness_error_css')) {195                  var style = document.createElement('style');196                  style.id = 'testharness_error_css';197                  style.textContent = '.testharness_error { outline: red dotted 2px !important; }';198                  document.body.appendChild(style);199                }200                if (node)201                  node.classList.add('testharness_error');202              }203                checkedLayout |= !passed;204            }205        }, selectorList + ' ' + String(++testNumber));206    });207    if (!checkedLayout) {208        console.error("No valid data-* attributes found in selector list : " + selectorList);209    }210    if (callDone)211        done();212};...hc_documentgetelementsbytagnametotallength.js
Source:hc_documentgetelementsbytagnametotallength.js  
1/*2Copyright é 2001-2004 World Wide Web Consortium, 3(Massachusetts Institute of Technology, European Research Consortium 4for Informatics and Mathematics, Keio University). All 5Rights Reserved. This work is distributed under the W3Cî Software License [1] in the 6hope that it will be useful, but WITHOUT ANY WARRANTY; without even 7the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 8[1] http://www.w3.org/Consortium/Legal/2002/copyright-software-200212319*/10   /**11    *  Gets URI that identifies the test.12    *  @return uri identifier of test13    */14function getTargetURI() {15      return "http://www.w3.org/2001/DOM-Test-Suite/level1/core/hc_documentgetelementsbytagnametotallength";16   }17var docsLoaded = -1000000;18var builder = null;19//20//   This function is called by the testing framework before21//      running the test suite.22//23//   If there are no configuration exceptions, asynchronous24//        document loading is started.  Otherwise, the status25//        is set to complete and the exception is immediately26//        raised when entering the body of the test.27//28function setUpPage() {29   setUpPageStatus = 'running';30   try {31     //32     //   creates test document builder, may throw exception33     //34     builder = createConfiguredBuilder();35      docsLoaded = 0;36      37      var docRef = null;38      if (typeof(this.doc) != 'undefined') {39        docRef = this.doc;40      }41      docsLoaded += preload(docRef, "doc", "hc_staff");42        43       if (docsLoaded == 1) {44          setUpPageStatus = 'complete';45       }46    } catch(ex) {47    	catchInitializationError(builder, ex);48        setUpPageStatus = 'complete';49    }50}51//52//   This method is called on the completion of 53//      each asychronous load started in setUpTests.54//55//   When every synchronous loaded document has completed,56//      the page status is changed which allows the57//      body of the test to be executed.58function loadComplete() {59    if (++docsLoaded == 1) {60        setUpPageStatus = 'complete';61    }62}63/**64* 65   Retrieve the entire DOM document and invoke its 66   "getElementsByTagName(tagName)" method with tagName67   equal to "*".  The method should return a NodeList 68   that contains all the elements of the document. 69* @author Curt Arnold70* @see http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core#ID-A6C909471* @see http://www.w3.org/Bugs/Public/show_bug.cgi?id=25172*/73function hc_documentgetelementsbytagnametotallength() {74   var success;75    if(checkInitialization(builder, "hc_documentgetelementsbytagnametotallength") != null) return;76    var doc;77      var nameList;78      expectedNames = new Array();79      expectedNames[0] = "html";80      expectedNames[1] = "head";81      expectedNames[2] = "meta";82      expectedNames[3] = "title";83      expectedNames[4] = "script";84      expectedNames[5] = "script";85      expectedNames[6] = "script";86      expectedNames[7] = "body";87      expectedNames[8] = "p";88      expectedNames[9] = "em";89      expectedNames[10] = "strong";90      expectedNames[11] = "code";91      expectedNames[12] = "sup";92      expectedNames[13] = "var";93      expectedNames[14] = "acronym";94      expectedNames[15] = "p";95      expectedNames[16] = "em";96      expectedNames[17] = "strong";97      expectedNames[18] = "code";98      expectedNames[19] = "sup";99      expectedNames[20] = "var";100      expectedNames[21] = "acronym";101      expectedNames[22] = "p";102      expectedNames[23] = "em";103      expectedNames[24] = "strong";104      expectedNames[25] = "code";105      expectedNames[26] = "sup";106      expectedNames[27] = "var";107      expectedNames[28] = "acronym";108      expectedNames[29] = "p";109      expectedNames[30] = "em";110      expectedNames[31] = "strong";111      expectedNames[32] = "code";112      expectedNames[33] = "sup";113      expectedNames[34] = "var";114      expectedNames[35] = "acronym";115      expectedNames[36] = "p";116      expectedNames[37] = "em";117      expectedNames[38] = "strong";118      expectedNames[39] = "code";119      expectedNames[40] = "sup";120      expectedNames[41] = "var";121      expectedNames[42] = "acronym";122      svgExpectedNames = new Array();123      svgExpectedNames[0] = "svg";124      svgExpectedNames[1] = "rect";125      svgExpectedNames[2] = "script";126      svgExpectedNames[3] = "head";127      svgExpectedNames[4] = "meta";128      svgExpectedNames[5] = "title";129      svgExpectedNames[6] = "body";130      svgExpectedNames[7] = "p";131      svgExpectedNames[8] = "em";132      svgExpectedNames[9] = "strong";133      svgExpectedNames[10] = "code";134      svgExpectedNames[11] = "sup";135      svgExpectedNames[12] = "var";136      svgExpectedNames[13] = "acronym";137      svgExpectedNames[14] = "p";138      svgExpectedNames[15] = "em";139      svgExpectedNames[16] = "strong";140      svgExpectedNames[17] = "code";141      svgExpectedNames[18] = "sup";142      svgExpectedNames[19] = "var";143      svgExpectedNames[20] = "acronym";144      svgExpectedNames[21] = "p";145      svgExpectedNames[22] = "em";146      svgExpectedNames[23] = "strong";147      svgExpectedNames[24] = "code";148      svgExpectedNames[25] = "sup";149      svgExpectedNames[26] = "var";150      svgExpectedNames[27] = "acronym";151      svgExpectedNames[28] = "p";152      svgExpectedNames[29] = "em";153      svgExpectedNames[30] = "strong";154      svgExpectedNames[31] = "code";155      svgExpectedNames[32] = "sup";156      svgExpectedNames[33] = "var";157      svgExpectedNames[34] = "acronym";158      svgExpectedNames[35] = "p";159      svgExpectedNames[36] = "em";160      svgExpectedNames[37] = "strong";161      svgExpectedNames[38] = "code";162      svgExpectedNames[39] = "sup";163      svgExpectedNames[40] = "var";164      svgExpectedNames[41] = "acronym";165      var actualNames = new Array();166      var thisElement;167      var thisTag;168      169      var docRef = null;170      if (typeof(this.doc) != 'undefined') {171        docRef = this.doc;172      }173      doc = load(docRef, "doc", "hc_staff");174      nameList = doc.getElementsByTagName("*");175      for(var indexN10148 = 0;indexN10148 < nameList.length; indexN10148++) {176      thisElement = nameList.item(indexN10148);177      thisTag = thisElement.tagName;178      actualNames[actualNames.length] = thisTag;179	}180   181	if(182	183	(builder.contentType == "image/svg+xml")184	) {185	assertEqualsListAutoCase("element", "svgTagNames",svgExpectedNames,actualNames);186       187	}188	189		else {190			assertEqualsListAutoCase("element", "tagNames",expectedNames,actualNames);191       192		}193	194}195function runTest() {196   hc_documentgetelementsbytagnametotallength();...assert.js
Source:assert.js  
1function Assert( testContext ) {2	this.test = testContext;3}4// Assert helpers5QUnit.assert = Assert.prototype = {6	// Specify the number of expected assertions to guarantee that failed test7	// (no assertions are run at all) don't slip through.8	expect: function( asserts ) {9		if ( arguments.length === 1 ) {10			this.test.expected = asserts;11		} else {12			return this.test.expected;13		}14	},15	// Increment this Test's semaphore counter, then return a single-use function that16	// decrements that counter a maximum of once.17	async: function() {18		var test = this.test,19			popped = false;20		test.semaphore += 1;21		test.usedAsync = true;22		pauseProcessing();23		return function done() {24			if ( !popped ) {25				test.semaphore -= 1;26				popped = true;27				resumeProcessing();28			} else {29				test.pushFailure( "Called the callback returned from `assert.async` more than once",30					sourceFromStacktrace( 2 ) );31			}32		};33	},34	// Exports test.push() to the user API35	push: function( /* result, actual, expected, message */ ) {36		var assert = this,37			currentTest = ( assert instanceof Assert && assert.test ) || QUnit.config.current;38		// Backwards compatibility fix.39		// Allows the direct use of global exported assertions and QUnit.assert.*40		// Although, it's use is not recommended as it can leak assertions41		// to other tests from async tests, because we only get a reference to the current test,42		// not exactly the test where assertion were intended to be called.43		if ( !currentTest ) {44			throw new Error( "assertion outside test context, in " + sourceFromStacktrace( 2 ) );45		}46		if ( currentTest.usedAsync === true && currentTest.semaphore === 0 ) {47			currentTest.pushFailure( "Assertion after the final `assert.async` was resolved",48				sourceFromStacktrace( 2 ) );49			// Allow this assertion to continue running anyway...50		}51		if ( !( assert instanceof Assert ) ) {52			assert = currentTest.assert;53		}54		return assert.test.push.apply( assert.test, arguments );55	},56	/**57	 * Asserts rough true-ish result.58	 * @name ok59	 * @function60	 * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );61	 */62	ok: function( result, message ) {63		message = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " +64			QUnit.dump.parse( result ) );65		this.push( !!result, result, true, message );66	},67	/**68	 * Assert that the first two arguments are equal, with an optional message.69	 * Prints out both actual and expected values.70	 * @name equal71	 * @function72	 * @example equal( format( "{0} bytes.", 2), "2 bytes.", "replaces {0} with next argument" );73	 */74	equal: function( actual, expected, message ) {75		/*jshint eqeqeq:false */76		this.push( expected == actual, actual, expected, message );77	},78	/**79	 * @name notEqual80	 * @function81	 */82	notEqual: function( actual, expected, message ) {83		/*jshint eqeqeq:false */84		this.push( expected != actual, actual, expected, message );85	},86	/**87	 * @name propEqual88	 * @function89	 */90	propEqual: function( actual, expected, message ) {91		actual = objectValues( actual );92		expected = objectValues( expected );93		this.push( QUnit.equiv( actual, expected ), actual, expected, message );94	},95	/**96	 * @name notPropEqual97	 * @function98	 */99	notPropEqual: function( actual, expected, message ) {100		actual = objectValues( actual );101		expected = objectValues( expected );102		this.push( !QUnit.equiv( actual, expected ), actual, expected, message );103	},104	/**105	 * @name deepEqual106	 * @function107	 */108	deepEqual: function( actual, expected, message ) {109		this.push( QUnit.equiv( actual, expected ), actual, expected, message );110	},111	/**112	 * @name notDeepEqual113	 * @function114	 */115	notDeepEqual: function( actual, expected, message ) {116		this.push( !QUnit.equiv( actual, expected ), actual, expected, message );117	},118	/**119	 * @name strictEqual120	 * @function121	 */122	strictEqual: function( actual, expected, message ) {123		this.push( expected === actual, actual, expected, message );124	},125	/**126	 * @name notStrictEqual127	 * @function128	 */129	notStrictEqual: function( actual, expected, message ) {130		this.push( expected !== actual, actual, expected, message );131	},132	"throws": function( block, expected, message ) {133		var actual, expectedType,134			expectedOutput = expected,135			ok = false;136		// 'expected' is optional unless doing string comparison137		if ( message == null && typeof expected === "string" ) {138			message = expected;139			expected = null;140		}141		this.test.ignoreGlobalErrors = true;142		try {143			block.call( this.test.testEnvironment );144		} catch (e) {145			actual = e;146		}147		this.test.ignoreGlobalErrors = false;148		if ( actual ) {149			expectedType = QUnit.objectType( expected );150			// we don't want to validate thrown error151			if ( !expected ) {152				ok = true;153				expectedOutput = null;154			// expected is a regexp155			} else if ( expectedType === "regexp" ) {156				ok = expected.test( errorString( actual ) );157			// expected is a string158			} else if ( expectedType === "string" ) {159				ok = expected === errorString( actual );160			// expected is a constructor, maybe an Error constructor161			} else if ( expectedType === "function" && actual instanceof expected ) {162				ok = true;163			// expected is an Error object164			} else if ( expectedType === "object" ) {165				ok = actual instanceof expected.constructor &&166					actual.name === expected.name &&167					actual.message === expected.message;168			// expected is a validation function which returns true if validation passed169			} else if ( expectedType === "function" && expected.call( {}, actual ) === true ) {170				expectedOutput = null;171				ok = true;172			}173			this.push( ok, actual, expectedOutput, message );174		} else {175			this.test.pushFailure( message, null, "No exception was thrown." );176		}177	}178};179// Provide an alternative to assert.throws(), for enviroments that consider throws a reserved word180// Known to us are: Closure Compiler, Narwhal181(function() {182	/*jshint sub:true */183	Assert.prototype.raises = Assert.prototype[ "throws" ];...Using AI Code Generation
1const chai = require('chai');2const expect = chai.expect;3const assert = chai.assert;4const should = chai.should();5const mocha = require('mocha');6const describe = mocha.describe;7const it = mocha.it;8const myObject = require('./myObject');9describe('myObject', function() {10  it('should return an object', function() {11    expect(myObject).to.be.an('object');12  });13  it('should have a property called name', function() {14    expect(myObject).to.have.property('name');15  });16  it('should have a property called age', function() {17    expect(myObject).to.have.property('age');18  });19  it('should have a property called city', function() {20    expect(myObject).to.have.property('city');21  });22  it('should have a property called state', function() {23    expect(myObject).to.have.property('state');24  });25  it('should have a property called country', function() {26    expect(myObject).to.have.property('country');27  });28  it('should have a property called hobbies', function() {29    expect(myObject).to.have.property('hobbies');30  });31  it('should have a property called favoriteFood', function() {32    expect(myObject).to.have.property('favoriteFood');33  });34  it('should have a property called favoriteMovie', function() {35    expect(myObject).to.have.property('favoriteMovie');36  });37  it('should have a property called favoriteSport', function() {38    expect(myObject).to.have.property('favoriteSport');39  });40  it('should have a property called favoriteGame', function() {41    expect(myObject).to.have.property('favoriteGame');42  });43  it('should have a property called favoriteShow', function() {44    expect(myObject).to.have.property('favoriteShow');45  });46  it('should have a property called favoriteBand', function() {47    expect(myObject).to.have.property('favoriteBand');48  });49  it('should have a property called favoriteArtist', function() {50    expect(myObject).to.have.property('favoriteArtist');51  });52  it('should have a property called favoriteSong', function() {53    expect(myObject).to.have.property('favoriteSong');54  });55  it('should have a property called favoriteQuote', function() {56    expect(myObject).to.haveUsing AI Code Generation
1const chai = require('chai');2const expect = chai.expect;3const should = chai.should();4const assert = chai.assert;5const add = require('../app.js');6describe('Addition Test', function(){7    it('should add two numbers', function(){8        expect(add(2,2)).to.equal(4);9        expect(add(2,2)).to.not.equal(5);10        assert.equal(add(2,2), 4);11        assert.notEqual(add(2,2), 5);12        add(2,2).should.equal(4);13        add(2,2).should.not.equal(5);14    });15});Using AI Code Generation
1const chai = require('chai');2const assert = chai.assert;3const expect = chai.expect;4const should = chai.should();5const chaiHttp = require('chai-http');6chai.use(chaiHttp);7const server = require('../server');8describe('GET /api/convert', function(){9  it('test case 1: Convert 10L (valid input)', function(done){10    chai.request(server)11      .get('/api/convert')12      .query({input: '10L'})13      .end(function(err, res){14        assert.equal(res.status, 200);15        assert.equal(res.body.initNum, 10);16        assert.equal(res.body.initUnit, 'L');17        assert.equal(res.body.returnNum, 2.64172);18        assert.equal(res.body.returnUnit, 'gal');19        assert.equal(res.body.string, '10 liters converts to 2.64172 gallons');20        done();21      })22  })23  it('test case 2: Convert 32g (invalid input unit)', function(done){24    chai.request(server)25      .get('/api/convert')26      .query({input: '32g'})27      .end(function(err, res){28        assert.equal(res.status, 200);29        assert.equal(res.body.initNum, 'invalid number');30        assert.equal(res.body.initUnit, 'invalid unit');31        assert.equal(res.body.returnNum, undefined);32        assert.equal(res.body.returnUnit, undefined);33        assert.equal(res.body.string, 'invalid number and unit');34        done();35      })36  })37  it('test case 3: Convert 3/7.2/4kg (invalid number)', function(done){38    chai.request(server)39      .get('/api/convert')40      .query({input: '3/7.2/4kg'})41      .end(function(err, res){42        assert.equal(res.status, 200);43        assert.equal(res.body.initNum, 'invalid number');44        assert.equal(res.body.initUnit, 'kg');45        assert.equal(res.body.returnNum, undefined);46        assert.equal(res.body.returnUnit, undefined);47        assert.equal(res.body.string, 'invalid number');48        done();49      })50  })Using AI Code Generation
1const chai = require('chai');2const expect = chai.expect;3const should = chai.should();4const assert = chai.assert;5const chaiHttp = require('chai-http');6const app = require('../app');7const User = require('../models/user');8const Cart = require('../models/cart');9const Product = require('../models/product');10chai.use(chaiHttp);11describe('Cart', function() {12  beforeEach(function(done) {13    let user = new User({Using AI Code Generation
1const expect = require('chai').expect;2const should = require('chai').should();3const assert = require('chai').assert;4const mocha = require('mocha');5const app = require('../app');6describe('App', function(){7    it('app should return hello', function(){8        let result = app();9        assert.equal(result, 'hello');10    });11    it('app should return type string', function(){12        let result = app();13        assert.typeOf(result, 'string');14    });15    it('app should return hello', function(){16        let result = app();17        expect(result).to.equal('hello');18    });19    it('app should return type string', function(){20        let result = app();21        expect(result).to.be.a('string');22    });23    it('app should return hello', function(){24        let result = app();25        result.should.equal('hello');26    });27    it('app should return type string', function(){28        let result = app();29        result.should.be.a('string');30    });31});Using AI Code Generation
1const chai = require('chai');2const expect = chai.expect;3const assert = chai.assert;4const should = chai.should();5const chaiHttp = require('chai-http');6const app = require('../server');7const User = require('../models/user');8const mongoose = require('mongoose');9const dbURI = require('../config/db');10const bcrypt = require('bcryptjs');11const jwt = require('jsonwebtoken');12chai.use(chaiHttp);13describe('Test User Routes', () => {14  beforeEach((done) => {15    mongoose.connect(dbURI, { useNewUrlParser: true });16    const db = mongoose.connection;17    db.dropDatabase();18    done();19  });20  afterEach((done) => {21    mongoose.connection.close();22    done();23  });24  describe('POST /users', () => {25    it('should create a new user', (done) => {26      let user = {Using AI Code Generation
1const chai = require('chai');2const expect = chai.expect;3const assert = chai.assert;4const should = chai.should();5const assert = require('chai').assert;6const expect = require('chai').expect;Using AI Code Generation
1var expect = require('chai').expect;2var add = require('./add.js');3describe("Add function", function() {4    it("should add two positive numbers", function() {5        expect(add(1, 2)).to.equal(3);6    });7    it("should add a positive and a negative number", function() {8        expect(add(-1, 2)).to.equal(1);9    });10    it("should add two negative numbers", function() {11        expect(add(-1, -2)).to.equal(-3);12    });13    it("should add two numbers that are strings", function() {14        expect(add("1", "2")).to.equal(3);15    });16    it("should add two numbers that are strings and numbers", function() {17        expect(add("1", 2)).to.equal(3);18    });19    it("should add two numbers that are strings and negative numbers", function() {20        expect(add("-1", "-2")).to.equal(-3);21    });22    it("should add two numbers that are strings and negative numbers", function() {23        expect(add("-1", 2)).to.equal(1);24    });25    it("should add two numbers that are strings and negative numbers", function() {26        expect(add("1", -2)).to.equal(-1);27    });28    it("should add two numbers that are strings and negative numbers", function() {29        expect(add("-1", 2)).to.equal(1);30    });31    it("should add two numbers that are strings and negative numbers", function() {32        expect(add("1", -2)).to.equal(-1);33    });34    it("should add two numbers that are strings and negative numbers", function() {35        expect(add("-1", "2")).to.equal(1);36    });37    it("should add two numbers that are strings and negative numbers", function() {38        expect(add("1", "-2")).to.equal(-1);39    });40    it("should add two numbers that are strings and negative numbers", function() {41        expect(add("-1", "2")).to.equal(1);42    });43    it("should add two numbers that are strings and negative numbers", function() {44        expect(add("1", "-2")).to.equal(-1);45    });46    it("should add two numbers that are strings and negative numbers", function() {Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
