def test_number_of_valid_statements(self):
        source = """
			pragma solidity ^0.4.22;
			contract testContract {
				function testFunction () public pure returns (string) {
					uint foo = 5;
					require(foo > 5);
					return 'helloWorld';
				}
			}
		"""
        events, statements = self.before_test(source)
        statement_under_test = filter_statements(events, statements)
        self.assertTrue(len(statement_under_test) == 2)
    def test_not_valid_function_assignment(self):
        source = """
			pragma solidity ^0.4.22;
			contract testContract {
				function testFunction () public pure returns (string) {
					uint foo = 5;
					foo = 6;
					require(foo > 5);
					return 'helloWorld';
				}
			}
		"""
        events, statements = self.before_test(source)
        self.assertTrue(len(statements) > 0)
        statement_under_test = filter_statements(events, statements)
        print(len(statement_under_test))
        self.assertTrue(len(statement_under_test) ==
                        2)  # foo and requ are ok, foo re-assigment is skipped
    def test_not_valid_function_function_call(self):
        source = """
			pragma solidity ^0.4.22;
			contract testContract {
				function getNumber () public pure returns (uint) {
					uint foo = 5;
					return foo;
				}
				
				function testFunction () public pure returns (string) {
					uint foo = 5;
					uint bar = getNumber();
					require(foo > 5);
					return 'helloWorld';
				}
			}
		"""
        events, statements = self.before_test(source)
        self.assertTrue(len(statements) > 0)
        statement_under_test = filter_statements(events, statements)
        self.assertTrue(len(statement_under_test) == 0)
    def test_valid_function_emitted_events(self):
        """
			the function should ignore all the emit events
			statements
		"""
        source = """
			pragma solidity ^0.4.22;
			contract testContract {
				event TestEvent(uint t);
				function testFunction () public returns (string) {
					uint foo = 5;
					emit TestEvent(foo);
					uint bar = uint8(foo);
					require(foo > 5);
					return 'helloWorld';
				}
			}
		"""
        events, statements = self.before_test(source)
        self.assertTrue(len(statements) > 0)
        self.assertTrue(len(events) == 1)
        statement_under_test = filter_statements(events, statements)
        self.assertTrue(len(statement_under_test) == 3)
    def test_valid_function_cast(self):
        """
			type casts are not consider as function call
			they are consider as valid statements
			and should be properly handle during the mapping
			from solidity to z3
		"""
        source = """
			pragma solidity ^0.4.22;
			contract testContract {
				event TestEvent(uint t);
				function testFunction () public returns (string) {
					uint foo = 5;
					uint bar = uint8(foo);
					require(foo > 5);
					return 'helloWorld';
				}
			}
		"""
        events, statements = self.before_test(source)
        self.assertTrue(len(statements) > 0)
        statement_under_test = filter_statements(events, statements)
        self.assertTrue(len(statement_under_test) == 3)