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

release #223

Merged
merged 11 commits into from Jan 19, 2022
6 changes: 3 additions & 3 deletions .github/workflows/ci.yaml
Expand Up @@ -245,7 +245,7 @@ jobs:
npm run build-${{ matrix.platform }}-${{ matrix.architecture }}

- name: Code sign bin (Windows)
if: matrix.os == 'windows-latest'
if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'windows-latest'
run: |
$certificate_file_name = "${env:TEMP}\certificate.pfx"

Expand All @@ -266,10 +266,10 @@ jobs:

- name: Build Installer (Windows)
if: matrix.os == 'windows-latest'
run: cargo wix -v --no-build --nocapture
run: cargo wix -v --no-build --nocapture -p clarinet

- name: Code sign installer (Windows)
if: matrix.os == 'windows-latest'
if: startsWith(github.ref, 'refs/tags/v') && matrix.os == 'windows-latest'
run: |
$certificate_file_name = "${env:TEMP}\certificate.pfx"

Expand Down
4 changes: 4 additions & 0 deletions deno/index.ts
Expand Up @@ -186,6 +186,8 @@ type PreSetupFunction = () => Array<Tx>;

interface UnitTestOptions {
name: string;
only?: true;
ignore? :true;
preSetup?: PreSetupFunction;
fn: TestFunction;
}
Expand Down Expand Up @@ -214,6 +216,8 @@ export class Clarinet {
static test(options: UnitTestOptions) {
Deno.test({
name: options.name,
only: options.only,
ignore: options.ignore,
async fn() {
(Deno as any).core.ops();

Expand Down
8 changes: 4 additions & 4 deletions src/frontend/cli.rs
Expand Up @@ -694,7 +694,7 @@ fn display_post_check_hint() {
"{}",
yellow!(" Run all run tests in the ./tests folder.\n")
);
println!("{}", yellow!("Find more information on testing with Clarinet here: https://docs.hiro.so/docs/smart-contracts/clarinet#testing-with-the-test-harness"));
println!("{}", yellow!("Find more information on testing with Clarinet here: https://docs.hiro.so/smart-contracts/clarinet#testing-with-the-test-harness"));
display_hint_footer();
}

Expand All @@ -717,7 +717,7 @@ fn display_post_poke_hint() {
yellow!(" Check contract syntax for all files in ./contracts.\n")
);

println!("{}", yellow!("Find more information on writing contracts with Clarinet here: https://docs.hiro.so/docs/smart-contracts/clarinet#developing-a-clarity-smart-contract"));
println!("{}", yellow!("Find more information on writing contracts with Clarinet here: https://docs.hiro.so/smart-contracts/clarinet#developing-a-clarity-smart-contract"));
display_hint_footer();
}

Expand Down Expand Up @@ -755,7 +755,7 @@ fn display_tests_pro_tips_hint() {
yellow!(" Deploy all contracts to a local dockerized blockchain setup (Devnet).\n")
);

println!("{}", yellow!("Find more information on testing with Clarinet here: https://docs.hiro.so/docs/smart-contracts/clarinet#testing-with-clarinet"));
println!("{}", yellow!("Find more information on testing with Clarinet here: https://docs.hiro.so/smart-contracts/clarinet#testing-with-clarinet"));
display_hint_footer();
}

Expand Down Expand Up @@ -785,7 +785,7 @@ fn display_deploy_hint() {
);
println!(
"{}",
yellow!("Find more information on the DevNet here: https://docs.hiro.so/docs/smart-contracts/devnet")
yellow!("Find more information on the DevNet here: https://docs.hiro.so/smart-contracts/devnet/")
);
display_hint_footer();
}
141 changes: 140 additions & 1 deletion src/runnner/deno.rs
@@ -1,4 +1,6 @@
use clarity_repl::clarity::coverage::CoverageReporter;
use clarity_repl::clarity::types;
use clarity_repl::clarity::util::hash;
use clarity_repl::prettytable::{color, format, Attr, Cell, Row, Table};
use clarity_repl::repl::session::CostsReport;
use clarity_repl::repl::Session;
Expand Down Expand Up @@ -35,6 +37,7 @@ use serde::Serialize;
use std::collections::HashSet;
use std::collections::{btree_map::Entry, BTreeMap};
use std::convert::TryFrom;
use std::fmt::Write;
use std::ops::Index;
use std::path::Path;
use std::path::PathBuf;
Expand Down Expand Up @@ -1183,6 +1186,61 @@ struct TransferSTXArgs {
recipient: String,
}

fn value_to_string(value: &types::Value) -> String {
use clarity_repl::clarity::types::{CharType, SequenceData, Value};

match value {
Value::Tuple(tup_data) => {
let mut out = String::new();
write!(out, "{{");
for (i, (name, value)) in tup_data.data_map.iter().enumerate() {
write!(out, "{}: {}", &**name, value_to_string(value));
if i < tup_data.data_map.len() - 1 {
write!(out, ", ");
}
}
write!(out, "}}");
out
}
Value::Optional(opt_data) => match opt_data.data {
Some(ref x) => format!("(some {})", value_to_string(&**x)),
None => "none".to_string(),
},
Value::Response(res_data) => match res_data.committed {
true => format!("(ok {})", value_to_string(&*res_data.data)),
false => format!("(err {})", value_to_string(&*res_data.data)),
},
Value::Sequence(SequenceData::String(CharType::ASCII(data))) => {
format!("\"{}\"", String::from_utf8(data.data.clone()).unwrap())
}
Value::Sequence(SequenceData::String(CharType::UTF8(data))) => {
let mut result = String::new();
for c in data.data.iter() {
if c.len() > 1 {
// We escape extended charset
result.push_str(&format!("\\u{{{}}}", hash::to_hex(&c[..])));
} else {
result.push(c[0] as char)
}
}
format!("u\"{}\"", result)
}
Value::Sequence(SequenceData::List(list_data)) => {
let mut out = String::new();
write!(out, "[");
for (ix, v) in list_data.data.iter().enumerate() {
if ix > 0 {
write!(out, ", ");
}
write!(out, "{}", value_to_string(v));
}
write!(out, "]");
out
}
_ => format!("{}", value),
}
}

fn mine_block(state: &mut OpState, args: Value, _: ()) -> Result<String, AnyError> {
let args: MineBlockArgs =
serde_json::from_value(args).expect("Invalid request from JavaScript.");
Expand Down Expand Up @@ -1215,7 +1273,7 @@ fn mine_block(state: &mut OpState, args: Value, _: ()) -> Result<String, AnyErro
}
};
let result = match execution.result {
Some(output) => format!("{}", output),
Some(output) => value_to_string(&output),
_ => unreachable!("Value empty"),
};
receipts.push((result, execution.events));
Expand Down Expand Up @@ -1360,3 +1418,84 @@ fn get_assets_maps(state: &mut OpState, args: Value, _: ()) -> Result<String, An
})
.to_string())
}

