Reorganize and cleanup truffle integration tests (#400)
parent
c25697d5c6
commit
3bd99ab6dd
@ -1,99 +1,7 @@ |
|||||||
/** |
|
||||||
* Use this file to configure your truffle project. It's seeded with some |
|
||||||
* common settings for different networks and features like migrations, |
|
||||||
* compilation and testing. Uncomment the ones you need or modify |
|
||||||
* them to suit your project as necessary. |
|
||||||
* |
|
||||||
* More information about configuration can be found at: |
|
||||||
* |
|
||||||
* truffleframework.com/docs/advanced/configuration |
|
||||||
* |
|
||||||
* To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider) |
|
||||||
* to sign your transactions before they're sent to a remote public node. Infura accounts |
|
||||||
* are available for free at: infura.io/register. |
|
||||||
* |
|
||||||
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate |
|
||||||
* public/private key pairs. If you're publishing your code to GitHub make sure you load this |
|
||||||
* phrase from a file you've .gitignored so it doesn't accidentally become public. |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
// const HDWalletProvider = require('truffle-hdwallet-provider');
|
|
||||||
// const infuraKey = "fj4jll3k.....";
|
|
||||||
//
|
|
||||||
// const fs = require('fs');
|
|
||||||
// const mnemonic = fs.readFileSync(".secret").toString().trim();
|
|
||||||
|
|
||||||
module.exports = { |
module.exports = { |
||||||
/** |
networks: {}, |
||||||
* Networks define how you connect to your ethereum client and let you set the |
mocha: {}, |
||||||
* defaults web3 uses to send transactions. If you don't specify one truffle |
|
||||||
* will spin up a development blockchain for you on port 9545 when you |
|
||||||
* run `develop` or `test`. You can ask a truffle command to use a specific |
|
||||||
* network from the command line, e.g |
|
||||||
* |
|
||||||
* $ truffle test --network <network-name> |
|
||||||
*/ |
|
||||||
|
|
||||||
networks: { |
|
||||||
// Useful for testing. The `development` name is special - truffle uses it by default
|
|
||||||
// if it's defined here and no other network is specified at the command line.
|
|
||||||
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
|
|
||||||
// tab if you use this network and you must also set the `host`, `port` and `network_id`
|
|
||||||
// options below to some value.
|
|
||||||
//
|
|
||||||
// development: {
|
|
||||||
// host: "127.0.0.1", // Localhost (default: none)
|
|
||||||
// port: 8545, // Standard Ethereum port (default: none)
|
|
||||||
// network_id: "*", // Any network (default: none)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Another network with more advanced options...
|
|
||||||
// advanced: {
|
|
||||||
// port: 8777, // Custom port
|
|
||||||
// network_id: 1342, // Custom network
|
|
||||||
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
|
|
||||||
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
|
|
||||||
// from: <address>, // Account to send txs from (default: accounts[0])
|
|
||||||
// websockets: true // Enable EventEmitter interface for web3 (default: false)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for deploying to a public network.
|
|
||||||
// NB: It's important to wrap the provider as a function.
|
|
||||||
// ropsten: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
|
|
||||||
// network_id: 3, // Ropsten's id
|
|
||||||
// gas: 5500000, // Ropsten has a lower block limit than mainnet
|
|
||||||
// confirmations: 2, // # of confs to wait between deployments. (default: 0)
|
|
||||||
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
|
|
||||||
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for private networks
|
|
||||||
// private: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
|
|
||||||
// network_id: 2111, // This network is yours, in the cloud.
|
|
||||||
// production: true // Treats this network as if it was a public net. (default: false)
|
|
||||||
// }
|
|
||||||
}, |
|
||||||
|
|
||||||
// Set default mocha options here, use special reporters etc.
|
|
||||||
mocha: { |
|
||||||
// timeout: 100000
|
|
||||||
}, |
|
||||||
|
|
||||||
// Configure your compilers
|
|
||||||
compilers: { |
compilers: { |
||||||
solc: { |
solc: {} |
||||||
// version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version)
|
|
||||||
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
|
|
||||||
// settings: { // See the solidity docs for advice about optimization and evmVersion
|
|
||||||
// optimizer: {
|
|
||||||
// enabled: false,
|
|
||||||
// runs: 200
|
|
||||||
// },
|
|
||||||
// evmVersion: "byzantium"
|
|
||||||
// }
|
|
||||||
} |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,99 +1,7 @@ |
|||||||
/** |
|
||||||
* Use this file to configure your truffle project. It's seeded with some |
|
||||||
* common settings for different networks and features like migrations, |
|
||||||
* compilation and testing. Uncomment the ones you need or modify |
|
||||||
* them to suit your project as necessary. |
|
||||||
* |
|
||||||
* More information about configuration can be found at: |
|
||||||
* |
|
||||||
* truffleframework.com/docs/advanced/configuration |
|
||||||
* |
|
||||||
* To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider) |
|
||||||
* to sign your transactions before they're sent to a remote public node. Infura accounts |
|
||||||
* are available for free at: infura.io/register. |
|
||||||
* |
|
||||||
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate |
|
||||||
* public/private key pairs. If you're publishing your code to GitHub make sure you load this |
|
||||||
* phrase from a file you've .gitignored so it doesn't accidentally become public. |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
// const HDWalletProvider = require('truffle-hdwallet-provider');
|
|
||||||
// const infuraKey = "fj4jll3k.....";
|
|
||||||
//
|
|
||||||
// const fs = require('fs');
|
|
||||||
// const mnemonic = fs.readFileSync(".secret").toString().trim();
|
|
||||||
|
|
||||||
module.exports = { |
module.exports = { |
||||||
/** |
networks: {}, |
||||||
* Networks define how you connect to your ethereum client and let you set the |
mocha: {}, |
||||||
* defaults web3 uses to send transactions. If you don't specify one truffle |
|
||||||
* will spin up a development blockchain for you on port 9545 when you |
|
||||||
* run `develop` or `test`. You can ask a truffle command to use a specific |
|
||||||
* network from the command line, e.g |
|
||||||
* |
|
||||||
* $ truffle test --network <network-name> |
|
||||||
*/ |
|
||||||
|
|
||||||
networks: { |
|
||||||
// Useful for testing. The `development` name is special - truffle uses it by default
|
|
||||||
// if it's defined here and no other network is specified at the command line.
|
|
||||||
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
|
|
||||||
// tab if you use this network and you must also set the `host`, `port` and `network_id`
|
|
||||||
// options below to some value.
|
|
||||||
//
|
|
||||||
// development: {
|
|
||||||
// host: "127.0.0.1", // Localhost (default: none)
|
|
||||||
// port: 8545, // Standard Ethereum port (default: none)
|
|
||||||
// network_id: "*", // Any network (default: none)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Another network with more advanced options...
|
|
||||||
// advanced: {
|
|
||||||
// port: 8777, // Custom port
|
|
||||||
// network_id: 1342, // Custom network
|
|
||||||
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
|
|
||||||
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
|
|
||||||
// from: <address>, // Account to send txs from (default: accounts[0])
|
|
||||||
// websockets: true // Enable EventEmitter interface for web3 (default: false)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for deploying to a public network.
|
|
||||||
// NB: It's important to wrap the provider as a function.
|
|
||||||
// ropsten: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
|
|
||||||
// network_id: 3, // Ropsten's id
|
|
||||||
// gas: 5500000, // Ropsten has a lower block limit than mainnet
|
|
||||||
// confirmations: 2, // # of confs to wait between deployments. (default: 0)
|
|
||||||
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
|
|
||||||
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for private networks
|
|
||||||
// private: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
|
|
||||||
// network_id: 2111, // This network is yours, in the cloud.
|
|
||||||
// production: true // Treats this network as if it was a public net. (default: false)
|
|
||||||
// }
|
|
||||||
}, |
|
||||||
|
|
||||||
// Set default mocha options here, use special reporters etc.
|
|
||||||
mocha: { |
|
||||||
// timeout: 100000
|
|
||||||
}, |
|
||||||
|
|
||||||
// Configure your compilers
|
|
||||||
compilers: { |
compilers: { |
||||||
solc: { |
solc: {} |
||||||
// version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version)
|
|
||||||
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
|
|
||||||
// settings: { // See the solidity docs for advice about optimization and evmVersion
|
|
||||||
// optimizer: {
|
|
||||||
// enabled: false,
|
|
||||||
// runs: 200
|
|
||||||
// },
|
|
||||||
// evmVersion: "byzantium"
|
|
||||||
// }
|
|
||||||
} |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,99 +1,7 @@ |
|||||||
/** |
|
||||||
* Use this file to configure your truffle project. It's seeded with some |
|
||||||
* common settings for different networks and features like migrations, |
|
||||||
* compilation and testing. Uncomment the ones you need or modify |
|
||||||
* them to suit your project as necessary. |
|
||||||
* |
|
||||||
* More information about configuration can be found at: |
|
||||||
* |
|
||||||
* truffleframework.com/docs/advanced/configuration |
|
||||||
* |
|
||||||
* To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider) |
|
||||||
* to sign your transactions before they're sent to a remote public node. Infura accounts |
|
||||||
* are available for free at: infura.io/register. |
|
||||||
* |
|
||||||
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate |
|
||||||
* public/private key pairs. If you're publishing your code to GitHub make sure you load this |
|
||||||
* phrase from a file you've .gitignored so it doesn't accidentally become public. |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
// const HDWalletProvider = require('truffle-hdwallet-provider');
|
|
||||||
// const infuraKey = "fj4jll3k.....";
|
|
||||||
//
|
|
||||||
// const fs = require('fs');
|
|
||||||
// const mnemonic = fs.readFileSync(".secret").toString().trim();
|
|
||||||
|
|
||||||
module.exports = { |
module.exports = { |
||||||
/** |
networks: {}, |
||||||
* Networks define how you connect to your ethereum client and let you set the |
mocha: {}, |
||||||
* defaults web3 uses to send transactions. If you don't specify one truffle |
|
||||||
* will spin up a development blockchain for you on port 9545 when you |
|
||||||
* run `develop` or `test`. You can ask a truffle command to use a specific |
|
||||||
* network from the command line, e.g |
|
||||||
* |
|
||||||
* $ truffle test --network <network-name> |
|
||||||
*/ |
|
||||||
|
|
||||||
networks: { |
|
||||||
// Useful for testing. The `development` name is special - truffle uses it by default
|
|
||||||
// if it's defined here and no other network is specified at the command line.
|
|
||||||
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
|
|
||||||
// tab if you use this network and you must also set the `host`, `port` and `network_id`
|
|
||||||
// options below to some value.
|
|
||||||
//
|
|
||||||
// development: {
|
|
||||||
// host: "127.0.0.1", // Localhost (default: none)
|
|
||||||
// port: 8545, // Standard Ethereum port (default: none)
|
|
||||||
// network_id: "*", // Any network (default: none)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Another network with more advanced options...
|
|
||||||
// advanced: {
|
|
||||||
// port: 8777, // Custom port
|
|
||||||
// network_id: 1342, // Custom network
|
|
||||||
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
|
|
||||||
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
|
|
||||||
// from: <address>, // Account to send txs from (default: accounts[0])
|
|
||||||
// websockets: true // Enable EventEmitter interface for web3 (default: false)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for deploying to a public network.
|
|
||||||
// NB: It's important to wrap the provider as a function.
|
|
||||||
// ropsten: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
|
|
||||||
// network_id: 3, // Ropsten's id
|
|
||||||
// gas: 5500000, // Ropsten has a lower block limit than mainnet
|
|
||||||
// confirmations: 2, // # of confs to wait between deployments. (default: 0)
|
|
||||||
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
|
|
||||||
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for private networks
|
|
||||||
// private: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
|
|
||||||
// network_id: 2111, // This network is yours, in the cloud.
|
|
||||||
// production: true // Treats this network as if it was a public net. (default: false)
|
|
||||||
// }
|
|
||||||
}, |
|
||||||
|
|
||||||
// Set default mocha options here, use special reporters etc.
|
|
||||||
mocha: { |
|
||||||
// timeout: 100000
|
|
||||||
}, |
|
||||||
|
|
||||||
// Configure your compilers
|
|
||||||
compilers: { |
compilers: { |
||||||
solc: { |
solc: {} |
||||||
// version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version)
|
|
||||||
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
|
|
||||||
// settings: { // See the solidity docs for advice about optimization and evmVersion
|
|
||||||
// optimizer: {
|
|
||||||
// enabled: false,
|
|
||||||
// runs: 200
|
|
||||||
// },
|
|
||||||
// evmVersion: "byzantium"
|
|
||||||
// }
|
|
||||||
} |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,99 +1,7 @@ |
|||||||
/** |
|
||||||
* Use this file to configure your truffle project. It's seeded with some |
|
||||||
* common settings for different networks and features like migrations, |
|
||||||
* compilation and testing. Uncomment the ones you need or modify |
|
||||||
* them to suit your project as necessary. |
|
||||||
* |
|
||||||
* More information about configuration can be found at: |
|
||||||
* |
|
||||||
* truffleframework.com/docs/advanced/configuration |
|
||||||
* |
|
||||||
* To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider) |
|
||||||
* to sign your transactions before they're sent to a remote public node. Infura accounts |
|
||||||
* are available for free at: infura.io/register. |
|
||||||
* |
|
||||||
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate |
|
||||||
* public/private key pairs. If you're publishing your code to GitHub make sure you load this |
|
||||||
* phrase from a file you've .gitignored so it doesn't accidentally become public. |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
// const HDWalletProvider = require('truffle-hdwallet-provider');
|
|
||||||
// const infuraKey = "fj4jll3k.....";
|
|
||||||
//
|
|
||||||
// const fs = require('fs');
|
|
||||||
// const mnemonic = fs.readFileSync(".secret").toString().trim();
|
|
||||||
|
|
||||||
module.exports = { |
module.exports = { |
||||||
/** |
networks: {}, |
||||||
* Networks define how you connect to your ethereum client and let you set the |
mocha: {}, |
||||||
* defaults web3 uses to send transactions. If you don't specify one truffle |
|
||||||
* will spin up a development blockchain for you on port 9545 when you |
|
||||||
* run `develop` or `test`. You can ask a truffle command to use a specific |
|
||||||
* network from the command line, e.g |
|
||||||
* |
|
||||||
* $ truffle test --network <network-name> |
|
||||||
*/ |
|
||||||
|
|
||||||
networks: { |
|
||||||
// Useful for testing. The `development` name is special - truffle uses it by default
|
|
||||||
// if it's defined here and no other network is specified at the command line.
|
|
||||||
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
|
|
||||||
// tab if you use this network and you must also set the `host`, `port` and `network_id`
|
|
||||||
// options below to some value.
|
|
||||||
//
|
|
||||||
// development: {
|
|
||||||
// host: "127.0.0.1", // Localhost (default: none)
|
|
||||||
// port: 8545, // Standard Ethereum port (default: none)
|
|
||||||
// network_id: "*", // Any network (default: none)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Another network with more advanced options...
|
|
||||||
// advanced: {
|
|
||||||
// port: 8777, // Custom port
|
|
||||||
// network_id: 1342, // Custom network
|
|
||||||
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
|
|
||||||
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
|
|
||||||
// from: <address>, // Account to send txs from (default: accounts[0])
|
|
||||||
// websockets: true // Enable EventEmitter interface for web3 (default: false)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for deploying to a public network.
|
|
||||||
// NB: It's important to wrap the provider as a function.
|
|
||||||
// ropsten: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
|
|
||||||
// network_id: 3, // Ropsten's id
|
|
||||||
// gas: 5500000, // Ropsten has a lower block limit than mainnet
|
|
||||||
// confirmations: 2, // # of confs to wait between deployments. (default: 0)
|
|
||||||
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
|
|
||||||
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for private networks
|
|
||||||
// private: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
|
|
||||||
// network_id: 2111, // This network is yours, in the cloud.
|
|
||||||
// production: true // Treats this network as if it was a public net. (default: false)
|
|
||||||
// }
|
|
||||||
}, |
|
||||||
|
|
||||||
// Set default mocha options here, use special reporters etc.
|
|
||||||
mocha: { |
|
||||||
// timeout: 100000
|
|
||||||
}, |
|
||||||
|
|
||||||
// Configure your compilers
|
|
||||||
compilers: { |
compilers: { |
||||||
solc: { |
solc: {} |
||||||
// version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version)
|
|
||||||
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
|
|
||||||
// settings: { // See the solidity docs for advice about optimization and evmVersion
|
|
||||||
// optimizer: {
|
|
||||||
// enabled: false,
|
|
||||||
// runs: 200
|
|
||||||
// },
|
|
||||||
// evmVersion: "byzantium"
|
|
||||||
// }
|
|
||||||
} |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,99 +1,7 @@ |
|||||||
/** |
|
||||||
* Use this file to configure your truffle project. It's seeded with some |
|
||||||
* common settings for different networks and features like migrations, |
|
||||||
* compilation and testing. Uncomment the ones you need or modify |
|
||||||
* them to suit your project as necessary. |
|
||||||
* |
|
||||||
* More information about configuration can be found at: |
|
||||||
* |
|
||||||
* truffleframework.com/docs/advanced/configuration |
|
||||||
* |
|
||||||
* To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider) |
|
||||||
* to sign your transactions before they're sent to a remote public node. Infura accounts |
|
||||||
* are available for free at: infura.io/register. |
|
||||||
* |
|
||||||
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate |
|
||||||
* public/private key pairs. If you're publishing your code to GitHub make sure you load this |
|
||||||
* phrase from a file you've .gitignored so it doesn't accidentally become public. |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
// const HDWalletProvider = require('truffle-hdwallet-provider');
|
|
||||||
// const infuraKey = "fj4jll3k.....";
|
|
||||||
//
|
|
||||||
// const fs = require('fs');
|
|
||||||
// const mnemonic = fs.readFileSync(".secret").toString().trim();
|
|
||||||
|
|
||||||
module.exports = { |
module.exports = { |
||||||
/** |
networks: {}, |
||||||
* Networks define how you connect to your ethereum client and let you set the |
mocha: {}, |
||||||
* defaults web3 uses to send transactions. If you don't specify one truffle |
|
||||||
* will spin up a development blockchain for you on port 9545 when you |
|
||||||
* run `develop` or `test`. You can ask a truffle command to use a specific |
|
||||||
* network from the command line, e.g |
|
||||||
* |
|
||||||
* $ truffle test --network <network-name> |
|
||||||
*/ |
|
||||||
|
|
||||||
networks: { |
|
||||||
// Useful for testing. The `development` name is special - truffle uses it by default
|
|
||||||
// if it's defined here and no other network is specified at the command line.
|
|
||||||
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
|
|
||||||
// tab if you use this network and you must also set the `host`, `port` and `network_id`
|
|
||||||
// options below to some value.
|
|
||||||
//
|
|
||||||
// development: {
|
|
||||||
// host: "127.0.0.1", // Localhost (default: none)
|
|
||||||
// port: 8545, // Standard Ethereum port (default: none)
|
|
||||||
// network_id: "*", // Any network (default: none)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Another network with more advanced options...
|
|
||||||
// advanced: {
|
|
||||||
// port: 8777, // Custom port
|
|
||||||
// network_id: 1342, // Custom network
|
|
||||||
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
|
|
||||||
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
|
|
||||||
// from: <address>, // Account to send txs from (default: accounts[0])
|
|
||||||
// websockets: true // Enable EventEmitter interface for web3 (default: false)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for deploying to a public network.
|
|
||||||
// NB: It's important to wrap the provider as a function.
|
|
||||||
// ropsten: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
|
|
||||||
// network_id: 3, // Ropsten's id
|
|
||||||
// gas: 5500000, // Ropsten has a lower block limit than mainnet
|
|
||||||
// confirmations: 2, // # of confs to wait between deployments. (default: 0)
|
|
||||||
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
|
|
||||||
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for private networks
|
|
||||||
// private: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
|
|
||||||
// network_id: 2111, // This network is yours, in the cloud.
|
|
||||||
// production: true // Treats this network as if it was a public net. (default: false)
|
|
||||||
// }
|
|
||||||
}, |
|
||||||
|
|
||||||
// Set default mocha options here, use special reporters etc.
|
|
||||||
mocha: { |
|
||||||
// timeout: 100000
|
|
||||||
}, |
|
||||||
|
|
||||||
// Configure your compilers
|
|
||||||
compilers: { |
compilers: { |
||||||
solc: { |
solc: {} |
||||||
// version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version)
|
|
||||||
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
|
|
||||||
// settings: { // See the solidity docs for advice about optimization and evmVersion
|
|
||||||
// optimizer: {
|
|
||||||
// enabled: false,
|
|
||||||
// runs: 200
|
|
||||||
// },
|
|
||||||
// evmVersion: "byzantium"
|
|
||||||
// }
|
|
||||||
} |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,99 +1,7 @@ |
|||||||
/** |
|
||||||
* Use this file to configure your truffle project. It's seeded with some |
|
||||||
* common settings for different networks and features like migrations, |
|
||||||
* compilation and testing. Uncomment the ones you need or modify |
|
||||||
* them to suit your project as necessary. |
|
||||||
* |
|
||||||
* More information about configuration can be found at: |
|
||||||
* |
|
||||||
* truffleframework.com/docs/advanced/configuration |
|
||||||
* |
|
||||||
* To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider) |
|
||||||
* to sign your transactions before they're sent to a remote public node. Infura accounts |
|
||||||
* are available for free at: infura.io/register. |
|
||||||
* |
|
||||||
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate |
|
||||||
* public/private key pairs. If you're publishing your code to GitHub make sure you load this |
|
||||||
* phrase from a file you've .gitignored so it doesn't accidentally become public. |
|
||||||
* |
|
||||||
*/ |
|
||||||
|
|
||||||
// const HDWalletProvider = require('truffle-hdwallet-provider');
|
|
||||||
// const infuraKey = "fj4jll3k.....";
|
|
||||||
//
|
|
||||||
// const fs = require('fs');
|
|
||||||
// const mnemonic = fs.readFileSync(".secret").toString().trim();
|
|
||||||
|
|
||||||
module.exports = { |
module.exports = { |
||||||
/** |
networks: {}, |
||||||
* Networks define how you connect to your ethereum client and let you set the |
mocha: {}, |
||||||
* defaults web3 uses to send transactions. If you don't specify one truffle |
|
||||||
* will spin up a development blockchain for you on port 9545 when you |
|
||||||
* run `develop` or `test`. You can ask a truffle command to use a specific |
|
||||||
* network from the command line, e.g |
|
||||||
* |
|
||||||
* $ truffle test --network <network-name> |
|
||||||
*/ |
|
||||||
|
|
||||||
networks: { |
|
||||||
// Useful for testing. The `development` name is special - truffle uses it by default
|
|
||||||
// if it's defined here and no other network is specified at the command line.
|
|
||||||
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
|
|
||||||
// tab if you use this network and you must also set the `host`, `port` and `network_id`
|
|
||||||
// options below to some value.
|
|
||||||
//
|
|
||||||
// development: {
|
|
||||||
// host: "127.0.0.1", // Localhost (default: none)
|
|
||||||
// port: 8545, // Standard Ethereum port (default: none)
|
|
||||||
// network_id: "*", // Any network (default: none)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Another network with more advanced options...
|
|
||||||
// advanced: {
|
|
||||||
// port: 8777, // Custom port
|
|
||||||
// network_id: 1342, // Custom network
|
|
||||||
// gas: 8500000, // Gas sent with each transaction (default: ~6700000)
|
|
||||||
// gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
|
|
||||||
// from: <address>, // Account to send txs from (default: accounts[0])
|
|
||||||
// websockets: true // Enable EventEmitter interface for web3 (default: false)
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for deploying to a public network.
|
|
||||||
// NB: It's important to wrap the provider as a function.
|
|
||||||
// ropsten: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
|
|
||||||
// network_id: 3, // Ropsten's id
|
|
||||||
// gas: 5500000, // Ropsten has a lower block limit than mainnet
|
|
||||||
// confirmations: 2, // # of confs to wait between deployments. (default: 0)
|
|
||||||
// timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
|
|
||||||
// skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Useful for private networks
|
|
||||||
// private: {
|
|
||||||
// provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
|
|
||||||
// network_id: 2111, // This network is yours, in the cloud.
|
|
||||||
// production: true // Treats this network as if it was a public net. (default: false)
|
|
||||||
// }
|
|
||||||
}, |
|
||||||
|
|
||||||
// Set default mocha options here, use special reporters etc.
|
|
||||||
mocha: { |
|
||||||
// timeout: 100000
|
|
||||||
}, |
|
||||||
|
|
||||||
// Configure your compilers
|
|
||||||
compilers: { |
compilers: { |
||||||
solc: { |
solc: {} |
||||||
// version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version)
|
|
||||||
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
|
|
||||||
// settings: { // See the solidity docs for advice about optimization and evmVersion
|
|
||||||
// optimizer: {
|
|
||||||
// enabled: false,
|
|
||||||
// runs: 200
|
|
||||||
// },
|
|
||||||
// evmVersion: "byzantium"
|
|
||||||
// }
|
|
||||||
} |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,527 +0,0 @@ |
|||||||
const assert = require('assert'); |
|
||||||
const fs = require('fs'); |
|
||||||
const shell = require('shelljs'); |
|
||||||
const mock = require('../util/integration.truffle'); |
|
||||||
const plugin = require('../../dist/truffle.plugin'); |
|
||||||
const path = require('path') |
|
||||||
const util = require('util') |
|
||||||
const opts = { compact: false, depth: 5, breakLength: 80 }; |
|
||||||
|
|
||||||
// =======
|
|
||||||
// Helpers
|
|
||||||
// =======
|
|
||||||
function pathExists(path) { return shell.test('-e', path); } |
|
||||||
|
|
||||||
function pathToContract(config, file) { |
|
||||||
return path.join('contracts', file); |
|
||||||
} |
|
||||||
|
|
||||||
function assertLineCoverage(expected=[]){ |
|
||||||
let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json')); |
|
||||||
expected.forEach(item => assert(summary[item.file].lines.pct === item.pct)) |
|
||||||
} |
|
||||||
|
|
||||||
function assertCoverageMissing(expected=[]){ |
|
||||||
let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json')); |
|
||||||
expected.forEach(item => assert(summary[item.file] === undefined)) |
|
||||||
} |
|
||||||
|
|
||||||
function assertCleanInitialState(){ |
|
||||||
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
||||||
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
||||||
} |
|
||||||
|
|
||||||
function assertCoverageGenerate(truffleConfig){ |
|
||||||
const jsonPath = path.join(truffleConfig.working_directory, "coverage.json"); |
|
||||||
assert(pathExists('./coverage') === true, 'should gen coverage folder'); |
|
||||||
assert(pathExists(jsonPath) === true, 'should gen coverage.json'); |
|
||||||
} |
|
||||||
|
|
||||||
function assertCoverageNotGenerated(truffleConfig){ |
|
||||||
const jsonPath = path.join(truffleConfig.working_directory, "coverage.json"); |
|
||||||
assert(pathExists('./coverage') !== true, 'should NOT gen coverage folder'); |
|
||||||
assert(pathExists(jsonPath) !== true, 'should NOT gen coverage.json'); |
|
||||||
} |
|
||||||
|
|
||||||
function getOutput(truffleConfig){ |
|
||||||
const jsonPath = path.join(truffleConfig.working_directory, "coverage.json"); |
|
||||||
return JSON.parse(fs.readFileSync(jsonPath, 'utf8')); |
|
||||||
} |
|
||||||
|
|
||||||
// ========
|
|
||||||
// Tests
|
|
||||||
// ========
|
|
||||||
describe('app', function() { |
|
||||||
let truffleConfig; |
|
||||||
let solcoverConfig; |
|
||||||
let collector; |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
mock.clean(); |
|
||||||
|
|
||||||
mock.loggerOutput.val = ''; |
|
||||||
solcoverConfig = {}; |
|
||||||
truffleConfig = mock.getDefaultTruffleConfig(); |
|
||||||
}) |
|
||||||
|
|
||||||
afterEach(() => mock.clean()); |
|
||||||
|
|
||||||
it('simple contract: should generate coverage, cleanup & exit(0)', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
mock.install('Simple', 'simple.js', solcoverConfig); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
assertCoverageGenerate(truffleConfig); |
|
||||||
|
|
||||||
const output = getOutput(truffleConfig); |
|
||||||
const path = Object.keys(output)[0]; |
|
||||||
|
|
||||||
assert(output[path].fnMap['1'].name === 'test', 'coverage.json missing "test"'); |
|
||||||
assert(output[path].fnMap['2'].name === 'getX', 'coverage.json missing "getX"'); |
|
||||||
}); |
|
||||||
|
|
||||||
// Truffle test asserts balance is 777 ether
|
|
||||||
it('config with providerOptions', async function() { |
|
||||||
solcoverConfig.providerOptions = { default_balance_ether: 777 } |
|
||||||
|
|
||||||
mock.install('Simple', 'testrpc-options.js', solcoverConfig); |
|
||||||
await plugin(truffleConfig); |
|
||||||
}); |
|
||||||
|
|
||||||
it('large contract with many unbracketed statements (time check)', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
truffleConfig.compilers.solc.version = "0.4.24"; |
|
||||||
|
|
||||||
mock.install('Oraclize', 'oraclize.js', solcoverConfig, truffleConfig, true); |
|
||||||
await plugin(truffleConfig); |
|
||||||
}); |
|
||||||
|
|
||||||
// This project has three contract suites and uses .deployed() instances which
|
|
||||||
// depend on truffle's migratons and the inter-test evm_revert / evm_snapshot mechanism.
|
|
||||||
it('project evm_reverts repeatedly', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
mock.installFullProject('multiple-migrations'); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
const expected = [ |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractA.sol'), |
|
||||||
pct: 100 |
|
||||||
}, |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractB.sol'), |
|
||||||
pct: 100, |
|
||||||
}, |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractC.sol'), |
|
||||||
pct: 100, |
|
||||||
}, |
|
||||||
]; |
|
||||||
|
|
||||||
assertLineCoverage(expected); |
|
||||||
}); |
|
||||||
|
|
||||||
it('project skips a folder', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
mock.installFullProject('skipping'); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
const expected = [{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractA.sol'), |
|
||||||
pct: 100 |
|
||||||
}]; |
|
||||||
|
|
||||||
const missing = [{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractB.sol'), |
|
||||||
}]; |
|
||||||
|
|
||||||
assertLineCoverage(expected); |
|
||||||
assertCoverageMissing(missing); |
|
||||||
}); |
|
||||||
|
|
||||||
it('project contains no contract sources folder', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
mock.installFullProject('no-sources'); |
|
||||||
|
|
||||||
try { |
|
||||||
await plugin(truffleConfig); |
|
||||||
assert.fail() |
|
||||||
} catch(err){ |
|
||||||
assert( |
|
||||||
err.message.includes('Cannot locate expected contract sources folder'), |
|
||||||
`Should error when contract sources cannot be found: (output --> ${err.message}` |
|
||||||
); |
|
||||||
|
|
||||||
assert( |
|
||||||
err.message.includes('sc_temp/contracts'), |
|
||||||
`Error message should contain path: (output --> ${err.message}` |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
assertCoverageNotGenerated(truffleConfig); |
|
||||||
}); |
|
||||||
|
|
||||||
it('project with relative path solidity imports', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
mock.installFullProject('import-paths'); |
|
||||||
await plugin(truffleConfig); |
|
||||||
}); |
|
||||||
|
|
||||||
it('project contains native solidity tests', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
mock.install('Simple', 'TestSimple.sol', solcoverConfig); |
|
||||||
|
|
||||||
truffleConfig.logger = mock.testLogger; |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
assert( |
|
||||||
mock.loggerOutput.val.includes('native solidity tests'), |
|
||||||
`Should warn it is skipping native solidity tests (output --> ${mock.loggerOutput.val}` |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('project .solcover.js has syntax error', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
mock.installFullProject('bad-solcoverjs'); |
|
||||||
try { |
|
||||||
await plugin(truffleConfig); |
|
||||||
assert.fail() |
|
||||||
} catch(err){ |
|
||||||
assert( |
|
||||||
err.message.includes('Could not load .solcover.js config file.'), |
|
||||||
`Should notify when solcoverjs has syntax error: (output --> ${err.message}` |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
assertCoverageNotGenerated(truffleConfig); |
|
||||||
}) |
|
||||||
|
|
||||||
it('truffle run coverage --config ../.solcover.js', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
solcoverConfig = { |
|
||||||
silent: process.env.SILENT ? true : false, |
|
||||||
istanbulReporter: ['json-summary', 'text'] |
|
||||||
}; |
|
||||||
fs.writeFileSync('.solcover.js', `module.exports=${JSON.stringify(solcoverConfig)}`); |
|
||||||
|
|
||||||
// This relative path has to be ./ prefixed
|
|
||||||
// (because it's path.joined to truffle's working_directory)
|
|
||||||
truffleConfig.solcoverjs = './../.solcover.js'; |
|
||||||
|
|
||||||
mock.install('Simple', 'simple.js'); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
// The relative solcoverjs uses the json-summary reporter which
|
|
||||||
// this assertion requires
|
|
||||||
const expected = [{ |
|
||||||
file: pathToContract(truffleConfig, 'Simple.sol'), |
|
||||||
pct: 100 |
|
||||||
}]; |
|
||||||
|
|
||||||
assertLineCoverage(expected); |
|
||||||
shell.rm('.solcover.js'); |
|
||||||
}); |
|
||||||
|
|
||||||
it('truffle run coverage --help', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
truffleConfig.help = "true"; |
|
||||||
|
|
||||||
truffleConfig.logger = mock.testLogger; |
|
||||||
mock.install('Simple', 'simple.js', solcoverConfig); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
assert( |
|
||||||
mock.loggerOutput.val.includes('Usage'), |
|
||||||
`Should output help with Usage instruction (output --> ${mock.loggerOutput.val}` |
|
||||||
); |
|
||||||
}) |
|
||||||
|
|
||||||
it('truffle run coverage --version', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
truffleConfig.version = "true"; |
|
||||||
|
|
||||||
truffleConfig.logger = mock.testLogger; |
|
||||||
mock.install('Simple', 'simple.js', solcoverConfig); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
assert( |
|
||||||
mock.loggerOutput.val.includes('truffle'), |
|
||||||
`Should output truffle version (output --> ${mock.loggerOutput.val}` |
|
||||||
); |
|
||||||
|
|
||||||
assert( |
|
||||||
mock.loggerOutput.val.includes('ganache-core'), |
|
||||||
`Should output ganache-core version (output --> ${mock.loggerOutput.val}` |
|
||||||
); |
|
||||||
|
|
||||||
assert( |
|
||||||
mock.loggerOutput.val.includes('solidity-coverage'), |
|
||||||
`Should output solidity-coverage version (output --> ${mock.loggerOutput.val}` |
|
||||||
); |
|
||||||
|
|
||||||
}) |
|
||||||
|
|
||||||
it('truffle run coverage --useGlobalTruffle', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
truffleConfig.useGlobalTruffle = true; |
|
||||||
|
|
||||||
truffleConfig.logger = mock.testLogger; |
|
||||||
mock.install('Simple', 'simple.js', solcoverConfig); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
assert( |
|
||||||
mock.loggerOutput.val.includes('global node_modules'), |
|
||||||
`Should notify it's using global truffle (output --> ${mock.loggerOutput.val}` |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('truffle run coverage --usePluginTruffle', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
truffleConfig.usePluginTruffle = true; |
|
||||||
|
|
||||||
truffleConfig.logger = mock.testLogger; |
|
||||||
mock.install('Simple', 'simple.js', solcoverConfig); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
assert( |
|
||||||
mock.loggerOutput.val.includes('fallback Truffle library module'), |
|
||||||
`Should notify it's using plugin truffle lib copy (output --> ${mock.loggerOutput.val}` |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('lib module load failure', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
truffleConfig.usePluginTruffle = true; |
|
||||||
truffleConfig.forceLibFailure = true; |
|
||||||
|
|
||||||
mock.install('Simple', 'simple.js', solcoverConfig); |
|
||||||
|
|
||||||
try { |
|
||||||
await plugin(truffleConfig); |
|
||||||
assert.fail() |
|
||||||
} catch (err) { |
|
||||||
assert( |
|
||||||
err.message.includes('Unable to load plugin copy of Truffle library module'), |
|
||||||
`Should error on failed lib module load (output --> ${err.message}` |
|
||||||
); |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
it('truffle run coverage --file test/<fileName>', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
const testPath = path.join(truffleConfig.working_directory, 'test/specific_a.js'); |
|
||||||
truffleConfig.file = testPath; |
|
||||||
mock.installFullProject('test-files'); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
const expected = [ |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractA.sol'), |
|
||||||
pct: 100 |
|
||||||
}, |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractB.sol'), |
|
||||||
pct: 0, |
|
||||||
}, |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractC.sol'), |
|
||||||
pct: 0, |
|
||||||
}, |
|
||||||
]; |
|
||||||
|
|
||||||
assertLineCoverage(expected); |
|
||||||
}); |
|
||||||
|
|
||||||
it('truffle run coverage --file test/<glob*>', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
const testPath = path.join(truffleConfig.working_directory, 'test/globby*'); |
|
||||||
truffleConfig.file = testPath; |
|
||||||
mock.installFullProject('test-files'); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
const expected = [ |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractA.sol'), |
|
||||||
pct: 0, |
|
||||||
}, |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractB.sol'), |
|
||||||
pct: 100, |
|
||||||
}, |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractC.sol'), |
|
||||||
pct: 100, |
|
||||||
}, |
|
||||||
]; |
|
||||||
|
|
||||||
assertLineCoverage(expected); |
|
||||||
}); |
|
||||||
|
|
||||||
it('truffle run coverage --file test/gl{o,b}*.js', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
const testPath = path.join(truffleConfig.working_directory, 'test/gl{o,b}*.js'); |
|
||||||
truffleConfig.file = testPath; |
|
||||||
mock.installFullProject('test-files'); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
const expected = [ |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractA.sol'), |
|
||||||
pct: 0, |
|
||||||
}, |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractB.sol'), |
|
||||||
pct: 100, |
|
||||||
}, |
|
||||||
{ |
|
||||||
file: pathToContract(truffleConfig, 'ContractC.sol'), |
|
||||||
pct: 100, |
|
||||||
}, |
|
||||||
]; |
|
||||||
|
|
||||||
assertLineCoverage(expected); |
|
||||||
}); |
|
||||||
|
|
||||||
it('contract only uses ".call"', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
mock.install('OnlyCall', 'only-call.js', solcoverConfig); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
assertCoverageGenerate(truffleConfig); |
|
||||||
|
|
||||||
const output = getOutput(truffleConfig); |
|
||||||
const path = Object.keys(output)[0]; |
|
||||||
assert(output[path].fnMap['1'].name === 'addTwo', 'cov should map "addTwo"'); |
|
||||||
}); |
|
||||||
|
|
||||||
it('contract sends / transfers to instrumented fallback', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
mock.install('Wallet', 'wallet.js', solcoverConfig); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
assertCoverageGenerate(truffleConfig); |
|
||||||
|
|
||||||
const output = getOutput(truffleConfig); |
|
||||||
const path = Object.keys(output)[0]; |
|
||||||
assert(output[path].fnMap['1'].name === 'transferPayment', 'cov should map "transferPayment"'); |
|
||||||
}); |
|
||||||
|
|
||||||
it('contracts are skipped', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
solcoverConfig.skipFiles = ['Owned.sol']; |
|
||||||
|
|
||||||
mock.installDouble(['Proxy', 'Owned'], 'inheritance.js', solcoverConfig); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
assertCoverageGenerate(truffleConfig); |
|
||||||
|
|
||||||
const output = getOutput(truffleConfig); |
|
||||||
const firstKey = Object.keys(output)[0]; |
|
||||||
assert(Object.keys(output).length === 1, 'Wrong # of contracts covered'); |
|
||||||
assert(firstKey.substr(firstKey.length - 9) === 'Proxy.sol', 'Wrong contract covered'); |
|
||||||
}); |
|
||||||
|
|
||||||
it('contract uses inheritance', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
mock.installDouble(['Proxy', 'Owned'], 'inheritance.js', solcoverConfig); |
|
||||||
await plugin(truffleConfig); |
|
||||||
|
|
||||||
assertCoverageGenerate(truffleConfig); |
|
||||||
|
|
||||||
const output = getOutput(truffleConfig); |
|
||||||
const ownedPath = Object.keys(output)[0]; |
|
||||||
const proxyPath = Object.keys(output)[1]; |
|
||||||
assert(output[ownedPath].fnMap['1'].name === 'constructor', '"constructor" not covered'); |
|
||||||
assert(output[proxyPath].fnMap['1'].name === 'isOwner', '"isOwner" not covered'); |
|
||||||
}); |
|
||||||
|
|
||||||
// Simple.sol with a failing assertion in a truffle test
|
|
||||||
it('truffle tests failing', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
mock.install('Simple', 'truffle-test-fail.js', solcoverConfig); |
|
||||||
|
|
||||||
try { |
|
||||||
await plugin(truffleConfig); |
|
||||||
assert.fail() |
|
||||||
} catch(err){ |
|
||||||
assert(err.message.includes('failed under coverage')); |
|
||||||
} |
|
||||||
|
|
||||||
assertCoverageGenerate(truffleConfig); |
|
||||||
|
|
||||||
const output = getOutput(truffleConfig); |
|
||||||
const path = Object.keys(output)[0]; |
|
||||||
|
|
||||||
assert(output[path].fnMap['1'].name === 'test', 'cov missing "test"'); |
|
||||||
assert(output[path].fnMap['2'].name === 'getX', 'cov missing "getX"'); |
|
||||||
}); |
|
||||||
|
|
||||||
// Truffle test asserts deployment cost is greater than 20,000,000 gas
|
|
||||||
it('deployment cost > block gasLimit', async function() { |
|
||||||
mock.install('Expensive', 'block-gas-limit.js', solcoverConfig); |
|
||||||
await plugin(truffleConfig); |
|
||||||
}); |
|
||||||
|
|
||||||
// Truffle test contains syntax error
|
|
||||||
it('truffle crashes', async function() { |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
mock.install('Simple', 'truffle-crash.js', solcoverConfig); |
|
||||||
try { |
|
||||||
await plugin(truffleConfig); |
|
||||||
assert.fail() |
|
||||||
} catch(err){ |
|
||||||
assert(err.toString().includes('SyntaxError')); |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
// Solidity syntax errors
|
|
||||||
it('compilation failure', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
mock.install('SimpleError', 'simple.js', solcoverConfig); |
|
||||||
|
|
||||||
try { |
|
||||||
await plugin(truffleConfig); |
|
||||||
assert.fail() |
|
||||||
} catch(err){ |
|
||||||
assert(err.toString().includes('Compilation failed')); |
|
||||||
} |
|
||||||
|
|
||||||
assertCoverageNotGenerated(truffleConfig); |
|
||||||
}); |
|
||||||
|
|
||||||
it('instrumentation failure', async function(){ |
|
||||||
assertCleanInitialState(); |
|
||||||
|
|
||||||
mock.install('Unparseable', 'simple.js', solcoverConfig); |
|
||||||
|
|
||||||
try { |
|
||||||
await plugin(truffleConfig); |
|
||||||
assert.fail() |
|
||||||
} catch(err){ |
|
||||||
assert( |
|
||||||
err.toString().includes('/Unparseable.sol.'), |
|
||||||
`Should throw instrumentation errors with file name (output --> ${err.toString()}` |
|
||||||
); |
|
||||||
|
|
||||||
assert(err.stack !== undefined, 'Should have error trace') |
|
||||||
} |
|
||||||
|
|
||||||
assertCoverageNotGenerated(truffleConfig); |
|
||||||
}) |
|
||||||
|
|
||||||
}); |
|
@ -0,0 +1,151 @@ |
|||||||
|
const assert = require('assert'); |
||||||
|
const fs = require('fs'); |
||||||
|
const path = require('path') |
||||||
|
const shell = require('shelljs'); |
||||||
|
|
||||||
|
const verify = require('../../util/verifiers') |
||||||
|
const mock = require('../../util/integration.truffle'); |
||||||
|
const plugin = require('../../../dist/truffle.plugin'); |
||||||
|
|
||||||
|
describe('Truffle Plugin: error cases', function() { |
||||||
|
let truffleConfig; |
||||||
|
let solcoverConfig; |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
mock.clean(); |
||||||
|
|
||||||
|
mock.loggerOutput.val = ''; |
||||||
|
solcoverConfig = {}; |
||||||
|
truffleConfig = mock.getDefaultTruffleConfig(); |
||||||
|
}) |
||||||
|
|
||||||
|
afterEach(() => mock.clean()); |
||||||
|
|
||||||
|
it('project contains no contract sources folder', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
mock.installFullProject('no-sources'); |
||||||
|
|
||||||
|
try { |
||||||
|
await plugin(truffleConfig); |
||||||
|
assert.fail() |
||||||
|
} catch(err){ |
||||||
|
assert( |
||||||
|
err.message.includes('Cannot locate expected contract sources folder'), |
||||||
|
`Should error when contract sources cannot be found: (output --> ${err.message}` |
||||||
|
); |
||||||
|
|
||||||
|
assert( |
||||||
|
err.message.includes('sc_temp/contracts'), |
||||||
|
`Error message should contain path: (output --> ${err.message}` |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
verify.coverageNotGenerated(truffleConfig); |
||||||
|
}); |
||||||
|
|
||||||
|
it('project .solcover.js has syntax error', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
mock.installFullProject('bad-solcoverjs'); |
||||||
|
try { |
||||||
|
await plugin(truffleConfig); |
||||||
|
assert.fail() |
||||||
|
} catch(err){ |
||||||
|
assert( |
||||||
|
err.message.includes('Could not load .solcover.js config file.'), |
||||||
|
`Should notify when solcoverjs has syntax error: (output --> ${err.message}` |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
verify.coverageNotGenerated(truffleConfig); |
||||||
|
}) |
||||||
|
|
||||||
|
it('lib module load failure', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
truffleConfig.usePluginTruffle = true; |
||||||
|
truffleConfig.forceLibFailure = true; |
||||||
|
|
||||||
|
mock.install('Simple', 'simple.js', solcoverConfig); |
||||||
|
|
||||||
|
try { |
||||||
|
await plugin(truffleConfig); |
||||||
|
assert.fail() |
||||||
|
} catch (err) { |
||||||
|
assert( |
||||||
|
err.message.includes('Unable to load plugin copy of Truffle library module'), |
||||||
|
`Should error on failed lib module load (output --> ${err.message}` |
||||||
|
); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// Simple.sol with a failing assertion in a truffle test
|
||||||
|
it('truffle tests failing', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
mock.install('Simple', 'truffle-test-fail.js', solcoverConfig); |
||||||
|
|
||||||
|
try { |
||||||
|
await plugin(truffleConfig); |
||||||
|
assert.fail() |
||||||
|
} catch(err){ |
||||||
|
assert(err.message.includes('failed under coverage')); |
||||||
|
} |
||||||
|
|
||||||
|
verify.coverageGenerated(truffleConfig); |
||||||
|
|
||||||
|
const output = mock.getOutput(truffleConfig); |
||||||
|
const path = Object.keys(output)[0]; |
||||||
|
|
||||||
|
assert(output[path].fnMap['1'].name === 'test', 'cov missing "test"'); |
||||||
|
assert(output[path].fnMap['2'].name === 'getX', 'cov missing "getX"'); |
||||||
|
}); |
||||||
|
|
||||||
|
// Truffle test contains syntax error
|
||||||
|
it('truffle crashes', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
mock.install('Simple', 'truffle-crash.js', solcoverConfig); |
||||||
|
try { |
||||||
|
await plugin(truffleConfig); |
||||||
|
assert.fail() |
||||||
|
} catch(err){ |
||||||
|
assert(err.toString().includes('SyntaxError')); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// Solidity syntax errors
|
||||||
|
it('compilation failure', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
mock.install('SimpleError', 'simple.js', solcoverConfig); |
||||||
|
|
||||||
|
try { |
||||||
|
await plugin(truffleConfig); |
||||||
|
assert.fail() |
||||||
|
} catch(err){ |
||||||
|
assert(err.toString().includes('Compilation failed')); |
||||||
|
} |
||||||
|
|
||||||
|
verify.coverageNotGenerated(truffleConfig); |
||||||
|
}); |
||||||
|
|
||||||
|
it('instrumentation failure', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
mock.install('Unparseable', 'simple.js', solcoverConfig); |
||||||
|
|
||||||
|
try { |
||||||
|
await plugin(truffleConfig); |
||||||
|
assert.fail() |
||||||
|
} catch(err){ |
||||||
|
assert( |
||||||
|
err.toString().includes('/Unparseable.sol.'), |
||||||
|
`Should throw instrumentation errors with file name (output --> ${err.toString()}` |
||||||
|
); |
||||||
|
|
||||||
|
assert(err.stack !== undefined, 'Should have error trace') |
||||||
|
} |
||||||
|
|
||||||
|
verify.coverageNotGenerated(truffleConfig); |
||||||
|
}) |
||||||
|
}) |
@ -0,0 +1,200 @@ |
|||||||
|
const assert = require('assert'); |
||||||
|
const fs = require('fs'); |
||||||
|
const path = require('path') |
||||||
|
const shell = require('shelljs'); |
||||||
|
|
||||||
|
const verify = require('../../util/verifiers') |
||||||
|
const mock = require('../../util/integration.truffle'); |
||||||
|
const plugin = require('../../../dist/truffle.plugin'); |
||||||
|
|
||||||
|
// =======================
|
||||||
|
// Standard Use-case Tests
|
||||||
|
// =======================
|
||||||
|
|
||||||
|
describe('Truffle Plugin: command line options', function() { |
||||||
|
let truffleConfig; |
||||||
|
let solcoverConfig; |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
mock.clean(); |
||||||
|
|
||||||
|
mock.loggerOutput.val = ''; |
||||||
|
solcoverConfig = {}; |
||||||
|
truffleConfig = mock.getDefaultTruffleConfig(); |
||||||
|
}) |
||||||
|
|
||||||
|
afterEach(() => mock.clean()); |
||||||
|
|
||||||
|
it('truffle run coverage --file test/<fileName>', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
const testPath = path.join(truffleConfig.working_directory, 'test/specific_a.js'); |
||||||
|
truffleConfig.file = testPath; |
||||||
|
mock.installFullProject('test-files'); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
const expected = [ |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractA.sol'), |
||||||
|
pct: 100 |
||||||
|
}, |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractB.sol'), |
||||||
|
pct: 0, |
||||||
|
}, |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractC.sol'), |
||||||
|
pct: 0, |
||||||
|
}, |
||||||
|
]; |
||||||
|
|
||||||
|
verify.lineCoverage(expected); |
||||||
|
}); |
||||||
|
|
||||||
|
it('truffle run coverage --file test/<glob*>', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
const testPath = path.join(truffleConfig.working_directory, 'test/globby*'); |
||||||
|
truffleConfig.file = testPath; |
||||||
|
mock.installFullProject('test-files'); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
const expected = [ |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractA.sol'), |
||||||
|
pct: 0, |
||||||
|
}, |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractB.sol'), |
||||||
|
pct: 100, |
||||||
|
}, |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractC.sol'), |
||||||
|
pct: 100, |
||||||
|
}, |
||||||
|
]; |
||||||
|
|
||||||
|
verify.lineCoverage(expected); |
||||||
|
}); |
||||||
|
|
||||||
|
it('truffle run coverage --file test/gl{o,b}*.js', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
const testPath = path.join(truffleConfig.working_directory, 'test/gl{o,b}*.js'); |
||||||
|
truffleConfig.file = testPath; |
||||||
|
mock.installFullProject('test-files'); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
const expected = [ |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractA.sol'), |
||||||
|
pct: 0, |
||||||
|
}, |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractB.sol'), |
||||||
|
pct: 100, |
||||||
|
}, |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractC.sol'), |
||||||
|
pct: 100, |
||||||
|
}, |
||||||
|
]; |
||||||
|
|
||||||
|
verify.lineCoverage(expected); |
||||||
|
}); |
||||||
|
|
||||||
|
it('truffle run coverage --config ../.solcover.js', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
solcoverConfig = { |
||||||
|
silent: process.env.SILENT ? true : false, |
||||||
|
istanbulReporter: ['json-summary', 'text'] |
||||||
|
}; |
||||||
|
fs.writeFileSync('.solcover.js', `module.exports=${JSON.stringify(solcoverConfig)}`); |
||||||
|
|
||||||
|
// This relative path has to be ./ prefixed
|
||||||
|
// (because it's path.joined to truffle's working_directory)
|
||||||
|
truffleConfig.solcoverjs = './../.solcover.js'; |
||||||
|
|
||||||
|
mock.install('Simple', 'simple.js'); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
// The relative solcoverjs uses the json-summary reporter which
|
||||||
|
// this assertion requires
|
||||||
|
const expected = [{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'Simple.sol'), |
||||||
|
pct: 100 |
||||||
|
}]; |
||||||
|
|
||||||
|
verify.lineCoverage(expected); |
||||||
|
shell.rm('.solcover.js'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('truffle run coverage --help', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
truffleConfig.help = "true"; |
||||||
|
|
||||||
|
truffleConfig.logger = mock.testLogger; |
||||||
|
mock.install('Simple', 'simple.js', solcoverConfig); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
assert( |
||||||
|
mock.loggerOutput.val.includes('Usage'), |
||||||
|
`Should output help with Usage instruction (output --> ${mock.loggerOutput.val}` |
||||||
|
); |
||||||
|
}) |
||||||
|
|
||||||
|
it('truffle run coverage --version', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
truffleConfig.version = "true"; |
||||||
|
|
||||||
|
truffleConfig.logger = mock.testLogger; |
||||||
|
mock.install('Simple', 'simple.js', solcoverConfig); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
assert( |
||||||
|
mock.loggerOutput.val.includes('truffle'), |
||||||
|
`Should output truffle version (output --> ${mock.loggerOutput.val}` |
||||||
|
); |
||||||
|
|
||||||
|
assert( |
||||||
|
mock.loggerOutput.val.includes('ganache-core'), |
||||||
|
`Should output ganache-core version (output --> ${mock.loggerOutput.val}` |
||||||
|
); |
||||||
|
|
||||||
|
assert( |
||||||
|
mock.loggerOutput.val.includes('solidity-coverage'), |
||||||
|
`Should output solidity-coverage version (output --> ${mock.loggerOutput.val}` |
||||||
|
); |
||||||
|
|
||||||
|
}) |
||||||
|
|
||||||
|
it('truffle run coverage --useGlobalTruffle', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
truffleConfig.useGlobalTruffle = true; |
||||||
|
|
||||||
|
truffleConfig.logger = mock.testLogger; |
||||||
|
mock.install('Simple', 'simple.js', solcoverConfig); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
assert( |
||||||
|
mock.loggerOutput.val.includes('global node_modules'), |
||||||
|
`Should notify it's using global truffle (output --> ${mock.loggerOutput.val}` |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it('truffle run coverage --usePluginTruffle', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
truffleConfig.usePluginTruffle = true; |
||||||
|
|
||||||
|
truffleConfig.logger = mock.testLogger; |
||||||
|
mock.install('Simple', 'simple.js', solcoverConfig); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
assert( |
||||||
|
mock.loggerOutput.val.includes('fallback Truffle library module'), |
||||||
|
`Should notify it's using plugin truffle lib copy (output --> ${mock.loggerOutput.val}` |
||||||
|
); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
@ -0,0 +1,187 @@ |
|||||||
|
const assert = require('assert'); |
||||||
|
const fs = require('fs'); |
||||||
|
const path = require('path') |
||||||
|
const shell = require('shelljs'); |
||||||
|
|
||||||
|
const verify = require('../../util/verifiers') |
||||||
|
const mock = require('../../util/integration.truffle'); |
||||||
|
const plugin = require('../../../dist/truffle.plugin'); |
||||||
|
|
||||||
|
// =======================
|
||||||
|
// Standard Use-case Tests
|
||||||
|
// =======================
|
||||||
|
|
||||||
|
describe('Truffle Plugin: standard use cases', function() { |
||||||
|
let truffleConfig; |
||||||
|
let solcoverConfig; |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
mock.clean(); |
||||||
|
|
||||||
|
mock.loggerOutput.val = ''; |
||||||
|
solcoverConfig = {}; |
||||||
|
truffleConfig = mock.getDefaultTruffleConfig(); |
||||||
|
}) |
||||||
|
|
||||||
|
afterEach(() => mock.clean()); |
||||||
|
|
||||||
|
it('simple contract: should generate coverage, cleanup & exit(0)', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
mock.install('Simple', 'simple.js', solcoverConfig); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
verify.coverageGenerated(truffleConfig); |
||||||
|
|
||||||
|
const output = mock.getOutput(truffleConfig); |
||||||
|
const path = Object.keys(output)[0]; |
||||||
|
|
||||||
|
assert(output[path].fnMap['1'].name === 'test', 'coverage.json missing "test"'); |
||||||
|
assert(output[path].fnMap['2'].name === 'getX', 'coverage.json missing "getX"'); |
||||||
|
}); |
||||||
|
|
||||||
|
// Truffle test asserts balance is 777 ether
|
||||||
|
it('config with providerOptions', async function() { |
||||||
|
solcoverConfig.providerOptions = { default_balance_ether: 777 } |
||||||
|
|
||||||
|
mock.install('Simple', 'testrpc-options.js', solcoverConfig); |
||||||
|
await plugin(truffleConfig); |
||||||
|
}); |
||||||
|
|
||||||
|
it('large contract with many unbracketed statements (time check)', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
truffleConfig.compilers.solc.version = "0.4.24"; |
||||||
|
|
||||||
|
mock.install('Oraclize', 'oraclize.js', solcoverConfig, truffleConfig, true); |
||||||
|
await plugin(truffleConfig); |
||||||
|
}); |
||||||
|
|
||||||
|
// This project has three contract suites and uses .deployed() instances which
|
||||||
|
// depend on truffle's migratons and the inter-test evm_revert / evm_snapshot mechanism.
|
||||||
|
it('project evm_reverts repeatedly', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
mock.installFullProject('multiple-migrations'); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
const expected = [ |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractA.sol'), |
||||||
|
pct: 100 |
||||||
|
}, |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractB.sol'), |
||||||
|
pct: 100, |
||||||
|
}, |
||||||
|
{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractC.sol'), |
||||||
|
pct: 100, |
||||||
|
}, |
||||||
|
]; |
||||||
|
|
||||||
|
verify.lineCoverage(expected); |
||||||
|
}); |
||||||
|
|
||||||
|
it('project skips a folder', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
mock.installFullProject('skipping'); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
const expected = [{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractA.sol'), |
||||||
|
pct: 100 |
||||||
|
}]; |
||||||
|
|
||||||
|
const missing = [{ |
||||||
|
file: mock.pathToContract(truffleConfig, 'ContractB.sol'), |
||||||
|
}]; |
||||||
|
|
||||||
|
verify.lineCoverage(expected); |
||||||
|
verify.coverageMissing(missing); |
||||||
|
}); |
||||||
|
|
||||||
|
it('project with relative path solidity imports', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
mock.installFullProject('import-paths'); |
||||||
|
await plugin(truffleConfig); |
||||||
|
}); |
||||||
|
|
||||||
|
it('project contains native solidity tests', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
mock.install('Simple', 'TestSimple.sol', solcoverConfig); |
||||||
|
|
||||||
|
truffleConfig.logger = mock.testLogger; |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
assert( |
||||||
|
mock.loggerOutput.val.includes('native solidity tests'), |
||||||
|
`Should warn it is skipping native solidity tests (output --> ${mock.loggerOutput.val}` |
||||||
|
); |
||||||
|
}); |
||||||
|
|
||||||
|
it('contract only uses ".call"', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
mock.install('OnlyCall', 'only-call.js', solcoverConfig); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
verify.coverageGenerated(truffleConfig); |
||||||
|
|
||||||
|
const output = mock.getOutput(truffleConfig); |
||||||
|
const path = Object.keys(output)[0]; |
||||||
|
assert(output[path].fnMap['1'].name === 'addTwo', 'cov should map "addTwo"'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('contract sends / transfers to instrumented fallback', async function(){ |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
mock.install('Wallet', 'wallet.js', solcoverConfig); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
verify.coverageGenerated(truffleConfig); |
||||||
|
|
||||||
|
const output = mock.getOutput(truffleConfig); |
||||||
|
const path = Object.keys(output)[0]; |
||||||
|
assert(output[path].fnMap['1'].name === 'transferPayment', 'cov should map "transferPayment"'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('contracts are skipped', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
solcoverConfig.skipFiles = ['Owned.sol']; |
||||||
|
|
||||||
|
mock.installDouble(['Proxy', 'Owned'], 'inheritance.js', solcoverConfig); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
verify.coverageGenerated(truffleConfig); |
||||||
|
|
||||||
|
const output = mock.getOutput(truffleConfig); |
||||||
|
const firstKey = Object.keys(output)[0]; |
||||||
|
|
||||||
|
assert(Object.keys(output).length === 1, 'Wrong # of contracts covered'); |
||||||
|
assert(firstKey.substr(firstKey.length - 9) === 'Proxy.sol', 'Wrong contract covered'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('contract uses inheritance', async function() { |
||||||
|
verify.cleanInitialState(); |
||||||
|
|
||||||
|
mock.installDouble(['Proxy', 'Owned'], 'inheritance.js', solcoverConfig); |
||||||
|
await plugin(truffleConfig); |
||||||
|
|
||||||
|
verify.coverageGenerated(truffleConfig); |
||||||
|
|
||||||
|
const output = mock.getOutput(truffleConfig); |
||||||
|
const ownedPath = Object.keys(output)[0]; |
||||||
|
const proxyPath = Object.keys(output)[1]; |
||||||
|
|
||||||
|
assert(output[ownedPath].fnMap['1'].name === 'constructor', '"constructor" not covered'); |
||||||
|
assert(output[proxyPath].fnMap['1'].name === 'isOwner', '"isOwner" not covered'); |
||||||
|
}); |
||||||
|
|
||||||
|
// Truffle test asserts deployment cost is greater than 20,000,000 gas
|
||||||
|
it('deployment cost > block gasLimit', async function() { |
||||||
|
mock.install('Expensive', 'block-gas-limit.js', solcoverConfig); |
||||||
|
await plugin(truffleConfig); |
||||||
|
}); |
||||||
|
}) |
@ -0,0 +1,41 @@ |
|||||||
|
const fs = require('fs'); |
||||||
|
const path = require('path'); |
||||||
|
const shell = require('shelljs'); |
||||||
|
const assert = require('assert'); |
||||||
|
|
||||||
|
function pathExists(path) { return shell.test('-e', path); } |
||||||
|
|
||||||
|
function lineCoverage(expected=[]){ |
||||||
|
let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json')); |
||||||
|
expected.forEach(item => assert(summary[item.file].lines.pct === item.pct)) |
||||||
|
} |
||||||
|
|
||||||
|
function coverageMissing(expected=[]){ |
||||||
|
let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json')); |
||||||
|
expected.forEach(item => assert(summary[item.file] === undefined)) |
||||||
|
} |
||||||
|
|
||||||
|
function cleanInitialState(){ |
||||||
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
||||||
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
||||||
|
} |
||||||
|
|
||||||
|
function coverageGenerated(truffleConfig){ |
||||||
|
const jsonPath = path.join(truffleConfig.working_directory, "coverage.json"); |
||||||
|
assert(pathExists('./coverage') === true, 'should gen coverage folder'); |
||||||
|
assert(pathExists(jsonPath) === true, 'should gen coverage.json'); |
||||||
|
} |
||||||
|
|
||||||
|
function coverageNotGenerated(truffleConfig){ |
||||||
|
const jsonPath = path.join(truffleConfig.working_directory, "coverage.json"); |
||||||
|
assert(pathExists('./coverage') !== true, 'should NOT gen coverage folder'); |
||||||
|
assert(pathExists(jsonPath) !== true, 'should NOT gen coverage.json'); |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
lineCoverage: lineCoverage, |
||||||
|
coverageMissing: coverageMissing, |
||||||
|
cleanInitialState: cleanInitialState, |
||||||
|
coverageGenerated: coverageGenerated, |
||||||
|
coverageNotGenerated: coverageNotGenerated, |
||||||
|
} |
Loading…
Reference in new issue