diff --git a/packages/cli/test/scripts/create.test.js b/packages/cli/test/scripts/create.test.js index 70197e2ab..38fe6cdbb 100644 --- a/packages/cli/test/scripts/create.test.js +++ b/packages/cli/test/scripts/create.test.js @@ -81,25 +81,6 @@ contract('create script', function([_, owner]) { networks.filter(network => network.address === proxyAddress).should.be.have.lengthOf(1) }); - it('should refuse to create a proxy for an undefined contract', async function() { - await createProxy({ contractAlias: 'NotExists', network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith(/Contract NotExists not found/); - }); - - it('should refuse to create a proxy for a lib project', async function() { - this.packageFile.lib = true - await createProxy({ contractAlias, network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith('Cannot create a proxy for a library project'); - }); - - it('should refuse to create a proxy for an undeployed contract', async function() { - const customContractsData = [{ name: contractName, alias: 'NotDeployed' }] - await add({ contractsData: customContractsData, packageFile: this.packageFile }); - - await createProxy({ contractAlias: 'NotDeployed', network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith('Contract NotDeployed is not deployed to test.'); - }); - it('should be able to have multiple proxies for one of its contracts', async function() { await createProxy({ contractAlias, network, txParams, networkFile: this.networkFile }); await createProxy({ contractAlias, network, txParams, networkFile: this.networkFile }); @@ -116,7 +97,7 @@ contract('create script', function([_, owner]) { await assertProxy(this.networkFile, anotherContractAlias, { version, say: 'AnotherV1' }); }); - describe('warnings', function () { + describe('warnings and errors', function () { beforeEach('capturing log output', function () { this.logs = new CaptureLogs(); }); @@ -150,6 +131,28 @@ contract('create script', function([_, owner]) { this.logs.errors.should.have.lengthOf(0); }); + + it('should refuse to create a proxy for an undefined contract', async function() { + await createProxy({ contractAlias: 'NotExists', network, txParams, networkFile: this.networkFile }) + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.match(/Contract NotExists not found/) + }); + + it('should refuse to create a proxy for a lib project', async function() { + this.packageFile.lib = true + await createProxy({ contractAlias, network, txParams, networkFile: this.networkFile }) + .should.be.rejectedWith('Cannot create a proxy for a library project') + }); + + it('should refuse to create a proxy for an undeployed contract', async function() { + const customContractsData = [{ name: contractName, alias: 'NotDeployed' }] + await add({ contractsData: customContractsData, packageFile: this.packageFile }); + + await createProxy({ contractAlias: 'NotDeployed', network, txParams, networkFile: this.networkFile }) + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.eq('Contract NotDeployed is not deployed to test.') + }); + }); describe('with dependency', function () { @@ -158,46 +161,84 @@ contract('create script', function([_, owner]) { await push({ network, txParams, deployLibs: true, networkFile: this.networkFile }); }); - it('should fail to create a proxy from a dependency without specifying package name', async function () { - await createProxy({ contractAlias: 'Greeter', network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith(/not found/) - }); - it('should create a proxy from a dependency', async function () { await createProxy({ packageName: 'mock-stdlib-undeployed', contractAlias: 'Greeter', network, txParams, networkFile: this.networkFile }); await assertProxy(this.networkFile, 'Greeter', { version, packageName: 'mock-stdlib-undeployed' }); }); + + describe('errors', function() { + beforeEach('capturing log output', function() { + this.logs = new CaptureLogs() + }) + + afterEach(function() { + this.logs.restore() + }) + + it('should fail to create a proxy from a dependency without specifying package name', async function () { + await createProxy({ contractAlias: 'Greeter', network, txParams, networkFile: this.networkFile }) + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.match(/not found/) + }); + }) }); describe('with unlinked dependency', function () { beforeEach('setting dependency', async function () { + this.logs = new CaptureLogs() await linkLibs({ libs: ['mock-stdlib@1.1.0'], packageFile: this.packageFile }); }); + afterEach(function() { + this.logs.restore() + }) + it('should refuse create a proxy for unlinked dependency', async function () { await createProxy({ packageName: 'mock-stdlib', contractAlias: 'Greeter', network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith(/Dependency mock-stdlib has not been linked yet/) + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.match(/Dependency mock-stdlib has not been linked yet/) }); }); - it('should refuse to create a proxy for an undefined contract', async function() { - await createProxy({ contractAlias: 'NotExists', network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith(/Contract NotExists not found/); - }); + describe('errors', function() { + beforeEach('capturing log output', function () { + this.logs = new CaptureLogs() + }); - it('should refuse to create a proxy for an undefined dependency', async function() { - await createProxy({ packageName: 'NotExists', contractAlias, network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith(/Dependency NotExists not found/); - }); + afterEach(function() { + this.logs.restore() + }) + + it('should refuse to create a proxy for an undefined contract', async function() { + await createProxy({ contractAlias: 'NotExists', network, txParams, networkFile: this.networkFile }) + + this.logs.errors.should.have.lengthOf(1) + this.logs.errors.should.match(/Contract NotExists not found/); + }); + + it('should refuse to create a proxy for an undefined dependency', async function() { + await createProxy({ packageName: 'NotExists', contractAlias, network, txParams, networkFile: this.networkFile }) + + this.logs.errors.should.have.lengthOf(1) + this.logs.errors.should.match(/Dependency NotExists not found/); + }); + }) describe('with local modifications', function () { - beforeEach('changing local network file to have a different bytecode', async function () { + beforeEach('changing local network file to have a different bytecode', function () { + this.logs = new CaptureLogs() this.networkFile.contract(contractAlias).bytecodeHash = '0xabcd' }); + afterEach(function() { + this.logs.restore() + }) + it('should refuse to create a proxy for a modified contract', async function () { await createProxy({ contractAlias,network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith('Contract Impl has changed locally since the last deploy, consider running \'zos push\'.'); + + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.eq('Contract Impl has changed locally since the last deploy, consider running \'zos push\'.'); }); it('should create a proxy for an unmodified contract', async function () { @@ -215,7 +256,7 @@ contract('create script', function([_, owner]) { } describe('on lightweight app', function () { - beforeEach('setup', async function() { + beforeEach('setup', function() { this.packageFile = new ZosPackageFile('test/mocks/packages/package-empty.zos.json') this.packageFile.lightweight = true }); @@ -224,7 +265,7 @@ contract('create script', function([_, owner]) { }) describe('on full app', function () { - beforeEach('setup', async function() { + beforeEach('setup', function() { this.packageFile = new ZosPackageFile('test/mocks/packages/package-empty.zos.json') }); diff --git a/packages/cli/test/scripts/push.test.js b/packages/cli/test/scripts/push.test.js index 87b72aae7..3c4610200 100644 --- a/packages/cli/test/scripts/push.test.js +++ b/packages/cli/test/scripts/push.test.js @@ -12,6 +12,7 @@ import bumpVersion from '../../src/scripts/bump'; import ZosPackageFile from '../../src/models/files/ZosPackageFile'; import remove from '../../src/scripts/remove'; import Dependency from '../../src/models/dependency/Dependency'; +import CaptureLogs from '../helpers/captureLogs' const should = require('chai').should(); @@ -23,6 +24,14 @@ contract('push script', function([_, owner]) { const txParams = { from: owner } const defaultVersion = '1.1.0'; + beforeEach('init capture logs', function() { + this.logs = new CaptureLogs() + }) + + afterEach(function() { + this.logs.restore() + }) + const shouldDeployPackage = function () { it('should create a network file with version info', async function() { this.networkFile.isCurrentVersion(defaultVersion).should.be.true; @@ -117,7 +126,10 @@ contract('push script', function([_, owner]) { it('should refuse to redeploy a contract if storage is incompatible', async function () { modifyBytecode.call(this, 'Impl'); modifyStorageInfo.call(this, 'Impl'); - await push({ networkFile: this.networkFile, network, txParams }).should.be.rejectedWith(/review the warnings/) + await push({ networkFile: this.networkFile, network, txParams }) + this.logs.errors.should.have.lengthOf(2) + this.logs.errors[0].should.match(/was removed from contract ImplV1/) + this.logs.errors[1].should.match(/review the warnings/) this.networkFile.contract('Impl').address.should.eq(this.previousAddress); }); @@ -249,7 +261,9 @@ contract('push script', function([_, owner]) { const packageFile = new ZosPackageFile('test/mocks/packages/package-with-invalid-contracts.zos.json') this.networkFile = packageFile.networkFile(network) - await push({ networkFile: this.networkFile, network, txParams }).should.be.rejectedWith(/WithFailingConstructor deployment failed/); + await push({ networkFile: this.networkFile, network, txParams }) + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.match(/WithFailingConstructor deployment failed/) }); shouldDeployApp(); @@ -306,7 +320,8 @@ contract('push script', function([_, owner]) { it('should fail to push', async function () { await push({ network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith(/Required dependency version 1.0.0 does not match dependency package version 2.0.0/) + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.match(/Required dependency version 1.0.0 does not match dependency package version 2.0.0/) }); }) @@ -318,7 +333,8 @@ contract('push script', function([_, owner]) { it('should fail to push', async function () { await push({ network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith(/Could not find a zos file for network 'test' for 'mock-stdlib-undeployed'/) + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.match(/Could not find a zos file for network 'test' for 'mock-stdlib-undeployed'/) }); }) }); @@ -356,7 +372,9 @@ contract('push script', function([_, owner]) { it('should refuse to push when frozen', async function() { await freeze({ network, txParams, networkFile: this.networkFile }) - await push({ network, txParams, networkFile: this.networkFile }).should.be.rejectedWith(/frozen/i) + await push({ network, txParams, networkFile: this.networkFile }) + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.match(/frozen/i) }); }); @@ -398,8 +416,9 @@ contract('push script', function([_, owner]) { const packageFile = new ZosPackageFile('test/mocks/packages/package-with-invalid-contracts.zos.json') packageFile.lightweight = true this.networkFile = packageFile.networkFile(network) - - await push({ networkFile: this.networkFile, network, txParams }).should.be.rejectedWith(/WithFailingConstructor deployment failed/); + await push({ networkFile: this.networkFile, network, txParams }) + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.match(/WithFailingConstructor deployment failed/); }); shouldDeployContracts(); diff --git a/packages/cli/test/scripts/update.test.js b/packages/cli/test/scripts/update.test.js index 874524311..f7d1b664a 100644 --- a/packages/cli/test/scripts/update.test.js +++ b/packages/cli/test/scripts/update.test.js @@ -134,27 +134,39 @@ contract('update script', function([_skipped, owner, anotherAccount]) { await assertProxyInfo(this.networkFile, 'Impl', 1, { version: version_2, implementation: this.implV2Address, value: 42 }); }); - it('should upgrade multiple proxies and migrate them', async function() { - // add non-migratable implementation for AnotherImpl contract - await add({ contractsData: [{ name: 'UnmigratableImplV2', alias: 'AnotherImpl' }], packageFile: this.packageFile }) - await push({ network, txParams, networkFile: this.networkFile }); + describe('errors', function(){ + beforeEach('capturing log output', function() { + this.logs = new CaptureLogs() + }) + + afterEach(function() { + this.logs.restore() + }) + + it('should upgrade multiple proxies and migrate them', async function() { + // add non-migratable implementation for AnotherImpl contract + await add({ contractsData: [{ name: 'UnmigratableImplV2', alias: 'AnotherImpl' }], packageFile: this.packageFile }) + await push({ network, txParams, networkFile: this.networkFile }); - await update({ contractAlias: undefined, proxyAddress: undefined, all: true, initMethod: "migrate", initArgs: [42], network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith(/failed to update/); + await update({ contractAlias: undefined, proxyAddress: undefined, all: true, initMethod: "migrate", initArgs: [42], network, txParams, networkFile: this.networkFile }) + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.match(/failed to update/) - await assertProxyInfo(this.networkFile, 'Impl', 0, { version: version_2, implementation: this.implV2Address, value: 42 }); - await assertProxyInfo(this.networkFile, 'Impl', 1, { version: version_2, implementation: this.implV2Address, value: 42 }); - await assertProxyInfo(this.networkFile, 'AnotherImpl', 0, { version: version_1, implementation: this.anotherImplV1Address }); - }); + await assertProxyInfo(this.networkFile, 'Impl', 0, { version: version_2, implementation: this.implV2Address, value: 42 }); + await assertProxyInfo(this.networkFile, 'Impl', 1, { version: version_2, implementation: this.implV2Address, value: 42 }); + await assertProxyInfo(this.networkFile, 'AnotherImpl', 0, { version: version_1, implementation: this.anotherImplV1Address }); + }); - it('should refuse to upgrade a proxy to an undeployed contract', async function() { - const contracts = this.networkFile.contracts - delete contracts['Impl']; - this.networkFile.contracts = contracts + it('should refuse to upgrade a proxy to an undeployed contract', async function() { + const contracts = this.networkFile.contracts + delete contracts['Impl']; + this.networkFile.contracts = contracts - await update({ contractAlias: 'Impl', proxyAddress: null, network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith('Contracts Impl are not deployed.') - }); + await update({ contractAlias: 'Impl', proxyAddress: null, network, txParams, networkFile: this.networkFile }) + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.eq('Contracts Impl are not deployed.') + }); + }) describe('with local modifications', function () { beforeEach('changing local network file to have a different bytecode', async function () { @@ -163,15 +175,27 @@ contract('update script', function([_skipped, owner, anotherAccount]) { this.networkFile.contracts = contracts }); - it('should refuse to upgrade a proxy for a modified contract', async function () { - await update({ contractAlias: 'Impl', network, txParams, networkFile: this.networkFile }) - .should.be.rejectedWith('Contracts Impl have changed since the last deploy.'); - }); - it('should upgrade a proxy for a modified contract if force is set', async function () { await update({ contractAlias: 'Impl', network, txParams, force: true, networkFile: this.networkFile }); await assertProxyInfo(this.networkFile, 'Impl', 0, { version: version_2, implementation: this.implV2Address }) }); + + describe('errors', function() { + beforeEach('capturing log output', function() { + this.logs = new CaptureLogs() + }) + + afterEach(function() { + this.logs.restore() + }) + + it('should refuse to upgrade a proxy for a modified contract', async function () { + await update({ contractAlias: 'Impl', network, txParams, networkFile: this.networkFile }) + + this.logs.errors.should.have.lengthOf(1) + this.logs.errors[0].should.eq('Contracts Impl have changed since the last deploy.') + }); + }) }); describe('warnings', function () {