def test_format_report(self): report = FileReport( file_name=Path('syntaxTests/scoping/library_inherited2.sol'), contract_reports=[ ContractReport( contract_name='A', file_name=Path('syntaxTests/smoke_test.sol'), bytecode=None, metadata=None, ), ContractReport( contract_name='B', file_name=Path('syntaxTests/smoke_test.sol'), bytecode=None, metadata='{"language":"Solidity"}', ), ContractReport( contract_name='Lib', file_name=Path('syntaxTests/smoke_test.sol'), bytecode='60566050600b828282398051', metadata=None, ), ]) expected_output = ( "syntaxTests/scoping/library_inherited2.sol:A <NO BYTECODE>\n" "syntaxTests/scoping/library_inherited2.sol:A <NO METADATA>\n" "syntaxTests/scoping/library_inherited2.sol:B <NO BYTECODE>\n" "syntaxTests/scoping/library_inherited2.sol:B {\"language\":\"Solidity\"}\n" "syntaxTests/scoping/library_inherited2.sol:Lib 60566050600b828282398051\n" "syntaxTests/scoping/library_inherited2.sol:Lib <NO METADATA>\n") self.assertEqual(report.format_report(), expected_output)
def test_parse_cli_output_should_handle_link_references_in_bytecode(self): compiler_output = dedent("""\ ======= contract.sol:C ======= Binary: 73123456789012345678901234567890123456789073__$fb58009a6b1ecea3b9d99bedd645df4ec3$__5050 ======= contract.sol:D ======= Binary: __$fb58009a6b1ecea3b9d99bedd645df4ec3$__ """) # pragma pylint: disable=line-too-long expected_report = FileReport( file_name=Path('contract.sol'), contract_reports=[ ContractReport( contract_name='C', file_name=Path('contract.sol'), bytecode= '73123456789012345678901234567890123456789073__$fb58009a6b1ecea3b9d99bedd645df4ec3$__5050', metadata=None), ContractReport( contract_name='D', file_name=Path('contract.sol'), bytecode='__$fb58009a6b1ecea3b9d99bedd645df4ec3$__', metadata=None), ]) # pragma pylint: enable=line-too-long self.assertEqual( parse_cli_output(Path('contract.sol'), compiler_output), expected_report)
def test_parse_cli_output_should_handle_empty_bytecode_and_metadata_lines(self): compiler_output = dedent("""\ ======= contract.sol:C ======= Binary: 60806040523480156 Metadata: ======= contract.sol:D ======= Binary: Metadata: {} ======= contract.sol:E ======= Binary: Metadata: """) expected_report = FileReport( file_name=Path('contract.sol'), contract_reports=[ ContractReport(contract_name='C', file_name=Path('contract.sol'), bytecode='60806040523480156', metadata=None), ContractReport(contract_name='D', file_name=Path('contract.sol'), bytecode=None, metadata='{}'), ContractReport(contract_name='E', file_name=Path('contract.sol'), bytecode=None, metadata=None), ] ) self.assertEqual(parse_cli_output(Path('contract.sol'), compiler_output), expected_report)
def test_parse_standard_json_output_should_report_missing_if_value_is_just_whitespace( self): compiler_output = dedent("""\ { "contracts": { "contract.sol": { "A": { "evm": {"bytecode": {"object": ""}}, "metadata": "" }, "B": { "evm": {"bytecode": {"object": " "}}, "metadata": " " } } } } """) expected_report = FileReport( file_name=Path('contract.sol'), contract_reports=[ ContractReport(contract_name='A', file_name=Path('contract.sol'), bytecode=None, metadata=None), ContractReport(contract_name='B', file_name=Path('contract.sol'), bytecode=None, metadata=None), ]) self.assertEqual( parse_standard_json_output(Path('contract.sol'), compiler_output), expected_report)
def test_parse_cli_output(self): expected_report = FileReport( file_name=Path('syntaxTests/scoping/library_inherited2.sol'), contract_reports=[ # pragma pylint: disable=line-too-long ContractReport( contract_name='A', file_name=Path('syntaxTests/scoping/library_inherited2.sol'), bytecode='6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea264697066735822122086e727f29d40b264a19bbfcad38d64493dca4bab5dbba8c82ffdaae389d2bba064736f6c63430008000033', metadata='{"compiler":{"version":"0.8.0+commit.c7dfd78e"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"syntaxTests/scoping/library_inherited2.sol":"A"},"evmVersion":"istanbul","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"syntaxTests/scoping/library_inherited2.sol":{"keccak256":"0xd0619f00638fdfea187368965615dbd599fead93dd14b6558725e85ec7011d96","urls":["bzz-raw://ec7af066be66a223f0d25ba3bf9ba6dc103e1a57531a66a38a5ca2b6ce172f55","dweb:/ipfs/QmW1NrqQNhnY1Tkgr3Z9oM8buCGLUJCJVCDTVejJTT5Vet"]}},"version":1}', ), ContractReport( contract_name='B', file_name=Path('syntaxTests/scoping/library_inherited2.sol'), bytecode='608060405234801561001057600080fd5b506101cc806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80630423a13214610030575b600080fd5b61004a6004803603810190610045919061009d565b610060565b60405161005791906100d5565b60405180910390f35b600061006b82610072565b9050919050565b6000602a8261008191906100f0565b9050919050565b6000813590506100978161017f565b92915050565b6000602082840312156100af57600080fd5b60006100bd84828501610088565b91505092915050565b6100cf81610146565b82525050565b60006020820190506100ea60008301846100c6565b92915050565b60006100fb82610146565b915061010683610146565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561013b5761013a610150565b5b828201905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b61018881610146565b811461019357600080fd5b5056fea2646970667358221220104c345633313efe410492448844d96d78452c3044ce126b5e041b7fbeaa790064736f6c63430008000033', metadata='{"compiler":{"version":"0.8.0+commit.c7dfd78e"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"bar","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"syntaxTests/scoping/library_inherited2.sol":"B"},"evmVersion":"istanbul","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"syntaxTests/scoping/library_inherited2.sol":{"keccak256":"0xd0619f00638fdfea187368965615dbd599fead93dd14b6558725e85ec7011d96","urls":["bzz-raw://ec7af066be66a223f0d25ba3bf9ba6dc103e1a57531a66a38a5ca2b6ce172f55","dweb:/ipfs/QmW1NrqQNhnY1Tkgr3Z9oM8buCGLUJCJVCDTVejJTT5Vet"]}},"version":1}', ), ContractReport( contract_name='Lib', file_name=Path('syntaxTests/scoping/library_inherited2.sol'), bytecode='60566050600b82828239805160001a6073146043577f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207f9515e2263fa71a7984707e2aefd82241fac15c497386ca798b526f14f8ba6664736f6c63430008000033', metadata='{"compiler":{"version":"0.8.0+commit.c7dfd78e"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"syntaxTests/scoping/library_inherited2.sol":"Lib"},"evmVersion":"istanbul","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"syntaxTests/scoping/library_inherited2.sol":{"keccak256":"0xd0619f00638fdfea187368965615dbd599fead93dd14b6558725e85ec7011d96","urls":["bzz-raw://ec7af066be66a223f0d25ba3bf9ba6dc103e1a57531a66a38a5ca2b6ce172f55","dweb:/ipfs/QmW1NrqQNhnY1Tkgr3Z9oM8buCGLUJCJVCDTVejJTT5Vet"]}},"version":1}', ), # pragma pylint: enable=line-too-long ] ) report = parse_cli_output(Path('syntaxTests/scoping/library_inherited2.sol'), LIBRARY_INHERITED2_SOL_CLI_OUTPUT) self.assertEqual(report, expected_report)
def test_aggregate_multiple_contract_reports(self): statistics = Statistics() statistics.aggregate( FileReport(file_name=Path('F'), contract_reports=[ ContractReport('C', 'c.sol', 'B', 'M'), ContractReport('C', 'c.sol', None, 'M'), ContractReport('C', 'c.sol', 'B', None), ContractReport('C', 'c.sol', None, None), ])) self.assertEqual(statistics, Statistics(1, 4, 0, 2, 2))
def test_aggregate_metadata_missing(self): statistics = Statistics() statistics.aggregate( FileReport( file_name=Path('F'), contract_reports=[ContractReport('C', 'c.sol', 'B', None)])) self.assertEqual(statistics, Statistics(1, 1, 0, 0, 1))
def test_aggregate_bytecode_and_metadata_present(self): statistics = Statistics() statistics.aggregate( FileReport( file_name=Path('F'), contract_reports=[ContractReport('C', 'c.sol', 'B', 'M')])) self.assertEqual(statistics, Statistics(1, 1, 0, 0, 0))
def test_str(self): statistics = Statistics() statistics.aggregate( FileReport(file_name=Path('F'), contract_reports=[ ContractReport('C', 'c.sol', 'B', 'M'), ContractReport('C', 'c.sol', None, 'M'), ContractReport('C', 'c.sol', 'B', None), ContractReport('C', 'c.sol', None, None), ])) statistics.aggregate( FileReport(file_name=Path('F'), contract_reports=None)) self.assertEqual(statistics, Statistics(2, 4, 1, 2, 2)) self.assertEqual( str(statistics), "test cases: 2, contracts: 4+, errors: 1, missing bytecode: 2, missing metadata: 2" )
def test_parse_cli_output_should_handle_output_from_solc_0_4_0(self): expected_report = FileReport( file_name=Path('contract.sol'), contract_reports=[ ContractReport( contract_name='C', file_name=None, bytecode='6060604052600c8060106000396000f360606040526008565b600256', metadata=None, ) ] ) self.assertEqual(parse_cli_output(Path('contract.sol'), SOLC_0_4_0_CLI_OUTPUT), expected_report)
def test_parse_cli_output_should_handle_output_from_solc_0_4_8(self): expected_report = FileReport( file_name=Path('contract.sol'), contract_reports=[ # pragma pylint: disable=line-too-long ContractReport( contract_name='C', file_name=None, bytecode='6060604052346000575b60358060166000396000f30060606040525b60005600a165627a7a72305820ccf9337430b4c4f7d6ad41efb10a94411a2af6a9f173ef52daeadd31f4bf11890029', metadata='{"compiler":{"version":"0.4.8+commit.60cc1668.mod.Darwin.appleclang"},"language":"Solidity","output":{"abi":[],"devdoc":{"methods":{}},"userdoc":{"methods":{}}},"settings":{"compilationTarget":{"contract.sol":"C"},"libraries":{},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"contract.sol":{"keccak256":"0xbe86d3681a198587296ad6d4a834606197e1a8f8944922c501631b04e21eeba2","urls":["bzzr://af16957d3d86013309d64d3cc572d007b1d8b08a821f2ff366840deb54a78524"]}},"version":1}', ) # pragma pylint: enable=line-too-long ] ) self.assertEqual(parse_cli_output(Path('contract.sol'), SOLC_0_4_8_CLI_OUTPUT), expected_report)
def test_parse_standard_json_output_should_not_report_error_if_there_is_at_least_one_file_with_contracts(self): compiler_output = ( "{\n" " \"contracts\": {\n" " \"contract1.sol\": {\"A\": {}},\n" " \"contract2.sol\": {}\n" " }\n" "}\n" ) expected_report = FileReport( file_name=Path('contract.sol'), contract_reports=[ContractReport(contract_name='A', file_name=Path('contract1.sol'), bytecode=None, metadata=None)] ) self.assertEqual(parse_standard_json_output(Path('contract.sol'), compiler_output), expected_report)
def test_parse_cli_output_should_handle_leading_and_trailing_spaces(self): compiler_output = ( ' ======= contract.sol : C ======= \n' ' Binary: \n' ' 60806040523480156 \n' ' Metadata: \n' ' { } \n' ) expected_report = FileReport( file_name=Path('contract.sol'), contract_reports=[ ContractReport(contract_name='C', file_name=Path('contract.sol'), bytecode='60806040523480156', metadata='{ }') ] ) self.assertEqual(parse_cli_output(Path('contract.sol'), compiler_output), expected_report)