Skip to content

Commit 6c3d978

Browse files
committed
feat: ability to run scripts
example in counter: clarinet run scripts/abi.ts
2 parents 63dcc2f + 896b98f commit 6c3d978

File tree

8 files changed

+97
-9
lines changed

8 files changed

+97
-9
lines changed

deno/index.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,26 @@ interface UnitTestOptions {
189189
fn: TestFunction;
190190
}
191191

192+
export interface Contract {
193+
contract_id: string;
194+
source: string;
195+
contract_interface: any
196+
}
197+
198+
export interface StacksNode {
199+
url: string;
200+
}
201+
202+
type ScriptFunction = (
203+
accounts: Map<string, Account>,
204+
contracts: Map<string, Contract>,
205+
node: StacksNode,
206+
) => void | Promise<void>;
207+
208+
interface ScriptOptions {
209+
fn: ScriptFunction;
210+
}
211+
192212
export class Clarinet {
193213
static test(options: UnitTestOptions) {
194214
Deno.test({
@@ -213,6 +233,32 @@ export class Clarinet {
213233
},
214234
});
215235
}
236+
237+
static run(options: ScriptOptions) {
238+
Deno.test({
239+
name: "running script",
240+
async fn() {
241+
(Deno as any).core.ops();
242+
let result = JSON.parse((Deno as any).core.opSync("setup_chain", {
243+
name: "running script",
244+
transactions: [],
245+
}));
246+
let accounts: Map<string, Account> = new Map();
247+
for (let account of result["accounts"]) {
248+
accounts.set(account.name, account);
249+
}
250+
let contracts: Map<string, any> = new Map();
251+
for (let contract of result["contracts"]) {
252+
contracts.set(contract.contract_id, contract);
253+
}
254+
let stacks_node: StacksNode = {
255+
url: result["stacks_node_url"]
256+
};
257+
await options.fn(accounts, contracts, stacks_node);
258+
},
259+
});
260+
}
261+
216262
}
217263

218264
export namespace types {
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
{
2-
"git.ignoreLimitWarning": true,
32
"deno.enable": true,
43
"deno.unstable": false,
5-
"editor.formatOnSave": true,
6-
"editor.formatOnPaste": true,
74
}

examples/counter/contracts/counter.clar

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
(define-public (increment (step uint))
77
(let ((new-val (+ step (var-get counter))))
88
(var-set counter new-val)
9+
(print { object: "counter", action: "incremented", value: new-val })
910
(ok new-val)))
1011

1112
(define-read-only (read-counter)

examples/counter/scripts/abi.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Clarinet, Contract, Account, StacksNode } from 'https://deno.land/x/clarinet@v0.11.0/index.ts';
2+
3+
Clarinet.run({
4+
async fn(accounts: Map<string, Account>, contracts: Map<string, Contract>, node: StacksNode) {
5+
console.log("Contracts");
6+
for (let contract of contracts) {
7+
console.log(contract);
8+
}
9+
console.log("Accounts");
10+
for (let account of accounts) {
11+
console.log(account);
12+
}
13+
14+
}
15+
});

examples/counter/tests/counter_test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Clarinet, Tx, Chain, Account, types } from 'https://deno.land/x/clarinet@v0.6.0/index.ts';
1+
import { Clarinet, Tx, Chain, Account, types } from 'https://deno.land/x/clarinet@v0.11.0/index.ts';
22
import { assertEquals } from "https://deno.land/std@0.90.0/testing/asserts.ts";
33

