/ block.test.js
block.test.js
  1  const hextToBinary = require("hex-to-binary");
  2  const Block = require("./block");
  3  const config = require("./config");
  4  const cryptoHash = require("./crypto-hash");
  5  
  6  describe("Block", () => {
  7    const timestamp = 2000;
  8    const lastHash = "lastHash";
  9    const hash = "hash";
 10    const data = ["blockchain", "data"];
 11    const nonce = 1;
 12    const difficulty = 1;
 13    const block = new Block({
 14      timestamp,
 15      lastHash,
 16      hash,
 17      data,
 18      nonce,
 19      difficulty,
 20    });
 21    it("has a  timestamp, lastHash, hash, data property", () => {
 22      expect(block.timestamp).toEqual(timestamp);
 23      expect(block.lastHash).toEqual(lastHash);
 24      expect(block.hash).toEqual(hash);
 25      expect(block.data).toEqual(data);
 26      expect(block.nonce).toEqual(nonce);
 27      expect(block.difficulty).toEqual(difficulty);
 28    });
 29  
 30    describe("genesis block", () => {
 31      const genesisBlock = Block.genesis();
 32  
 33      it("returns a Block instance", () => {
 34        expect(genesisBlock instanceof Block).toBe(true);
 35      });
 36  
 37      it("returns the genesis data", () => {
 38        expect(genesisBlock).toEqual(config.GENESIS_DATA);
 39      });
 40    });
 41  
 42    describe("mineBlock", () => {
 43      const lastBlock = Block.genesis();
 44      const data = "mined block";
 45      const minedBlock = Block.mineBlock({ lastBlock, data });
 46  
 47      it("returns a Block instance", () => {
 48        expect(minedBlock instanceof Block).toBe(true);
 49      });
 50  
 51      it("sets the,`lastHash` to be the `hash` of the lastBlock", () => {
 52        expect(minedBlock.lastHash).toEqual(lastBlock.hash);
 53      });
 54  
 55      it("sets the `data`", () => {
 56        expect(minedBlock.data).toEqual(data);
 57      });
 58  
 59      it("sets the `timestamp`", () => {
 60        expect(minedBlock.timestamp).not.toEqual(undefined);
 61      });
 62  
 63      it("creates a SHA-256 `hash` based on the proper inputs", () => {
 64        expect(minedBlock.hash).toEqual(
 65          cryptoHash(
 66            minedBlock.timestamp,
 67            minedBlock.nonce,
 68            minedBlock.difficulty,
 69            lastBlock.hash,
 70            data
 71          )
 72        );
 73      });
 74  
 75      it("sets a `hash` that matches the difficulty criteria", () => {
 76        expect(hextToBinary(minedBlock.hash).substring(0, minedBlock.difficulty)).toEqual(
 77          "0".repeat(minedBlock.difficulty)
 78        );
 79      });
 80  
 81      it("adjusts the difficulty", () => {
 82        const possibleResults = [
 83          lastBlock.difficulty + 1,
 84          lastBlock.difficulty - 1,
 85        ];
 86        expect(possibleResults.includes(minedBlock.difficulty)).toBe(true);
 87      });
 88  
 89      describe("adjustDifficulty()", () => {
 90        it("raises the difficulty for a quickly mined block", () => {
 91          expect(
 92            Block.adjustDifficulty({
 93              originalBlock: block,
 94              timestamp: block.timestamp + config.MINE_RATE - 100,
 95            })
 96          ).toEqual(block.difficulty + 1);
 97        });
 98        it("lowers the difficulty for a slowly mined block", () => {
 99          expect(
100            Block.adjustDifficulty({
101              originalBlock: block,
102              timestamp: block.timestamp + config.MINE_RATE + 100,
103            })
104          ).toEqual(block.difficulty - 1);
105        });
106  
107        it("has a lower limit of 1",()=> {
108          block.difficulty = -1;
109  
110          expect(Block.adjustDifficulty({originalBlock:block})).toEqual(1);
111        });
112      });
113    });
114  });