Skip to content

Commit

Permalink
ProtostarFixture (#566)
Browse files Browse the repository at this point in the history
* Initial draft

* Removed artifacts

* Cleanup

* Added protocols

* add compiled_project fixture

* fix project testing environemnet

* rename fixtures

* use constants for fixture names

* fix importing fixtures

* use module scope

* add declare test

* add tests

* add more learning tests

* remove invoke and _add call test

* _add test

* refine test

* change fixture desired interface

* _add protostar fixture

* add protostar fixture

* use protostar fixture for declare cheatcode

* use protostar fixture in gateway facade

* remove asyncs

* remove dead code

* use protostar fixture

* make call pass

* move contract to tests.data

* fix creating migration output file

* add more tests

* format

* handle errors

* fix gateway facade tests

* fix types and format

* refine

* fix protostar toml

* fix lint

* remove invoke

* remove call cheatcode

* refine no protostar toml exception

* remove "call" literal type

* rename type

* remove unnecessary log color provider

* remove cwd

* remove cwd

* remove type

* renamed cwd to project root path

* fix e2e tests

Co-authored-by: Arkadiusz Kasprzyk <arkadiusz.kasprzyk@swmansion.com>
Co-authored-by: Arkadiusz Kasprzyk <arkadiuszkasprzyk95@gmail.com>
  • Loading branch information
3 people authored Aug 17, 2022
1 parent 7418246 commit b497508
Show file tree
Hide file tree
Showing 19 changed files with 348 additions and 64 deletions.
2 changes: 1 addition & 1 deletion protostar/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sys

from starkware.crypto.signature.fast_pedersen_hash import pedersen_hash
from crypto_cpp_py.cpp_bindings import cpp_hash
from starkware.crypto.signature.fast_pedersen_hash import pedersen_hash


def patched_pedersen_hash(left: int, right: int) -> int:
Expand Down
19 changes: 16 additions & 3 deletions protostar/commands/build/build_command.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from logging import Logger
from pathlib import Path
from typing import List, Optional

from protostar.cli import ActivityIndicator, Command
Expand Down Expand Up @@ -48,15 +49,27 @@ def arguments(self) -> List[Command.Argument]:
]

async def run(self, args):
await self.build(
output_dir=args.output,
disable_hint_validation=args.disable_hint_validation,
relative_cairo_path=args.cairo_path,
)

async def build(
self,
output_dir: Path,
disable_hint_validation=False,
relative_cairo_path: Optional[List[Path]] = None,
):
with ActivityIndicator(
log_color_provider.colorize("GRAY", "Building projects' contracts")
):
try:
self._project_compiler.compile_project(
output_dir=args.output,
output_dir=output_dir,
config=ProjectCompilerConfig(
hint_validation_disabled=args.disable_hint_validation,
relative_cairo_path=args.cairo_path,
hint_validation_disabled=disable_hint_validation,
relative_cairo_path=relative_cairo_path or [],
),
)
except BaseException as exc:
Expand Down
6 changes: 3 additions & 3 deletions protostar/commands/init/init_command.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import glob
from glob import glob
from typing import List, Optional

from protostar.cli import Command
Expand Down Expand Up @@ -67,7 +67,7 @@ def init(self, force_adapting_existing_project: bool):

@staticmethod
def _can_be_protostar_project() -> bool:
files_depth_3 = glob.glob("*") + glob.glob("*/*") + glob.glob("*/*/*")
files_depth_3 = glob("*") + glob("*/*") + glob("*/*/*")
return any(
map(lambda f: f.endswith(".cairo") or f == ".git", files_depth_3)
) and "protostar.toml" not in glob.glob("*")
) and "protostar.toml" not in glob("*")
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from dataclasses import dataclass
from pathlib import Path
from typing import Optional

from git import InvalidGitRepositoryError
from git.repo import Repo
Expand All @@ -16,17 +17,20 @@ class UserInput:
project_dirname: str
lib_dirname: str