44
Clarinet.test({
@@ -26,6 +26,7 @@ Clarinet.test({
2626
Tx.contractCall("counter", "increment", [types.uint(4)], wallet_1.address),
2727
Tx.contractCall("counter", "increment", [types.uint(10)], wallet_1.address)
2828
]);
29+
2930
assertEquals(block.height, 3);
3031
block.receipts[0].result
3132
.expectOk()

src/frontend/cli.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ enum Command {
4444
/// Deploy subcommand
4545
#[clap(name = "deploy")]
4646
Deploy(Deploy),
47+
/// Run subcommand
48+
#[clap(name = "run")]
49+
Run(Run),
4750
}
4851

4952
#[derive(Clap)]
@@ -120,6 +123,15 @@ struct Test {
120123
pub files: Vec<String>,
121124
}
122125

126+
#[derive(Clap)]
127+
struct Run {
128+
/// Print debug info
129+
#[clap(short = 'd')]
130+
pub debug: bool,
131+
/// Script to run
132+
pub script: String,
133+
}
134+
123135
#[derive(Clap)]
124136
struct Deploy {
125137
/// Print debug info
@@ -234,6 +246,15 @@ pub fn main() {
234246
}
235247
run_tests(test.files, test.coverage, test.watch);
236248
},
249+
Command::Run(run) => {
250+
let start_repl = false;
251+
let res = load_session(start_repl, "development".into());
252+
if let Err(e) = res {
253+
println!("{}", e);
254+
return;
255+
}
256+
run_tests(vec![run.script], false, false);
257+
},
237258
Command::Deploy(deploy) => {
238259
let start_repl = false;
239260
let mode = if deploy.mocknet == true {

src/generators/contract.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl GetChangesForNewContract {
6666
fn create_template_test(&mut self) {
6767
let content = format!(
6868
r#"
69-
import {{ Clarinet, Tx, Chain, Account, types }} from 'https://deno.land/x/clarinet@v0.10.0/index.ts';
69+
import {{ Clarinet, Tx, Chain, Account, types }} from 'https://deno.land/x/clarinet@v0.11.0/index.ts';
7070
import {{ assertEquals }} from 'https://deno.land/std@0.90.0/testing/asserts.ts';
7171
7272
Clarinet.test({{

src/test/deno.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ mod sessions {
4444
use std::fs;
4545
use std::env;
4646
use std::collections::HashMap;
47+
use clarity_repl::clarity::analysis::ContractAnalysis;
4748
use deno_core::error::AnyError;
4849
use clarity_repl::repl::{self, Session};
4950
use clarity_repl::repl::settings::Account;
@@ -54,7 +55,7 @@ mod sessions {
5455
pub static ref SESSIONS: Mutex<HashMap<u32, (String, Session)>> = Mutex::new(HashMap::new());
5556
}
5657

57-
pub fn handle_setup_chain(name: String, transactions: Vec<TransactionArgs>) -> Result<(u32, Vec<Account>), AnyError> {
58+
pub fn handle_setup_chain(name: String, transactions: Vec<TransactionArgs>) -> Result<(u32, Vec<Account>, Vec<(ContractAnalysis, String)>), AnyError> {
5859
let mut sessions = SESSIONS.lock().unwrap();
5960
let session_id = sessions.len() as u32;
6061

@@ -133,10 +134,10 @@ mod sessions {
133134
settings.initial_deployer = initial_deployer;
134135
settings.include_boot_contracts = vec!["pox".to_string(), "costs".to_string(), "bns".to_string()];
135136
let mut session = Session::new(settings.clone());
136-
session.start();
137+
let (_, contracts) = session.start();
137138
session.advance_chain_tip(1);
138139
sessions.insert(session_id, (name, session));
139-
Ok((session_id, settings.initial_accounts))
140+
Ok((session_id, settings.initial_accounts, contracts))
140141
}
141142

142143
pub fn perform_block<F, R>(session_id: u32, handler: F) -> Result<R, AnyError> where F: FnOnce(&str, &mut Session) -> Result<R, AnyError> {
@@ -702,11 +703,17 @@ struct SetupChainArgs {
702703
fn setup_chain(state: &mut OpState, args: Value, _: ()) -> Result<String, AnyError> {
703704
let args: SetupChainArgs = serde_json::from_value(args)
704705
.expect("Invalid request from JavaScript for \"op_load\".");
705-
let (session_id, accounts) = sessions::handle_setup_chain(args.name, args.transactions)?;
706+
let (session_id, accounts, contracts) = sessions::handle_setup_chain(args.name, args.transactions)?;
707+
let serialized_contracts = contracts.iter().map(|(a, s)| json!({
708+
"contract_id": a.contract_identifier.to_string(),
709+
"contract_interface": a.contract_interface.clone(),
710+
"source": s
711+
})).collect::<Vec<_>>();
706712

707713
Ok(json!({
708714
"session_id": session_id,
709715
"accounts": accounts,
716+
"contracts": serialized_contracts,
710717
}).to_string())
711718
}
712719

0 commit comments

Comments
 (0)