Skip to content

Commit

Permalink
Handle Cairo 1 print (#1803)
Browse files Browse the repository at this point in the history
  • Loading branch information
karol-bisztyga authored Apr 27, 2023
1 parent ace7af0 commit c34adfe
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 1 deletion.
2 changes: 2 additions & 0 deletions protostar/cairo_testing/cairo_hint_local_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
MockCallHintLocal,
ExpectCallHintLocal,
AssertExpectCallHintLocal,
PrintHintLocal,
)
from protostar.cheatable_starknet.callable_hint_locals.stop_prank_hint_local import (
StopPrankHintLocal,
Expand Down Expand Up @@ -116,6 +117,7 @@ def build_hint_locals(self) -> List[HintLocal]:
MockCallHintLocal(controller=contracts_controller),
ExpectCallHintLocal(controller=expect_call_controller),
AssertExpectCallHintLocal(controller=expect_call_controller),
PrintHintLocal(),
]


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
from .mock_call_hint_local import MockCallHintLocal
from .expect_call_hint_local import ExpectCallHintLocal
from .assert_expect_call_hint_local import AssertExpectCallHintLocal
from .print_hint_local import PrintHintLocal
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from typing import Callable

from protostar.cheatable_starknet.controllers.io import protostar_print
from protostar.starknet.data_transformer import CairoData

from .callable_hint_local import CallableHintLocal


class PrintHintLocal(CallableHintLocal):
@property
def name(self) -> str:
return "protostar_print"

def _build(
self,
) -> Callable[[CairoData], None]:
return self.protostar_print

def protostar_print(self, data: CairoData) -> None:
protostar_print(data=data)
10 changes: 10 additions & 0 deletions protostar/cheatable_starknet/controllers/io.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from protostar.starknet.data_transformer import CairoData
from protostar.cairo.short_string import short_string_to_str


def protostar_print(data: CairoData):
for data_item in data:
str_data = short_string_to_str(data_item)
original_value_msg = f"original value: [{str(data_item)}]"
converted_value_msg = f"converted to a string: [{str_data}]"
print(original_value_msg, converted_value_msg)
48 changes: 48 additions & 0 deletions tests/integration/cairo1/compiler_bindings/test_print.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from pathlib import Path

import pytest

from tests.integration._conftest import ProtostarProjectFixture
from tests.integration.conftest import (
CreateProtostarProjectFixture,
assert_cairo_test_cases,
)
from protostar.testing.test_results import PassedTestCaseResult


@pytest.fixture(name="protostar_project", scope="function")
def protostar_fixture(create_protostar_project: CreateProtostarProjectFixture):
with create_protostar_project() as protostar_project:
yield protostar_project


async def test_print(protostar_project: ProtostarProjectFixture, datadir: Path):
testing_summary = await protostar_project.protostar.test_cairo1(
datadir / "print_test.cairo",
)

assert_cairo_test_cases(
testing_summary,
expected_passed_test_cases_names=["test_print_basic"],
)

expected_outputs = {
"test_print_basic": [
"original value: [448378203247] converted to a string: [hello]",
"original value: [1953658213] converted to a string: [true]",
"original value: [439721161573] converted to a string: [false]",
"original value: [1953658213] converted to a string: [true]",
"original value: [1986358889] converted to a string: [veni]",
"original value: [1986618473] converted to a string: [vidi]",
"original value: [1986618217] converted to a string: [vici]",
],
}

mapping_item = testing_summary.test_suites_mapping.get(datadir / "print_test.cairo")
assert mapping_item is not None

for item in mapping_item:
assert isinstance(item, PassedTestCaseResult)
expected_outputs_list = expected_outputs[item.test_case_name]
for expected_output in expected_outputs_list:
assert expected_output in item.captured_stdout["test"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use array::ArrayTrait;
use protostar_print::PrintTrait;
use result::ResultTrait;

#[test]
fn test_print_basic() {
1.print();

'hello'.print();

let mut array = ArrayTrait::new();
array.append('veni');
array.append('vidi');
array.append('vici');
array.print();

(1 == 2).print();

true.print();

assert(1 == 1, 'xxx');
}
36 changes: 36 additions & 0 deletions website/docs/tutorials/08-cairo-1-support/07-debugging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
sidebar_label: Debugging
---

Currently, Cairo does not support a debugging mechanism per se, but we can print variables' values to the standard output.

# Printing to stdout

In order to print a variable's value to the standard output, we have to use `PrintTrait`:

```
use array::ArrayTrait;
use protostar_print::PrintTrait;
use result::ResultTrait;
#[test]
fn test_print_basic() {
1.print();
'hello'.print();
let mut array = ArrayTrait::new();
array.append('veni');
array.append('vidi');
array.append('vici');
array.print();
(1 == 2).print();
true.print();
assert(1 == 1, 'xxx');
}
```

You can print numbers, booleans and [Cairo short strings](https://www.cairo-lang.org/docs/how_cairo_works/consts.html#short-string-literals) as well as arrays containing values of these types.

0 comments on commit c34adfe

Please sign in to comment.