# pylint: disable=too-many-arguments
def __init__(
self,
script_root: Path,
requester: InputRequester,
protostar_toml_writer: ProtostarTOMLWriter,
version_manager: VersionManager,
output_dir_path: Optional[Path] = None,
):
super().__init__(script_root, protostar_toml_writer, version_manager)
self._protostar_toml_writer = protostar_toml_writer
self._version_manager = version_manager
self._requester = requester
self._output_dir_path = output_dir_path or Path()

def run(self):
self._create_project(self._gather_input())
Expand All @@ -46,7 +50,8 @@ def _gather_input(self) -> "NewProjectCreator.UserInput":
return NewProjectCreator.UserInput(project_dirname, lib_dirname)

def _create_project(self, user_input: "NewProjectCreator.UserInput") -> None:
project_root_path = Path() / user_input.project_dirname
output_dir_path = self._output_dir_path
project_root_path = output_dir_path / user_input.project_dirname
self.copy_template("default", project_root_path)

libs_path = Path(project_root_path, user_input.lib_dirname)
Expand Down
10 changes: 6 additions & 4 deletions protostar/commands/migrate/migrate_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
from typing import List, Optional

from protostar.cli import Command
from protostar.commands.deploy import DeployCommand
from protostar.commands.test.test_environment_exceptions import CheatcodeException
from protostar.migrator import Migrator
from protostar.protostar_exception import ProtostarException
from protostar.utils.input_requester import InputRequester
from protostar.utils.log_color_provider import LogColorProvider
from protostar.commands.deploy import DeployCommand


class MigrateCommand(Command):
Expand Down Expand Up @@ -69,8 +69,8 @@ def arguments(self) -> List[Command.Argument]:
DeployCommand.network_arg,
]

