From 82d1cc53fcaf2cbf536b917c8ffd8e645c5e093a Mon Sep 17 00:00:00 2001 From: konstantinabl Date: Fri, 3 Nov 2023 11:38:19 +0200 Subject: [PATCH] Adds tests for control structures (#463) * Adds tests for control structures Signed-off-by: Konstantina Blazhukova * Fixes small nits Signed-off-by: Konstantina Blazhukova * Sets loop limit Signed-off-by: Konstantina Blazhukova * Resolves conflict in constants Signed-off-by: Konstantina Blazhukova * Fixes comments Signed-off-by: Konstantina Blazhukova --------- Signed-off-by: Konstantina Blazhukova --- .../solidity/control/ControlStructures.sol | 89 +++++++++++++++++++ test/constants.js | 4 + test/solidity/control/control.js | 77 ++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 contracts/solidity/control/ControlStructures.sol create mode 100644 test/solidity/control/control.js diff --git a/contracts/solidity/control/ControlStructures.sol b/contracts/solidity/control/ControlStructures.sol new file mode 100644 index 000000000..ab15e3fe8 --- /dev/null +++ b/contracts/solidity/control/ControlStructures.sol @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.20; + +contract TestTryCatchContract { + function myFunc(uint x) public pure returns (string memory) { + require(x != 0, "require failed"); + return "my func was called"; + } +} + + +contract ControlStructures { + TestTryCatchContract private testContract; + + constructor() { + testContract = new TestTryCatchContract(); + } + + function testIfElse(bool condition) external pure returns(bool) { + if(condition) { + return true; + } else { + return false; + } + } + + function testWhile(uint256 total) external pure returns(uint256) { + require(total < 100, "Cannot have more than 100 iterations"); + uint256 it = 0; + while(++it < total) {} + + return it; + } + + function testDoWhile(uint256 total) external pure returns(uint256) { + require(total < 100, "Cannot have more than 100 iterations"); + uint256 it = 0; + do { + it++; + } while(it < total); + + return it; + } + + function testBreak(uint256 total, uint256 interception) external pure returns(uint256) { + require(total < 100, "Cannot have more than 100 iterations"); + uint256 it = 0; + while(it++ < total) { + if(it == interception) break; + } + + return it; + } + + function testContinue(uint256 total, uint256 interception) external pure returns(uint256) { + require(total < 100, "Cannot have more than 100 iterations"); + uint256 iterableSteps = 0; + + for(uint i=0; i < total; i++) { + if(interception < i) continue; + iterableSteps++; + } + + return iterableSteps; + } + + function testFor(uint256 total) external pure returns(uint256) { + require(total < 100, "Cannot have more than 100 iterations"); + uint256 it = 0; + for(uint i=0; i < total; i++) { + it = i; + } + + return it; + } + + function myFunc(uint x) internal pure returns (string memory) { + require(x != 0, "require failed"); + return "my func was called"; + } + + function testTryCatch(uint256 condition) external view returns(bool) { + try testContract.myFunc(condition) { + return true; + } catch { + return false; + } + } +} diff --git a/test/constants.js b/test/constants.js index 7719ec7aa..c395e0a32 100644 --- a/test/constants.js +++ b/test/constants.js @@ -117,6 +117,10 @@ const Contract = { Defaults: "Defaults", NonExisting: "NonExisting", NonExtDup: "NonExtDup", + AddressContract: 'AddressContract', + Recipient: 'Recipient', + Inheritance: 'Inheritance', + ControlStructures: 'ControlStructures' } const CALL_EXCEPTION = 'CALL_EXCEPTION' diff --git a/test/solidity/control/control.js b/test/solidity/control/control.js new file mode 100644 index 000000000..a1c341823 --- /dev/null +++ b/test/solidity/control/control.js @@ -0,0 +1,77 @@ +/*- + * + * Hedera Smart Contracts + * + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +const { expect } = require('chai') +const { ethers } = require('hardhat') +const Constants = require('../../constants') + +describe('Control Structures', function () { + let contract; + + before(async function () { + const factory = await ethers.getContractFactory(Constants.Contract.ControlStructures) + contract = await factory.deploy() + }) + + it('should verify is is working correctly', async function () { + const res = await contract.testIfElse(false) + expect(res).to.equal(false) + }) + + it('should verify else is working correctly', async function () { + const res = await contract.testIfElse(true) + expect(res).to.equal(true) + }) + + it('should verify while is working correctly', async function () { + const res = await contract.testWhile(5) + expect(res).to.equal(5) + }) + + it('should verify do is working correctly', async function () { + const res = await contract.testDoWhile(5) + expect(res).to.equal(5) + }) + + it('should verify break is working correctly', async function () { + const res = await contract.testBreak(5, 3) + expect(res).to.equal(3) + }) + + it('should verify continue is working correctly', async function () { + const res = await contract.testContinue(5, 3) + expect(res).to.equal(4) + }) + + it('should verify for is working correctly', async function () { + const res = await contract.testFor(5) + expect(res).to.equal(4) + }) + + it('should verify catch is working correctly', async function () { + const res = await contract.testTryCatch(0) + expect(res).to.equal(false) + }) + + it('should verify try is working correctly', async function () { + const res = await contract.testTryCatch(1) + expect(res).to.equal(true) + }) +})