def test_diagnostics_across_multiple_files() -> None: file_info_1 = FileInfo( file_path="dummy1.pytch", source_code="""dummy1 line1 dummy1 line2 """, ) file_info_2 = FileInfo( file_path="dummy2.pytch", source_code="""dummy2 line1 dummy2 line2 """, ) error = Error( file_info=file_info_1, code=ErrorCode.NOT_A_REAL_ERROR, severity=Severity.ERROR, message="Look into this", range=Range( start=Position(line=0, character=7), end=Position(line=0, character=12) ), notes=[ Note( file_info=file_info_2, message="This is an additional point of interest", range=Range( start=Position(line=0, character=0), end=Position(line=0, character=5), ), ) ], ) lines = lines_to_string(get_error_lines(error, ascii=True)) print(lines) assert ( lines == """\ NOT_A_REAL_ERROR[9001] in dummy1.pytch, line 1, character 8: Error: Look into this +-----------------------------------------------------+ | dummy1.pytch | 1 | dummy1 line1 | | ^~~~~ Error: Look into this | 2 | dummy1 line2 | +-----------------------------------------------------+ | dummy2.pytch | 1 | dummy2 line1 | | ^~~~~ Note: This is an additional point of interest | 2 | dummy2 line2 | +-----------------------------------------------------+ """ )
def test_regression1_note_with_no_range() -> None: file_info = FileInfo( file_path="dummy.pytch", source_code="""\ let foo = let bar = 3 baz bar """, ) error = Error( file_info=file_info, code=ErrorCode.UNBOUND_NAME, severity=Severity.ERROR, message="I couldn't find a binding...", range=Range( start=Position(line=2, character=2), end=Position(line=2, character=5) ), notes=[ Note(file_info=file_info, message="Did you mean 'map' (a builtin)?"), Note( file_info=file_info, message="Did you mean 'bar', defined here?", range=Range( start=Position(line=1, character=6), end=Position(line=1, character=9), ), ), ], ) lines = lines_to_string(get_error_lines(error, ascii=True)) print(lines) assert ( lines == """\ UNBOUND_NAME[2000] in dummy.pytch, line 3, character 3: Error: I couldn't find a binding... +---------------------------------------------------+ | dummy.pytch | 1 | let foo = | 2 | let bar = 3 | | ^~~ Note: Did you mean 'bar', defined here? | 3 | baz | | ^~~ Error: I couldn't find a binding... | 4 | bar | +---------------------------------------------------+ | Note: Did you mean 'map' (a builtin)? | +---------------------------------------------------+ """ )
def test_print_error() -> None: file_info = FileInfo( file_path="dummy.pytch", source_code="""line1 line2 line3 line4 """, ) error = Error( file_info=file_info, code=ErrorCode.NOT_A_REAL_ERROR, severity=Severity.ERROR, message="Look into this", range=Range( start=Position(line=1, character=3), end=Position(line=2, character=2) ), notes=[ Note( file_info=file_info, message="This is an additional point of interest", range=Range( start=Position(line=0, character=0), end=Position(line=0, character=5), ), ) ], ) lines = lines_to_string(get_error_lines(error, ascii=True)) print(lines) assert ( lines == """\ NOT_A_REAL_ERROR[9001] in dummy.pytch, line 2, character 4: Error: Look into this +-----------------------------------------------------+ | dummy.pytch | 1 | line1 | | ^~~~~ Note: This is an additional point of interest | 2 | line2 | | ^~~~ | 3 | line3 | | ~ Error: Look into this | 4 | line4 | +-----------------------------------------------------+ """ )
def test_fileinfo_get_range_from_offset_range(): source_code = """foo barbaz qux """ file_info = FileInfo(file_path="dummy", source_code=source_code) offset_range = OffsetRange(start=0, end=len(source_code)) range = file_info.get_range_from_offset_range(offset_range) assert range == Range( start=Position(line=0, character=0), end=Position(line=3, character=0) )
def test_binder_error() -> None: file_info = FileInfo( file_path="<stdin>", source_code="""\ let foo = let bar = 3 baz """, ) (syntax_tree, errors) = get_syntax_tree(file_info) assert not errors bindation = bind(file_info=file_info, syntax_tree=syntax_tree, global_scope=GLOBAL_SCOPE) assert bindation.errors == [ Error( file_info=file_info, code=ErrorCode.UNBOUND_NAME, severity=Severity.ERROR, message=("I couldn't find a binding in the current scope " + "with the name 'baz'."), range=Range(start=Position(line=2, character=2), end=Position(line=2, character=5)), notes=[ Note( file_info=file_info, message="Did you mean 'map' (a builtin)?", range=None, ), Note( file_info=file_info, message="Did you mean 'bar', defined here?", range=Range( start=Position(line=1, character=6), end=Position(line=1, character=9), ), ), ], ) ]
def test_regression2() -> None: file_info = FileInfo( file_path="test/typesystem/statement.warning.pytch", source_code="""\ if True then 1 None """, ) error = Error( file_info=file_info, code=ErrorCode.NOT_A_REAL_ERROR, severity=Severity.WARNING, message="The value of this expression is being thrown away, which might indicate a bug.", range=Range( start=Position(line=0, character=0), end=Position(line=3, character=6) ), notes=[], ) lines = lines_to_string(get_error_lines(error, ascii=True)) print(lines) assert ( lines == """\ NOT_A_REAL_ERROR[9001] in test/typesystem/statement.warning.pytch, line 1, character 1: Warning: The value of this expression is being thrown away, which might indicate a bug. +--------------------------------------------------------------------------+ | test/typesystem/statement.warning.pytch | 1 | if True | | ^~~~~~~ | 2 | then | | ~~~~ | 3 | 1 | | ~ | 4 | None | | ~~~~ Warning: The value of this expression is being thrown away, which | | might indicate a bug. | +--------------------------------------------------------------------------+ """ )
def test_wrap_message() -> None: file_info = FileInfo( file_path="dummy.pytch", source_code="""line1 line2 line3 line4 """, ) long_message = ("xxxx " * (80 // len("xxxx "))) + "y." error = Error( file_info=file_info, code=ErrorCode.NOT_A_REAL_ERROR, severity=Severity.ERROR, message=long_message, range=Range( start=Position(line=1, character=3), end=Position(line=2, character=2) ), notes=[], ) lines = lines_to_string(get_error_lines(error, ascii=True)) print(lines) assert ( lines == """\ NOT_A_REAL_ERROR[9001] in dummy.pytch, line 2, character 4: Error: xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx y. +------------------------------------------------------------------------+ | dummy.pytch | 1 | line1 | 2 | line2 | | ^~~~ | 3 | line3 | | ~ Error: xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx | | xxxx xxxx xxxx xxxx y. | 4 | line4 | +------------------------------------------------------------------------+ """ )
def test_get_diagnostic_lines_to_insert() -> None: file_info = FileInfo(file_path="dummy.pytch", source_code="foo\nbar\nbaz\n") error = Error( file_info=file_info, code=ErrorCode.NOT_A_REAL_ERROR, severity=Severity.ERROR, message="An error message", notes=[], range=Range( start=Position(line=1, character=1), end=Position(line=2, character=0) ), ) color = error.color context = _DiagnosticContext(file_info=file_info, line_ranges=[(0, 3)]) assert _get_diagnostic_lines_to_insert( output_env=get_output_env(ascii=True), context=context, diagnostics=[error] ) == { 1: [_MessageLine(text=" ^~", color=color, is_wrappable=False)], 2: [ _MessageLine( text="~ Error: An error message", color=color, is_wrappable=True ) ], }
def test_binding_defs() -> None: file_info = FileInfo( file_path="<stdin>", source_code="""\ def foo(bar) => bar + baz bar """, ) (syntax_tree, errors) = get_syntax_tree(file_info) assert not errors bindation = bind(file_info=file_info, syntax_tree=syntax_tree, global_scope=GLOBAL_SCOPE) [containing_def] = Query(syntax_tree).find_instances(DefExpr) [_, bar_ident_definition] = Query(syntax_tree).find_instances(VariablePattern) [bar_ident_use, _, _] = Query(syntax_tree).find_instances(IdentifierExpr) assert bar_ident_use.t_identifier is not None assert bar_ident_use.t_identifier.text == "bar" assert bindation.get(bar_ident_use) == [bar_ident_definition] assert bindation.errors == [ Error( file_info=file_info, code=ErrorCode.UNBOUND_NAME, severity=Severity.ERROR, message=("I couldn't find a binding in the current scope " + "with the name 'baz'."), range=Range(start=Position(line=1, character=10), end=Position(line=1, character=13)), notes=[ Note( file_info=file_info, message="Did you mean 'map' (a builtin)?", range=None, ), Note( file_info=file_info, message="Did you mean 'bar', defined here?", range=Range( start=Position(line=0, character=8), end=Position(line=0, character=11), ), ), ], ), Error( file_info=file_info, code=ErrorCode.UNBOUND_NAME, severity=Severity.ERROR, message=("I couldn't find a binding in the current scope " + "with the name 'bar'."), range=Range(start=Position(line=2, character=0), end=Position(line=2, character=3)), notes=[ Note( file_info=file_info, message="Did you mean 'map' (a builtin)?", range=None, ) ], ), ]