async def run(self, args):
await self.migrate(
async def run(self, args) -> Optional[Migrator.History]:
return await self.migrate(
migration_file_path=args.path,
rollback=args.rollback,
network=args.network or args.gateway_url,
Expand Down Expand Up @@ -114,8 +114,10 @@ async def migrate(
migrator.save_history(
migrator_history,
migration_file_basename=Path(migration_file_path).stem,
output_dir_path=output_dir_path,
output_dir_relative_path=output_dir_path,
)
self._logger.info("Migration completed")

return migrator_history
except CheatcodeException as ex:
raise ProtostarException(str(ex)) from ex
8 changes: 4 additions & 4 deletions protostar/composition_root.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,10 @@ class DIContainer:
# pylint: disable=too-many-locals
def build_di_container(script_root: Path):
logger = getLogger()
protostar_toml_path = search_upwards_protostar_toml_path(
start_path=Path().resolve()
)
cwd = Path().resolve()
protostar_toml_path = search_upwards_protostar_toml_path(start_path=cwd)
project_root_path = (
protostar_toml_path.parent if protostar_toml_path is not None else Path()
protostar_toml_path.parent if protostar_toml_path is not None else cwd
)
protostar_toml_path = protostar_toml_path or project_root_path / "protostar.toml"
protostar_directory = ProtostarDirectory(script_root)
Expand Down Expand Up @@ -152,6 +151,7 @@ def build_di_container(script_root: Path):
migrator_builder=Migrator.Builder(
migrator_execution_environment_builder=MigratorExecutionEnvironment.Builder(),
gateway_facade_builder=GatewayFacade.Builder(project_root_path),
project_root_path=project_root_path,
),
requester=requester,
logger=logger,
Expand Down
19 changes: 14 additions & 5 deletions protostar/migrator/migrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from protostar.migrator.migrator_execution_environment import (
MigratorExecutionEnvironment,
)

from protostar.starknet_gateway.gateway_facade import GatewayFacade
from protostar.starknet_gateway.starknet_request import StarknetRequest
from protostar.utils.log_color_provider import LogColorProvider
Expand All @@ -29,6 +28,7 @@ def __init__(
self,
migrator_execution_environment_builder: MigratorExecutionEnvironment.Builder,
gateway_facade_builder: GatewayFacade.Builder,
project_root_path: Optional[Path] = None,
) -> None:
self._migrator_execution_environment_builder = (
migrator_execution_environment_builder
Expand All @@ -39,6 +39,7 @@ def __init__(
self._migrator_execution_environment_config = (
MigratorExecutionEnvironment.Config()
)
self._project_root_path = project_root_path

def set_logger(
self, logger: Logger, log_color_provider: LogColorProvider
Expand Down Expand Up @@ -72,12 +73,17 @@ async def build(self, migration_file_path: Path):
)
)

return Migrator(migrator_execution_environment=migrator_execution_env)
return Migrator(
migrator_execution_environment=migrator_execution_env,
project_root_path=self._project_root_path,
)

def __init__(
self,
migrator_execution_environment: MigratorExecutionEnvironment,
project_root_path: Optional[Path] = None,
) -> None:
self._project_root_path = project_root_path or Path()
self._migrator_execution_environment = migrator_execution_environment

async def run(self, rollback=False) -> History:
Expand All @@ -90,16 +96,19 @@ async def run(self, rollback=False) -> History:
starknet_requests=self._migrator_execution_environment.cheatcode_factory.gateway_facade.get_starknet_requests()
)

@staticmethod
def save_history(
self,
history: History,
migration_file_basename: str,
output_dir_path: Path,
output_dir_relative_path: Path,
):
output_dir_path = self._project_root_path / output_dir_relative_path
prefix = datetime.strftime(datetime.now(), "%Y%m%d%H%M%S")
output_file_path = output_dir_path / f"{prefix}_{migration_file_basename}.json"

if not output_dir_path.exists():
output_dir_path.mkdir(parents=True)
output_dir_path.mkdir(
parents=True,
)

history.save_as_json(output_file_path)
11 changes: 8 additions & 3 deletions protostar/migrator/migrator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
from pathlib import Path

from freezegun import freeze_time
from pytest_mock import MockerFixture

from protostar.migrator.migrator import Migrator
from protostar.starknet_gateway.starknet_request import StarknetRequest


@freeze_time("2022-04-02 21:37:42")
def test_migrator_saves_result_successfully_with_proper_name(tmp_path: Path):
Migrator.save_history(
def test_migrator_saves_result_successfully_with_proper_name(
mocker: MockerFixture, tmp_path: Path
):
migrator = Migrator(migrator_execution_environment=mocker.MagicMock())

migrator.save_history(
history=Migrator.History(
starknet_requests=[
StarknetRequest(
Expand All @@ -18,7 +23,7 @@ def test_migrator_saves_result_successfully_with_proper_name(tmp_path: Path):
]
),
migration_file_basename="01_init",
output_dir_path=tmp_path,
output_dir_relative_path=tmp_path,
)

assert "20220402213742_01_init.json" in listdir(tmp_path)
4 changes: 1 addition & 3 deletions protostar/protostar_toml/io/protostar_toml_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,7 @@ def _read_if_cache_miss(self) -> Dict[str, Any]:
return self._cache

if not self.path.is_file():
raise NoProtostarProjectFoundException(
"No protostar.toml found in the working directory"
)
raise NoProtostarProjectFoundException("`protostar.toml` not found")

with open(self.path, "rb") as protostar_toml_file:
protostar_toml_dict = tomli.load(protostar_toml_file)
Expand Down
11 changes: 5 additions & 6 deletions protostar/starknet_gateway/gateway_facade.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import dataclasses
from logging import Logger
from pathlib import Path
from typing import Callable, List, Optional
import dataclasses

from starkware.starknet.services.api.gateway.transaction import DECLARE_SENDER_ADDRESS
from starkware.starknet.definitions import constants

from starknet_py.net.gateway_client import GatewayClient
from starknet_py.transactions.deploy import make_deploy_tx
from starknet_py.transactions.declare import make_declare_tx
from starknet_py.net.models import StarknetChainId
from starknet_py.transactions.declare import make_declare_tx
from starknet_py.transactions.deploy import make_deploy_tx
from starkware.starknet.definitions import constants
from starkware.starknet.services.api.gateway.transaction import DECLARE_SENDER_ADDRESS

from protostar.protostar_exception import ProtostarException
from protostar.starknet_gateway.gateway_response import (
Expand Down
2 changes: 1 addition & 1 deletion scripts/generate_reference_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from protostar.composition_root import build_di_container

CLI_REFERENCE_MARKDOWN_CONTENT = ReferenceDocsGenerator(
build_di_container(Path()).protostar_cli
build_di_container(script_root=Path()).protostar_cli
).generate_cli_reference_markdown()

ReferenceDocsGenerator.save_to_markdown_file(
Expand Down
2 changes: 1 addition & 1 deletion scripts/generate_reference_docs_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


def test_instance_matches_cli_reference_docs():
di_container = build_di_container(Path())
di_container = build_di_container(script_root=Path())
new_snapshot = ReferenceDocsGenerator(
di_container.protostar_cli
).generate_cli_reference_markdown()
Expand Down
8 changes: 8 additions & 0 deletions tests/data/contracts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
IDENTITY_CONTRACT = """
%lang starknet
@view
func identity(arg) -> (res : felt):
return (arg)
end
"""
22 changes: 22 additions & 0 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@
from typing import List, Optional, Set, Union

import pytest
from pytest import TempPathFactory
from pytest_mock import MockerFixture
from typing_extensions import Protocol

from protostar.commands.test.test_command import TestCommand
from protostar.commands.test.testing_summary import TestingSummary
from tests.conftest import run_devnet
from tests.integration.protostar_fixture import (
ProtostarFixture,
build_protostar_fixture,
)


@dataclass
Expand Down Expand Up @@ -102,3 +107,20 @@ async def run_cairo_test_runner(
).test(targets=[str(path)], seed=seed, fuzz_max_examples=fuzz_max_examples)

return run_cairo_test_runner


@pytest.fixture(name="protostar_project_root_path", scope="module")
def protostar_project_root_path_fixture(tmp_path_factory: TempPathFactory) -> Path:
tmp_path = tmp_path_factory.mktemp("data")
return tmp_path / "tmp_project"


@pytest.fixture(name="protostar", scope="module")
def protostar_fixture(
session_mocker: MockerFixture,
protostar_project_root_path: Path,
) -> ProtostarFixture:
return build_protostar_fixture(
mocker=session_mocker,
project_root_path=protostar_project_root_path,
)
34 changes: 34 additions & 0 deletions tests/integration/gateway/gateway_facade_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from pathlib import Path

import pytest

from protostar.starknet_gateway.gateway_facade import GatewayFacade
from tests.integration.protostar_fixture import ProtostarFixture


@pytest.fixture(autouse=True, scope="module")
def setup(protostar: ProtostarFixture):
protostar.init_sync()
protostar.build_sync()


@pytest.fixture(name="compiled_contract_path")
def compiled_contract_path_fixture(protostar: ProtostarFixture) -> Path:
return protostar.project_root_path / "build" / "main.json"


@pytest.fixture(name="gateway_facade")
def gateway_facade_fixture(devnet_gateway_url: str):
gateway_facade_builder = GatewayFacade.Builder(project_root_path=Path())
gateway_facade_builder.set_network(devnet_gateway_url)
return gateway_facade_builder.build()


async def test_deploy(gateway_facade: GatewayFacade, compiled_contract_path: Path):
response = await gateway_facade.deploy(compiled_contract_path)
assert response is not None


async def test_declare(gateway_facade: GatewayFacade, compiled_contract_path: Path):
response = await gateway_facade.declare(compiled_contract_path)
assert response is not None

This file was deleted.

Loading

0 comments on commit b497508

Please sign in to comment.