From 63ac6c1e15594f874103658b9cbef82c60ae1cf1 Mon Sep 17 00:00:00 2001 From: Joe Scharf Date: Sun, 20 Feb 2022 09:29:39 -0700 Subject: [PATCH] Improvements to hh tests - added fixture, split contract_addres --- packages/hardhat-ts/test/challenge-1.ts | 156 ------------------ packages/hardhat-ts/test/challenge_1.ts | 134 +++++++++++++++ .../test/challenge_1_contract_address.ts | 29 ++++ 3 files changed, 163 insertions(+), 156 deletions(-) delete mode 100644 packages/hardhat-ts/test/challenge-1.ts create mode 100644 packages/hardhat-ts/test/challenge_1.ts create mode 100644 packages/hardhat-ts/test/challenge_1_contract_address.ts diff --git a/packages/hardhat-ts/test/challenge-1.ts b/packages/hardhat-ts/test/challenge-1.ts deleted file mode 100644 index 86ea73b..0000000 --- a/packages/hardhat-ts/test/challenge-1.ts +++ /dev/null @@ -1,156 +0,0 @@ -// -// this script executes when you run 'yarn test' -// -// you can also test remote submissions like: -// CONTRACT_ADDRESS=0x43Ab1FCd430C1f20270C2470f857f7a006117bbb yarn test --network rinkeby -// -// you can even run mint commands if the tests pass like: -// yarn test && echo "PASSED" || echo "FAILED" -// -import { ethers, network } from 'hardhat'; -import { use, expect } from 'chai'; -import { solidity } from "ethereum-waffle"; -import { Contract } from 'ethers'; - -use(solidity); - -describe("🚩 Challenge 1: 🥩 Decentralized Staking App", function () { - - this.timeout(120000); - - let exampleExternalContract: Contract; - let stakerContract: Contract; - //console.log("hre:",Object.keys(hre)) // <-- you can access the hardhat runtime env here - - describe("Staker", function () { - - if(process.env.CONTRACT_ADDRESS){ - it("Should connect to external contract", async function () { - stakerContract = await ethers.getContractAt("Staker",process.env.CONTRACT_ADDRESS!); - console.log(" 🛰 Connected to external contract",stakerContract.address) - }); - }else{ - it("Should deploy ExampleExternalContract", async function () { - const ExampleExternalContract = await ethers.getContractFactory("ExampleExternalContract"); - exampleExternalContract = await ExampleExternalContract.deploy(); - }); - it("Should deploy Staker", async function () { - const Staker = await ethers.getContractFactory("Staker"); - stakerContract = await Staker.deploy(exampleExternalContract.address); - }); - } - - describe("mintItem()", function () { - it("Balance should go up when you stake()", async function () { - const [ owner ] = await ethers.getSigners(); - - console.log('\t'," 🧑‍🏫 Tester Address: ",owner.address) - - const startingBalance = await stakerContract.balances(owner.address) - console.log('\t'," ⚖️ Starting balance: ",startingBalance.toNumber()) - - console.log('\t'," 🔨 Staking...") - const stakeResult = await stakerContract.stake({value: ethers.utils.parseEther("0.001")}); - console.log('\t'," 🏷 stakeResult: ",stakeResult.hash) - - console.log('\t'," ⏳ Waiting for confirmation...") - const txResult = await stakeResult.wait() - expect(txResult.status).to.equal(1); - - const newBalance = await stakerContract.balances(owner.address) - console.log('\t'," 🔎 New balance: ", ethers.utils.formatEther(newBalance)) - expect(newBalance).to.equal(startingBalance.add(ethers.utils.parseEther("0.001"))); - - }); - - - if(process.env.CONTRACT_ADDRESS){ - console.log(" 🤷 since we will run this test on a live contract this is as far as the automated tests will go...") - }else{ - - it("If enough is staked and time has passed, you should be able to complete", async function () { - - const timeLeft1 = await stakerContract.timeLeft() - console.log('\t',"⏱ There should be some time left: ",timeLeft1.toNumber()) - expect(timeLeft1.toNumber()).to.greaterThan(0); - - - console.log('\t'," 🚀 Staking a full eth!") - const stakeResult = await stakerContract.stake({value: ethers.utils.parseEther("1")}); - console.log('\t'," 🏷 stakeResult: ",stakeResult.hash) - - console.log('\t'," ⌛️ fast forward time...") - await network.provider.send("evm_increaseTime", [3600]) - await network.provider.send("evm_mine") - - const timeLeft2 = await stakerContract.timeLeft() - console.log('\t',"⏱ Time should be up now: ",timeLeft2.toNumber()) - expect(timeLeft2.toNumber()).to.equal(0); - - console.log('\t'," 🎉 calling execute") - const execResult = await stakerContract.execute(); - console.log('\t'," 🏷 execResult: ",execResult.hash) - - const result = await exampleExternalContract.completed() - console.log('\t'," 🥁 complete: ",result) - expect(result).to.equal(true); - - }) - - - - it("Should redeploy Staker, stake, not get enough, and withdraw", async function () { - const [ owner, secondAccount ] = await ethers.getSigners(); - - const ExampleExternalContract = await ethers.getContractFactory("ExampleExternalContract"); - exampleExternalContract = await ExampleExternalContract.deploy(); - - const Staker = await ethers.getContractFactory("Staker"); - stakerContract = await Staker.deploy(exampleExternalContract.address); - - console.log('\t'," 🔨 Staking...") - const stakeResult = await stakerContract.stake({value: ethers.utils.parseEther("0.001")}); - console.log('\t'," 🏷 stakeResult: ",stakeResult.hash) - - console.log('\t'," ⏳ Waiting for confirmation...") - const txResult = await stakeResult.wait() - expect(txResult.status).to.equal(1); - - console.log('\t'," ⌛️ fast forward time...") - await network.provider.send("evm_increaseTime", [3600]) - await network.provider.send("evm_mine") - - console.log('\t'," 🎉 calling execute") - const execResult = await stakerContract.execute(); - console.log('\t'," 🏷 execResult: ",execResult.hash) - - const result = await exampleExternalContract.completed() - console.log('\t'," 🥁 complete should be false: ",result) - expect(result).to.equal(false); - - - const startingBalance = await ethers.provider.getBalance(secondAccount.address); - console.log("startingBalance before withdraw", ethers.utils.formatEther(startingBalance)) - - console.log('\t'," 💵 calling withdraw") - const withdrawResult = await stakerContract.withdraw(secondAccount.address); - console.log('\t'," 🏷 withdrawResult: ",withdrawResult.hash) - - const endingBalance = await ethers.provider.getBalance(secondAccount.address); - console.log("endingBalance after withdraw", ethers.utils.formatEther(endingBalance)) - - expect(endingBalance).to.equal(startingBalance.add(ethers.utils.parseEther("0.001"))); - - }); - } - // - - /*it("Should track tokens of owner by index", async function () { - const [ owner ] = await ethers.getSigners(); - const startingBalance = await myContract.balanceOf(owner.address) - const token = await myContract.tokenOfOwnerByIndex(owner.address,startingBalance.sub(1)); - expect(token.toNumber()).to.greaterThan(0); - });*/ - }); - }); -}); \ No newline at end of file diff --git a/packages/hardhat-ts/test/challenge_1.ts b/packages/hardhat-ts/test/challenge_1.ts new file mode 100644 index 0000000..21875f9 --- /dev/null +++ b/packages/hardhat-ts/test/challenge_1.ts @@ -0,0 +1,134 @@ +// +// this script executes when you run 'yarn test' +// and is used to execute local contract tests +// +// you can even run mint commands if the tests pass like: +// yarn test && echo "PASSED" || echo "FAILED" +// +import { expect } from 'chai'; +import { ethers, deployments, network } from 'hardhat'; + +const CONTRACTS = { + staker: 'Staker', + exampleExternalContract: 'ExampleExternalContract', +}; +const contractAddress = process.env.CONTRACT_ADDRESS || ''; + +// Setup the test fixture +const setupTest = deployments.createFixture(async ({ deployments, getNamedAccounts, ethers }, options) => { + await deployments.fixture([CONTRACTS.staker, CONTRACTS.exampleExternalContract]); // ensure you start from a fresh deployments + const { deployer } = await getNamedAccounts(); + const stakerContract = await ethers.getContract(CONTRACTS.staker); + const exampleExternalContract = await ethers.getContract(CONTRACTS.exampleExternalContract); + return { + fixture: { + deployer, + stakerContract, + exampleExternalContract, + }, + }; +}); + +describe('🚩 Challenge 1: 🥩 Decentralized Staking App - Local Tests', function () { + if (contractAddress) { + console.log('CONTRACT_ADDRESS is set, skipping local tests'); + return; + } + describe('Staker', function () { + describe('mintItem()', function () { + it('Balance should go up when you stake()', async function () { + const { fixture } = await setupTest(); + + const [owner] = await ethers.getSigners(); + + console.log('\t', ' 🧑‍🏫 Tester Address: ', owner.address); + + const startingBalance = await fixture.stakerContract.balances(owner.address); + console.log('\t', ' ⚖️ Starting balance: ', startingBalance.toNumber()); + + console.log('\t', ' 🔨 Staking...'); + const stakeResult = await fixture.stakerContract.stake({ value: ethers.utils.parseEther('0.001') }); + console.log('\t', ' 🏷 stakeResult: ', stakeResult.hash); + + console.log('\t', ' ⏳ Waiting for confirmation...'); + const txResult = await stakeResult.wait(); + expect(txResult.status).to.equal(1); + + const newBalance = await fixture.stakerContract.balances(owner.address); + console.log('\t', ' 🔎 New balance: ', ethers.utils.formatEther(newBalance)); + expect(newBalance).to.equal(startingBalance.add(ethers.utils.parseEther('0.001'))); + }); + + it('If enough is staked and time has passed, you should be able to complete', async function () { + const { fixture } = await setupTest(); + + const timeLeft1 = await fixture.stakerContract.timeLeft(); + console.log('\t', '⏱ There should be some time left: ', timeLeft1.toNumber()); + expect(timeLeft1.toNumber()).to.greaterThan(0); + + console.log('\t', ' 🚀 Staking a full eth!'); + const stakeResult = await fixture.stakerContract.stake({ value: ethers.utils.parseEther('1') }); + console.log('\t', ' 🏷 stakeResult: ', stakeResult.hash); + + console.log('\t', ' ⌛️ fast forward time...'); + await network.provider.send('evm_increaseTime', [3600]); + await network.provider.send('evm_mine'); + + const timeLeft2 = await fixture.stakerContract.timeLeft(); + console.log('\t', '⏱ Time should be up now: ', timeLeft2.toNumber()); + expect(timeLeft2.toNumber()).to.equal(0); + + console.log('\t', ' 🎉 calling execute'); + const execResult = await fixture.stakerContract.execute(); + console.log('\t', ' 🏷 execResult: ', execResult.hash); + + const result = await fixture.exampleExternalContract.completed(); + console.log('\t', ' 🥁 complete: ', result); + expect(result).to.equal(true); + }); + + it('Should redeploy Staker, stake, not get enough, and withdraw', async function () { + const { fixture } = await setupTest(); + const [owner, secondAccount] = await ethers.getSigners(); + + console.log('\t', ' 🔨 Staking...'); + const stakeResult = await fixture.stakerContract.stake({ value: ethers.utils.parseEther('0.001') }); + console.log('\t', ' 🏷 stakeResult: ', stakeResult.hash); + + console.log('\t', ' ⏳ Waiting for confirmation...'); + const txResult = await stakeResult.wait(); + expect(txResult.status).to.equal(1); + + console.log('\t', ' ⌛️ fast forward time...'); + await network.provider.send('evm_increaseTime', [3600]); + await network.provider.send('evm_mine'); + + console.log('\t', ' 🎉 calling execute'); + const execResult = await fixture.stakerContract.execute(); + console.log('\t', ' 🏷 execResult: ', execResult.hash); + + const result = await fixture.exampleExternalContract.completed(); + console.log('\t', ' 🥁 complete should be false: ', result); + expect(result).to.equal(false); + + const startingBalance = await ethers.provider.getBalance(owner.address); + console.log('startingBalance before withdraw', ethers.utils.formatEther(startingBalance)); + + console.log('\t', ' 💵 calling withdraw'); + const withdrawResult = await fixture.stakerContract.withdraw(owner.address); + console.log('\t', ' 🏷 withdrawResult: ', withdrawResult.hash); + + const endingBalance = await ethers.provider.getBalance(owner.address); + console.log('endingBalance after withdraw', ethers.utils.formatEther(endingBalance)); + + // Truncating the starting and ending balances so we don't have to deal with gas issues + const startRemainder = startingBalance.mod(1e15); + const startRounded = startingBalance.sub(startRemainder); + const endRemainder = endingBalance.mod(1e15); + const endRounded = endingBalance.sub(endRemainder); + + expect(endRounded).to.equal(startRounded.add(ethers.utils.parseEther('0.001'))); + }); + }); + }); +}); diff --git a/packages/hardhat-ts/test/challenge_1_contract_address.ts b/packages/hardhat-ts/test/challenge_1_contract_address.ts new file mode 100644 index 0000000..7d46367 --- /dev/null +++ b/packages/hardhat-ts/test/challenge_1_contract_address.ts @@ -0,0 +1,29 @@ +// +// this script executes when you run 'yarn test' +// and is used to test contracts at an external address like so: +// +// CONTRACT_ADDRESS=0x43Ab1FCd430C1f20270C2470f857f7a006117bbb yarn test --network rinkeby +// +// you can even run mint commands if the tests pass like: +// yarn test && echo "PASSED" || echo "FAILED" +// +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { Contract } from 'ethers'; + +const contractAddress = process.env.CONTRACT_ADDRESS || ''; +let stakerContract: Contract; + +describe('🚩 Challenge 1: 🥩 Decentralized Staking App - External tests', function () { + if (!contractAddress) { + console.log('CONTRACT_ADDRESS is not set, skipping external tests'); + return; + } + describe('Staker', function () { + it('Should connect to external contract', async function () { + stakerContract = await ethers.getContractAt('Staker', contractAddress); + console.log(' 🛰 Connected to external contract', stakerContract.address); + expect(stakerContract).to.not.be.undefined; + }); + }); +});