Kaynağa Gözat

add TS support for tests (#94)

NorbertBodziony 4 yıl önce
ebeveyn
işleme
7b69e0ba23

+ 2 - 0
.travis.yml

@@ -16,6 +16,8 @@ _examples: &examples
   before_install:
   - nvm install $NODE_VERSION
   - npm install -g mocha
+  - npm install -g ts-mocha
+  - npm install -g typescript
   - npm install -g @project-serum/anchor
   - npm install -g @project-serum/serum
   - npm install -g @project-serum/common

+ 1 - 0
CHANGELOG.md

@@ -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
 

+ 40 - 14
cli/src/main.rs

@@ -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.
@@ -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),
@@ -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() {
@@ -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")?;
@@ -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 {

+ 37 - 0
cli/src/template.rs

@@ -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 {
+    r#"{
+  "compilerOptions": {
+    "types": ["mocha", "chai"],
+    "typeRoots": ["./node_modules/@types"],
+    "lib": ["es2015"],
+    "module": "commonjs",
+    "target": "es6",
+    "esModuleInterop": true
+  }
+}
+"#
+    .to_string()
+}

+ 25 - 0
examples/tutorial/basic-2/package.json

@@ -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"
+  }
+}

+ 0 - 47
examples/tutorial/basic-2/tests/basic-2.js

@@ -1,47 +0,0 @@
-const assert = require("assert");
-const anchor = require('@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,
-      },
-    });
-
-    counterAccount = await program.account.counter(counter.publicKey);
-
-    assert.ok(counterAccount.authority.equals(provider.wallet.publicKey));
-    assert.ok(counterAccount.count.toNumber() == 1);
-  });
-});

+ 44 - 0
examples/tutorial/basic-2/tests/basic-2.ts

@@ -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 - 0
examples/tutorial/basic-2/tsconfig.json

@@ -0,0 +1,10 @@
+{
+  "compilerOptions": {
+    "types": ["mocha", "chai"],
+    "typeRoots": ["./node_modules/@types"],
+    "lib": ["es2015"],
+    "module": "commonjs",
+    "target": "es6",
+    "esModuleInterop": true
+  }
+}