156 lines
6.9 KiB
TypeScript
156 lines
6.9 KiB
TypeScript
import { blockchainTests, constants, expect, hexSlice } from '@0x/contracts-test-utils';
|
|
import { BigNumber } from '@0x/utils';
|
|
import { BlockParam, CallData } from 'ethereum-types';
|
|
import * as ethUtil from 'ethereumjs-util';
|
|
|
|
import { artifacts, TestFrameworkContract } from '../../src';
|
|
import { GetterCache } from '../utils/cache';
|
|
|
|
blockchainTests.resets('Cache Tests', env => {
|
|
let exampleContract: TestFrameworkContract;
|
|
|
|
before(async () => {
|
|
exampleContract = await TestFrameworkContract.deployFrom0xArtifactAsync(
|
|
artifacts.TestFramework,
|
|
env.provider,
|
|
env.txDefaults,
|
|
artifacts,
|
|
);
|
|
});
|
|
|
|
describe('callAsync', () => {
|
|
describe('() => uint', () => {
|
|
let cache: GetterCache;
|
|
|
|
beforeEach(async () => {
|
|
cache = new GetterCache(exampleContract.numberSideEffect);
|
|
});
|
|
|
|
it('should return 0 when "counter" == 0', async () => {
|
|
expect(await cache.callAsync()).bignumber.to.be.eq(constants.ZERO_AMOUNT);
|
|
});
|
|
|
|
it('should return 1 when "counter" == 1', async () => {
|
|
// Update the counter to 1.
|
|
await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1));
|
|
|
|
// Ensure that the returned value is the updated counter.
|
|
expect(await cache.callAsync()).bignumber.to.be.eq(new BigNumber(1));
|
|
});
|
|
|
|
it('should return the cached counter', async () => {
|
|
// Cache a value.
|
|
expect(await cache.callAsync()).bignumber.to.be.eq(constants.ZERO_AMOUNT);
|
|
|
|
// Update the counter to 1.
|
|
await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1));
|
|
|
|
// This should return "0" because a value was cached by the first call to "callAsync"
|
|
expect(await cache.callAsync()).bignumber.to.be.eq(constants.ZERO_AMOUNT);
|
|
});
|
|
});
|
|
|
|
describe('uint => boolean', () => {
|
|
let cache: GetterCache;
|
|
|
|
beforeEach(async () => {
|
|
cache = new GetterCache(exampleContract.equalsSideEffect);
|
|
});
|
|
|
|
it('should return true when "possiblyZero" == 0 && "counter" == 0', async () => {
|
|
expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.true();
|
|
});
|
|
|
|
it('should return false when "possiblyZero" == 0 && "counter" != 0', async () => {
|
|
// Update "counter" to "1", which will cause all calls to return false.
|
|
await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1));
|
|
expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.false();
|
|
});
|
|
|
|
it('should return the cached value', async () => {
|
|
// Cache a "true" value when "possiblyZero" == 0 && "counter" == 0
|
|
expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.true();
|
|
|
|
// Update "counter" to "1", which will cause all calls of "isZeroOrFalse" to return "false".
|
|
await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1));
|
|
|
|
// This should return "true" because a value was by the first call to "callAsync"
|
|
expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.true();
|
|
});
|
|
});
|
|
|
|
describe('(uint, bytes32) => bytes32', () => {
|
|
let cache: GetterCache;
|
|
|
|
beforeEach(async () => {
|
|
cache = new GetterCache(exampleContract.hashSideEffect);
|
|
});
|
|
|
|
it('should return correct hash when counter == 0', async () => {
|
|
// Get the calldata for the function call, which includes the abi-encoded data to hash.
|
|
const hashData = exampleContract.hashSideEffect.getABIEncodedTransactionData(
|
|
new BigNumber(1),
|
|
ethUtil.bufferToHex(ethUtil.sha3(0)),
|
|
);
|
|
|
|
// Ensure that the correct hash was returned from the cache.
|
|
expect(await cache.callAsync(new BigNumber(1), ethUtil.bufferToHex(ethUtil.sha3(0)))).to.be.eq(
|
|
ethUtil.bufferToHex(ethUtil.sha3(hexSlice(hashData, 4))),
|
|
);
|
|
});
|
|
|
|
it('should return the null hash when counter != 0', async () => {
|
|
// Update "counter" to "1", which will cause all calls to return the null hash.
|
|
await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1));
|
|
|
|
// Ensure that the cache returns the correct value.
|
|
expect(await cache.callAsync(new BigNumber(1), ethUtil.bufferToHex(ethUtil.sha3(0)))).to.be.eq(
|
|
ethUtil.bufferToHex(ethUtil.sha3('0x')),
|
|
);
|
|
});
|
|
|
|
it('should return the cached hash', async () => {
|
|
// Get the calldata for the function call, which includes the abi-encoded data to hash.
|
|
const hashData = exampleContract.hashSideEffect.getABIEncodedTransactionData(
|
|
new BigNumber(1),
|
|
ethUtil.bufferToHex(ethUtil.sha3(0)),
|
|
);
|
|
const hash = ethUtil.bufferToHex(ethUtil.sha3(hexSlice(hashData, 4)));
|
|
|
|
// Ensure that the cache returns the correct value.
|
|
expect(await cache.callAsync(new BigNumber(1), ethUtil.bufferToHex(ethUtil.sha3(0)))).to.be.eq(hash);
|
|
|
|
// Update "counter" to "1", which will cause all calls to return the null hash.
|
|
await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1));
|
|
|
|
// The cache should return the same value as the first call to `callAsync` since a value was cached.
|
|
expect(await cache.callAsync(new BigNumber(1), ethUtil.bufferToHex(ethUtil.sha3(0)))).to.be.eq(hash);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('flush', () => {
|
|
describe('uint => boolean', () => {
|
|
let cache: GetterCache;
|
|
|
|
beforeEach(async () => {
|
|
cache = new GetterCache(exampleContract.equalsSideEffect);
|
|
});
|
|
|
|
it('should return false when the cache was flushed && "possiblyZero" == 0 && "counter" != 0', async () => {
|
|
// Cache a "true" value when "possiblyZero" == 0 && "counter" == 0
|
|
expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.true();
|
|
|
|
// Update "counter" to "1", which will cause all calls of "isZeroOrFalse" to return "false".
|
|
await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1));
|
|
|
|
// Flush the entire cache.
|
|
cache.flush();
|
|
|
|
// This should return "false" because the value was flushed.
|
|
expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.false();
|
|
});
|
|
});
|
|
});
|
|
});
|