text: var test = require('tape')
  var remixLib = require('remix-lib')
  
  var StatRunner = require('../../src/solidity-analyzer')
  var compilerInput = remixLib.helpers.compiler.compilerInput
  
  const niv = require('npm-install-version')
  niv.install('solc@0.5.0')
  var compiler = niv.require('solc@0.5.0')
  
  var fs = require('fs')
  var path = require('path')
  var folder = 'solidity-v0.5'
  
  var testFiles = [
    'KingOfTheEtherThrone.sol',
    'assembly.sol',
    'ballot.sol',
    'ballot_reentrant.sol',
    'ballot_withoutWarnings.sol',
    'cross_contract.sol',
    'inheritance.sol',
    'modifier1.sol',
    'modifier2.sol',
    'notReentrant.sol',
    'structReentrant.sol',
    'thisLocal.sol',
    'globals.sol',
    'library.sol',
    'transfer.sol',
    'ctor.sol',
    'forgottenReturn.sol',
    'selfdestruct.sol',
    'deleteDynamicArray.sol',
    'deleteFromDynamicArray.sol',
    'blockLevelCompare.sol',
    'intDivisionTruncate.sol',
    'ERC20.sol',
    'stringBytesLength.sol',
    'forLoopIteratesOverDynamicArray.sol'
  ]
  
  var testFileAsts = {}
  
  testFiles.forEach((fileName) => {
    var content = fs.readFileSync(path.join(__dirname, 'test-contracts/' + folder, fileName), 'utf8')
    testFileAsts[fileName] = JSON.parse(compiler.compile(compilerInput(content)))
  })
  
  test('Integration test thisLocal.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/thisLocal')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 1,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 1,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of this local warnings`)
    })
  })
  
  test('Integration test checksEffectsInteraction.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/checksEffectsInteraction')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 1,
      'assembly.sol': 1,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 1,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 1,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 1,
      'thisLocal.sol': 0,
      'globals.sol': 1,
      'library.sol': 1,
      'transfer.sol': 1,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of checks-effects-interaction warnings`)
    })
  })
  
  test('Integration test constantFunctions.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/constantFunctions')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 1,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 1,
      'thisLocal.sol': 1,
      'globals.sol': 0,
      'library.sol': 3,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of constant warnings`)
    })
  })
  
  test('Integration test inlineAssembly.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/inlineAssembly')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 2,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of inline assembly warnings`)
    })
  })
  
  test('Integration test txOrigin.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/txOrigin')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 1,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 1,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of tx.origin warnings`)
    })
  })
  
  test('Integration test gasCosts.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/gasCosts')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 2,
      'assembly.sol': 2,
      'ballot.sol': 3,
      'ballot_reentrant.sol': 2,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 1,
      'inheritance.sol': 1,
      'modifier1.sol': 0,
      'modifier2.sol': 1,
      'notReentrant.sol': 1,
      'structReentrant.sol': 1,
      'thisLocal.sol': 1,
      'globals.sol': 1,
      'library.sol': 1,
      'transfer.sol': 1,
      'ctor.sol': 0,
      'forgottenReturn.sol': 3,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 2,
      'deleteFromDynamicArray.sol': 1,
      'blockLevelCompare.sol': 1,
      'intDivisionTruncate.sol': 1,
      'ERC20.sol': 2,
      'stringBytesLength.sol': 1,
      'forLoopIteratesOverDynamicArray.sol': 1
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of gasCost warnings`)
    })
  })
  
  test('Integration test similarVariableNames.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/similarVariableNames')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 2,
      'ballot_reentrant.sol': 11,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 1,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 1,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 1,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of similarVariableNames warnings`)
    })
  })
  
  test('Integration test inlineAssembly.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/inlineAssembly')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 2,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of inlineAssembly warnings`)
    })
  })
  
  test('Integration test blockTimestamp.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/blockTimestamp')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 1,
      'assembly.sol': 0,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 3,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 2,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of blockTimestamp warnings`)
    })
  })
  
  test('Integration test lowLevelCalls.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/lowLevelCalls')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 1,
      'assembly.sol': 1,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 7,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 1,
      'inheritance.sol': 1,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 1,
      'structReentrant.sol': 1,
      'thisLocal.sol': 2,
      'globals.sol': 1,
      'library.sol': 1,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of lowLevelCalls warnings`)
    })
  })
  
  test('Integration test blockBlockhash.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/blockBlockhash')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 0, // was 1 !! @TODO
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of blockBlockhash warnings`)
    })
  })
  
  /*
  
  ! No return gives compilation error with solidity 0.5.0
  
  test('Integration test noReturn.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/noReturn')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 1,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 1,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 1,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 1,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of noReturn warnings`)
    })
  })
  */
  
  test('Integration test selfdestruct.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/selfdestruct')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 2,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 3,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'ERC20.sol': 0,
      'intDivisionTruncate.sol': 5,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of selfdestruct warnings`)
    })
  })
  
  test('Integration test guardConditions.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/guardConditions')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 1,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 1,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 1,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 1,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of guardCondition warnings`)
    })
  })
  
  test('Integration test deleteDynamicArrays.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/deleteDynamicArrays')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 2,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of deleteDynamicArrays warnings`)
    })
  })
  
  test('Integration test deleteFromDynamicArray.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/deleteFromDynamicArray')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 1,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of deleteFromDynamicArray warnings`)
    })
  })
  
  test('Integration test assignAndCompare.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/assignAndCompare')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 8,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of assignAndCompare warnings`)
    })
  })
  
  test('Integration test intDivisionTruncate.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/intDivisionTruncate')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 2,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of intDivisionTruncate warnings`)
    })
  })
  
  test('Integration test erc20Decimal.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/erc20Decimals')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 1,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of erc20Decimals warnings`)
    })
  })
  
  test('Integration test stringBytesLength.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/stringBytesLength')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 0,
      'ballot_reentrant.sol': 0,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 1,
      'forLoopIteratesOverDynamicArray.sol': 0
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of stringBytesLength warnings`)
    })
  })
  
  test('Integration test forLoopIteratesOverDynamicArray.js', function (t) {
    t.plan(testFiles.length)
  
    var module = require('../../src/solidity-analyzer/modules/forLoopIteratesOverDynamicArray')
  
    var lengthCheck = {
      'KingOfTheEtherThrone.sol': 0,
      'assembly.sol': 0,
      'ballot.sol': 2,
      'ballot_reentrant.sol': 1,
      'ballot_withoutWarnings.sol': 0,
      'cross_contract.sol': 0,
      'inheritance.sol': 0,
      'modifier1.sol': 0,
      'modifier2.sol': 0,
      'notReentrant.sol': 0,
      'structReentrant.sol': 0,
      'thisLocal.sol': 0,
      'globals.sol': 0,
      'library.sol': 0,
      'transfer.sol': 0,
      'ctor.sol': 0,
      'forgottenReturn.sol': 0,
      'selfdestruct.sol': 0,
      'deleteDynamicArray.sol': 0,
      'deleteFromDynamicArray.sol': 0,
      'blockLevelCompare.sol': 0,
      'intDivisionTruncate.sol': 0,
      'ERC20.sol': 0,
      'stringBytesLength.sol': 0,
      'forLoopIteratesOverDynamicArray.sol': 1
    }
  
    runModuleOnFiles(module, t, (file, report) => {
      t.equal(report.length, lengthCheck[file], `${file} has right amount of forLoopIteratesOverDynamicArray warnings`)
    })
  })
  
  // #################### Helpers
  function runModuleOnFiles (module, t, cb) {
    var statRunner = new StatRunner()
  
    testFiles.forEach((fileName) => {
      statRunner.runWithModuleList(testFileAsts[fileName], [{ name: module.name, mod: new module.Module() }], (reports) => {
        let report = reports[0].report
        if (report.some((x) => x['warning'].includes('INTERNAL ERROR'))) {
          t.comment('Error while executing Module: ' + JSON.stringify(report))
        }
        cb(fileName, report)
      })
    })
  }
  