Skip to content

Commit

Permalink
🧹 Add expect-based tests for interactive scripts (#389)
Browse files Browse the repository at this point in the history
  • Loading branch information
janjakubnanista authored Feb 12, 2024
1 parent bdbe8ab commit 3ca8eb9
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 1 deletion.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.turbo
dist
node_modules
*.exp
*.md
*.sol
*.toml
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.exp
*.log
.eslintignore
.prettierignore
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/expect -f
#
# This Expect script was generated by autoexpect on Mon Feb 12 16:57:18 2024
# Expect and autoexpect were both written by Don Libes, NIST.
#
# Note that autoexpect does not guarantee a working script. It
# necessarily has to guess about certain things. Two reasons a script
# might fail are:
#
# 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,
# etc.) and devices discard or ignore keystrokes that arrive "too
# quickly" after prompts. If you find your new script hanging up at
# one spot, try adding a short sleep just before the previous send.
# Setting "force_conservative" to 1 (see below) makes Expect do this
# automatically - pausing briefly before sending each character. This
# pacifies every program I know of. The -c flag makes the script do
# this in the first place. The -C flag allows you to define a
# character to toggle this mode off and on.

set force_conservative 0
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}


set timeout 60
spawn npx hardhat lz:deploy
match_max 100000

expect "Which networks would you like to deploy?"
send -- "\r"

expect "Which deploy script tags would you like to use?"
send -- "MeNoExist"
send -- "\r"

expect "Will deploy 3 networks: britney, tango, vengaboys"
expect "Will use deploy scripts tagged with MeNoExist"
expect "Do you want to continue?"
send -- "\r"

expect "Deploying..."
expect "Your contracts are now deployed"

expect eof
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/expect -f
#
# This Expect script was generated by autoexpect on Mon Feb 12 16:57:18 2024
# Expect and autoexpect were both written by Don Libes, NIST.
#
# Note that autoexpect does not guarantee a working script. It
# necessarily has to guess about certain things. Two reasons a script
# might fail are:
#
# 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,
# etc.) and devices discard or ignore keystrokes that arrive "too
# quickly" after prompts. If you find your new script hanging up at
# one spot, try adding a short sleep just before the previous send.
# Setting "force_conservative" to 1 (see below) makes Expect do this
# automatically - pausing briefly before sending each character. This
# pacifies every program I know of. The -c flag makes the script do
# this in the first place. The -C flag allows you to define a
# character to toggle this mode off and on.

set force_conservative 0
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}


set timeout 60
spawn npx hardhat lz:deploy
match_max 100000

expect "Which networks would you like to deploy?"
send -- "\r"

expect "Which deploy script tags would you like to use?"
send -- "\r"

expect "Will deploy 3 networks: britney, tango, vengaboys"
expect "Will use all deployment scripts"
expect "Do you want to continue?"
send -- "\r"

expect "Deploying..."
expect "Your contracts are now deployed"

expect eof
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/expect -f
#
# This Expect script was generated by autoexpect on Mon Feb 12 16:57:18 2024
# Expect and autoexpect were both written by Don Libes, NIST.
#
# Note that autoexpect does not guarantee a working script. It
# necessarily has to guess about certain things. Two reasons a script
# might fail are:
#
# 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,
# etc.) and devices discard or ignore keystrokes that arrive "too
# quickly" after prompts. If you find your new script hanging up at
# one spot, try adding a short sleep just before the previous send.
# Setting "force_conservative" to 1 (see below) makes Expect do this
# automatically - pausing briefly before sending each character. This
# pacifies every program I know of. The -c flag makes the script do
# this in the first place. The -C flag allows you to define a
# character to toggle this mode off and on.

set force_conservative 0
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}


set timeout 60
spawn npx hardhat lz:deploy
match_max 100000

expect "Which networks would you like to deploy?"

# First we deselect britney
send -- " "
# We move down by pressing down array
send -- "\[B"
# Then we deselect tango
send -- " "
# Finally we confirm
send -- "\r"

expect "Which deploy script tags would you like to use?"
send -- "Thrower"
send -- "\r"

expect "Will deploy 1 network: vengaboys"
expect "Will use deploy scripts tagged with Thrower"
expect "Do you want to continue?"
send -- "\r"

expect "Deploying..."
expect "Your contracts are now deployed"

expect eof
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/expect -f
#
# This Expect script was generated by autoexpect on Mon Feb 12 16:57:18 2024
# Expect and autoexpect were both written by Don Libes, NIST.
#
# Note that autoexpect does not guarantee a working script. It
# necessarily has to guess about certain things. Two reasons a script
# might fail are:
#
# 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,
# etc.) and devices discard or ignore keystrokes that arrive "too
# quickly" after prompts. If you find your new script hanging up at
# one spot, try adding a short sleep just before the previous send.
# Setting "force_conservative" to 1 (see below) makes Expect do this
# automatically - pausing briefly before sending each character. This
# pacifies every program I know of. The -c flag makes the script do
# this in the first place. The -C flag allows you to define a
# character to toggle this mode off and on.

