From 4358ad5c2c989424ae5df154733bc3d941cf9e8b Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Wed, 20 Mar 2019 10:16:40 +0100 Subject: [PATCH] Allow owner to remove nodes --- contracts/Nodes.sol | 29 ++++++++++++++++++++++++++--- package.json | 4 +++- test/TestNodes.js | 30 ++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/contracts/Nodes.sol b/contracts/Nodes.sol index 8c2cd48..f10e62f 100644 --- a/contracts/Nodes.sol +++ b/contracts/Nodes.sol @@ -4,7 +4,7 @@ contract Nodes { address owner; string[] public nodes; - uint public nodeCount; + mapping(string => uint) nodeIndex; modifier onlyOwner() { require(msg.sender == owner); @@ -17,12 +17,29 @@ contract Nodes owner = msg.sender; } + function nodeCount() + view + public + returns + (uint) + { + return nodes.length; + } + function addNode(string memory _node) public onlyOwner { + nodeIndex[_node] = nodes.length; nodes.push(_node); - nodeCount++; + } + + function deleteNode(string memory _node) + public + onlyOwner + { + uint index = nodeIndex[_node]; + _deleteNode(index); } function deleteAll() @@ -30,7 +47,13 @@ contract Nodes onlyOwner { delete nodes; - nodeCount = 0; + } + + function _deleteNode(uint index) internal { + require(index < nodes.length); + nodes[index] = nodes[nodes.length-1]; + delete nodes[nodes.length-1]; + nodes.length--; } function () external payable { diff --git a/package.json b/package.json index 29d559b..88bc6c6 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,9 @@ "scripts": { "test": "truffle test", "lint": "eslint . --ext .js", - "lint-watch": "nodemon --exec 'npm run lint'", + "lint-watch": "nodemon --exec 'npm run lint' -e js,sol", + "test-watch": "nodemon --exec 'npm test' -e js,sol", + "watch": "nodemon --exec 'npm test && npm run lint' -e js,sol", "validate": "npm test && npm run lint" }, "author": "", diff --git a/test/TestNodes.js b/test/TestNodes.js index 934d570..45cf129 100644 --- a/test/TestNodes.js +++ b/test/TestNodes.js @@ -45,6 +45,36 @@ contract('Nodes', async (accounts) => { }); }); + describe('deleteNode', async () => { + describe('called by the owner', async () => { + beforeEach(async () => { + await instance.addNode(node1); + await instance.addNode(node2); + await instance.deleteNode(node1); + }); + + it('removes the first node', async () => { + const actualNode2 = await instance.nodes(0); + assert.equal(actualNode2, node2); + }); + + it('sets the count', async () => { + const actualNodeCount = await instance.nodeCount(); + assert.equal(1, actualNodeCount); + }); + }); + describe('called by someone else', async () => { + it('throws an exception', async () => { + try { + await instance.deleteNode(node1, { from: accounts[1] }); + } catch (error) { + return; + } + assert.fail('it should throw an exception'); + }); + }); + }); + describe('deleteAll', async () => { beforeEach(async () => { await instance.addNode(node1);