#[cfg(test)]
mod tests {
use clarity_repl::clarity::representations::ClarityName;
use clarity_repl::clarity::types::{
ListTypeData, OptionalData, ResponseData, SequenceData, SequencedValue, TupleData,
};

use super::*;

#[test]
fn test_value_to_string() {
let mut s = value_to_string(&types::Value::Int(42));
assert_eq!(s, "42");

s = value_to_string(&types::Value::UInt(12345678909876));
assert_eq!(s, "u12345678909876");

s = value_to_string(&types::Value::Bool(true));
assert_eq!(s, "true");

s = value_to_string(&types::Value::buff_from(vec![1, 2, 3]).unwrap());
assert_eq!(s, "0x010203");

s = value_to_string(&types::Value::buff_from(vec![1, 2, 3]).unwrap());
assert_eq!(s, "0x010203");

s = value_to_string(&types::Value::Tuple(
TupleData::from_data(vec![(
ClarityName::try_from("foo".to_string()).unwrap(),
types::Value::Bool(true),
)])
.unwrap(),
));
assert_eq!(s, "{foo: true}");

s = value_to_string(&types::Value::Optional(OptionalData {
data: Some(Box::new(types::Value::UInt(42))),
}));
assert_eq!(s, "(some u42)");

s = value_to_string(&types::NONE);
assert_eq!(s, "none");

s = value_to_string(&types::Value::Response(ResponseData {
committed: true,
data: Box::new(types::Value::Int(-321)),
}));
assert_eq!(s, "(ok -321)");

s = value_to_string(&types::Value::Response(ResponseData {
committed: false,
data: Box::new(types::Value::Sequence(types::SequenceData::String(
types::CharType::ASCII(types::ASCIIData {
data: "'foo'".as_bytes().to_vec(),
}),
))),
}));
assert_eq!(s, "(err \"'foo'\")");

s = value_to_string(&types::Value::Sequence(types::SequenceData::String(
types::CharType::ASCII(types::ASCIIData {
data: "Hello, \"world\"\n".as_bytes().to_vec(),
}),
)));
assert_eq!(s, "\"Hello, \"world\"\n\"");

s = value_to_string(&types::UTF8Data::to_value(
&"Hello, 'world'\n".as_bytes().to_vec(),
));
assert_eq!(s, "u\"Hello, 'world'\n\"");

s = value_to_string(&types::Value::Sequence(SequenceData::List(
types::ListData {
data: vec![types::Value::Int(-321)],
type_signature: ListTypeData::new_list(types::TypeSignature::IntType, 2).unwrap(),
},
)));
assert_eq!(s, "[-321]");
}
}