set force_conservative 0
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}


set timeout 60
spawn npx hardhat lz:deploy
match_max 100000

expect "Which networks would you like to deploy?"

# First we deselect britney
send -- " "
# We move down by pressing down array
send -- "\[B"
# Then we deselect tango
send -- " "
# Finally we confirm
send -- "\r"

expect "Which deploy script tags would you like to use?"
send -- "\r"

expect "Will deploy 1 network: vengaboys"
expect "Will use all deployment scripts"
expect "Do you want to continue?"
send -- "\r"

expect "Deploying..."
expect "Your contracts are now deployed"

expect eof
81 changes: 80 additions & 1 deletion tests/devtools-evm-hardhat-test/test/task/deploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import hre from 'hardhat'
import { TASK_COMPILE } from 'hardhat/builtin-tasks/task-names'
import { DeploymentsManager } from 'hardhat-deploy/dist/src/DeploymentsManager'
import { TASK_LZ_DEPLOY } from '@layerzerolabs/devtools-evm-hardhat'
import { promptForText, promptToContinue, promptToSelectMultiple } from '@layerzerolabs/io-devtools'
import {
isDirectory,
isFile,
promptForText,
promptToContinue,
promptToSelectMultiple,
} from '@layerzerolabs/io-devtools'
import { spawnSync } from 'child_process'
import { join } from 'path'

jest.mock('@layerzerolabs/io-devtools', () => {
const original = jest.requireActual('@layerzerolabs/io-devtools')
Expand All @@ -24,6 +32,77 @@ const runSpy = jest.spyOn(hre, 'run')
const runDeploySpy = jest.spyOn(DeploymentsManager.prototype, 'runDeploy')

describe(`task ${TASK_LZ_DEPLOY}`, () => {
describe('expectations', () => {
const EXPECTATIONS_DIRECTORY = join('test', 'task', 'deploy.test.expectations')
const expectationPath = (name: string) => join(EXPECTATIONS_DIRECTORY, `${name}.exp`)
const runExpect = (name: string) =>
spawnSync(expectationPath(name), {
encoding: 'utf8',
stdio: 'inherit',
})

const deploymentsPath = (networkName: string) => join('deployments', networkName)

const deploymentPath = (networkName: string) => (name: string) =>
join(deploymentsPath(networkName), `${name}.json`)

it('should deploy all tags on all networks', async () => {
const result = runExpect('deploy-all')

expect(result.status).toBe(0)

const britneyDeploymentPath = deploymentPath('britney')
const tangoDeploymentPath = deploymentPath('tango')
const vengaboysDeploymentPath = deploymentPath('vengaboys')

expect(isFile(britneyDeploymentPath('TestProxy'))).toBeTruthy()
expect(isFile(tangoDeploymentPath('TestProxy'))).toBeTruthy()
expect(isFile(vengaboysDeploymentPath('TestProxy'))).toBeTruthy()

expect(isFile(britneyDeploymentPath('Thrower'))).toBeTruthy()
expect(isFile(tangoDeploymentPath('Thrower'))).toBeTruthy()
expect(isFile(vengaboysDeploymentPath('Thrower'))).toBeTruthy()
})

it('should deploy all tags on vengaboys', async () => {
const result = runExpect('deploy-vengaboys')

expect(result.status).toBe(0)

const vengaboysDeploymentPath = deploymentPath('vengaboys')

expect(isDirectory(deploymentsPath('britney'))).toBeFalsy()
expect(isDirectory(deploymentsPath('tango'))).toBeFalsy()

expect(isFile(vengaboysDeploymentPath('TestProxy'))).toBeTruthy()
expect(isFile(vengaboysDeploymentPath('Thrower'))).toBeTruthy()
})

it('should deploy single tag on vengaboys', async () => {
const result = runExpect('deploy-vengaboys-thrower')

expect(result.status).toBe(0)

const vengaboysDeploymentPath = deploymentPath('vengaboys')

expect(isDirectory(deploymentsPath('britney'))).toBeFalsy()
expect(isDirectory(deploymentsPath('tango'))).toBeFalsy()

expect(isFile(vengaboysDeploymentPath('Thrower'))).toBeTruthy()
expect(isFile(vengaboysDeploymentPath('TestProxy'))).toBeFalsy()
})

it('should not deploy anything if tag does not exist', async () => {
const result = runExpect('deploy-all-missing-tag')

expect(result.status).toBe(0)

expect(isDirectory(deploymentsPath('britney'))).toBeFalsy()
expect(isDirectory(deploymentsPath('tango'))).toBeFalsy()
expect(isDirectory(deploymentsPath('vengaboys'))).toBeFalsy()
})
})

const expectDeployment = expect.objectContaining({
abi: expect.any(Array),
args: expect.any(Array),
Expand Down

0 comments on commit 3ca8eb9

Please sign in to comment.