Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add TS support for tests #94

Merged
merged 10 commits into from
Mar 1, 2021
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ _examples: &examples
before_install:
- nvm install $NODE_VERSION
- npm install -g mocha
- npm install -g ts-mocha
armaniferrante marked this conversation as resolved.
Show resolved Hide resolved
- npm install -g typescript
- npm install -g @project-serum/anchor
- npm install -g @project-serum/serum
- npm install -g @project-serum/common
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ incremented for features.
* ts: Allow preloading instructions for state rpc transactions ([cf9c84](https://github.com/project-serum/anchor/commit/cf9c847e4144989b5bc1936149d171e90204777b)).
* cli: Specify programs to embed into local validator genesis via Anchor.toml while testing.
* cli: Allow skipping the creation of a local validator when testing against localnet.
* cli: Adds support for tests with Typescript ([#94](https://github.com/project-serum/anchor/pull/94)).

## Fixes

Expand Down
54 changes: 40 additions & 14 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ pub struct Opts {
#[derive(Debug, Clap)]
pub enum Command {
/// Initializes a workspace.
Init { name: String },
Init {
name: String,
#[clap(short, long)]
typescript: bool,
},
/// Builds the workspace.
Build {
/// Output directory for the IDL.
Expand Down Expand Up @@ -151,7 +155,7 @@ pub enum IdlCommand {
fn main() -> Result<()> {
let opts = Opts::parse();
match opts.command {
Command::Init { name } => init(name),
Command::Init { name, typescript } => init(name, typescript),
Command::New { name } => new(name),
Command::Build { idl } => build(idl),
Command::Deploy { url, keypair } => deploy(url, keypair),
Expand All @@ -170,7 +174,7 @@ fn main() -> Result<()> {
}
}

fn init(name: String) -> Result<()> {
fn init(name: String, typescript: bool) -> Result<()> {
let cfg = Config::discover()?;

if cfg.is_some() {
Expand All @@ -197,8 +201,17 @@ fn init(name: String) -> Result<()> {

// Build the test suite.
fs::create_dir("tests")?;
let mut mocha = File::create(&format!("tests/{}.js", name))?;
mocha.write_all(template::mocha(&name).as_bytes())?;
if typescript {
// Build typescript config
let mut ts_config = File::create("tsconfig.json")?;
ts_config.write_all(template::ts_config().as_bytes())?;

let mut mocha = File::create(&format!("tests/{}.ts", name))?;
mocha.write_all(template::ts_mocha(&name).as_bytes())?;
} else {
let mut mocha = File::create(&format!("tests/{}.js", name))?;
mocha.write_all(template::mocha(&name).as_bytes())?;
}

// Build the migrations directory.
fs::create_dir("migrations")?;
Expand Down Expand Up @@ -612,18 +625,31 @@ fn test(skip_deploy: bool, skip_local_validator: bool) -> Result<()> {
None
}
};

let log_streams = stream_logs(&cfg.cluster.url())?;

let ts_config_exist = Path::new("tsconfig.json").exists();

// Run the tests.
let exit = std::process::Command::new("mocha")
.arg("-t")
.arg("1000000")
.arg("tests/")
.env("ANCHOR_PROVIDER_URL", cfg.cluster.url())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.output()?;
let exit = match ts_config_exist {
true => std::process::Command::new("ts-mocha")
.arg("-p")
.arg("./tsconfig.json")
.arg("-t")
.arg("1000000")
.arg("tests/**/*.ts")
.env("ANCHOR_PROVIDER_URL", cfg.cluster.url())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.output()?,
false => std::process::Command::new("mocha")
.arg("-t")
.arg("1000000")
.arg("tests/")
.env("ANCHOR_PROVIDER_URL", cfg.cluster.url())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.output()?,
};

if !exit.status.success() {
if let Some(mut validator_handle) = validator_handle {
Expand Down
37 changes: 37 additions & 0 deletions cli/src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,40 @@ describe('{}', () => {{
name.to_camel_case(),
)
}

pub fn ts_mocha(name: &str) -> String {
format!(
r#"import * as anchor from '@project-serum/anchor';

describe('{}', () => {{

// Configure the client to use the local cluster.
anchor.setProvider(anchor.Provider.env());

it('Is initialized!', async () => {{
// Add your test here.
const program = anchor.workspace.{};
const tx = await program.rpc.initialize();
console.log("Your transaction signature", tx);
}});
}});
"#,
name,
name.to_camel_case(),
)
}

pub fn ts_config() -> String {
armaniferrante marked this conversation as resolved.
Show resolved Hide resolved
r#"{
"compilerOptions": {
"types": ["mocha", "chai"],
"typeRoots": ["./node_modules/@types"],
"lib": ["es2015"],
"module": "commonjs",
"target": "es6",
"esModuleInterop": true
}
}
"#
.to_string()
}
25 changes: 25 additions & 0 deletions examples/tutorial/basic-2/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "basic-2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"directories": {
"test": "tests"
},
"scripts": {
"test": "ts-mocha -t 100000 -p ./tsconfig.json tests/**/*.{j,t}s"
},
"author": "",
"license": "ISC",
"dependencies": {
"@project-serum/anchor": "^0.2.2-beta.1",
"@types/chai": "^4.2.15"
},
"devDependencies": {
"@types/expect": "^24.3.0",
"@types/jest": "^26.0.20",
"@types/mocha": "^8.2.1",
"@types/node": "^14.14.31",
"chai": "^4.3.0"
}
}
47 changes: 0 additions & 47 deletions examples/tutorial/basic-2/tests/basic-2.js

This file was deleted.

44 changes: 44 additions & 0 deletions examples/tutorial/basic-2/tests/basic-2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import assert from 'assert'
import * as anchor from '@project-serum/anchor'
describe('basic-2', () => {
const provider = anchor.Provider.local()

// Configure the client to use the local cluster.
anchor.setProvider(provider)

// Counter for the tests.
const counter = new anchor.web3.Account()

// Program for the tests.
const program = anchor.workspace.Basic2

it('Creates a counter', async () => {
await program.rpc.create(provider.wallet.publicKey, {
accounts: {
counter: counter.publicKey,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
},
signers: [counter],
instructions: [await program.account.counter.createInstruction(counter)],
})

let counterAccount = await program.account.counter(counter.publicKey)

assert.ok(counterAccount.authority.equals(provider.wallet.publicKey))
assert.ok(counterAccount.count.toNumber() === 0)
})

it('Updates a counter', async () => {
await program.rpc.increment({
accounts: {
counter: counter.publicKey,
authority: provider.wallet.publicKey,
},
})

const counterAccount = await program.account.counter(counter.publicKey)

assert.ok(counterAccount.authority.equals(provider.wallet.publicKey))
assert.ok(counterAccount.count.toNumber() == 1)
})
})
10 changes: 10 additions & 0 deletions examples/tutorial/basic-2/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"types": ["mocha", "chai"],
"typeRoots": ["./node_modules/@types"],
"lib": ["es2015"],
"module": "commonjs",
"target": "es6",
"esModuleInterop": true
}
}