Skip to content

Commit

Permalink
GD-32: Create test case use configured text ident settings (#35)
Browse files Browse the repository at this point in the history
# Why
A user can change the texteditor setting to use custom ident.
e.i. Tabs vs Spaces

# What
Use the editor settings to format the test function to expected ident,
  • Loading branch information
MikeSchulze authored Nov 13, 2022
1 parent 3faf085 commit 162969c
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 90 deletions.
3 changes: 1 addition & 2 deletions addons/gdUnit4/bin/GdUnitCmdTool.gd
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,12 @@ class CLIRunner extends Node:
var test_suites_to_process = Array()
var to_execute := config.to_execute()
# scan for the requested test suites
var _scanner := _TestSuiteScanner.new()
var _scanner := GdUnitTestSuiteScanner.new()
for resource_path in to_execute.keys():
var selected_tests :Array = to_execute.get(resource_path)
var scaned_suites = _scanner.scan(resource_path)
skip_test_case(scaned_suites, selected_tests)
test_suites_to_process += scaned_suites
_scanner.free()
skip_suites(test_suites_to_process, config)
return test_suites_to_process

Expand Down
3 changes: 1 addition & 2 deletions addons/gdUnit4/src/core/GdUnitRunner.gd
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,12 @@ func load_test_suits() -> Array:
return []
# scan for the requested test suites
var test_suites := Array()
var _scanner := _TestSuiteScanner.new()
var _scanner := GdUnitTestSuiteScanner.new()
for resource_path in to_execute.keys():
var selected_tests :Array[StringName] = to_execute.get(resource_path)
var scaned_suites := _scanner.scan(resource_path)
_filter_test_case(scaned_suites, selected_tests)
test_suites += scaned_suites
_scanner.free()
return test_suites

func gdUnitInit() -> void:
Expand Down
4 changes: 2 additions & 2 deletions addons/gdUnit4/src/core/GdUnitTestSuiteBuilder.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ extends RefCounted


static func create(source :Script, line_number :int) -> Result:
var test_suite_path := _TestSuiteScanner.resolve_test_suite_path(source.resource_path, GdUnitSettings.test_root_folder())
var test_suite_path := GdUnitTestSuiteScanner.resolve_test_suite_path(source.resource_path, GdUnitSettings.test_root_folder())
# we need to save and close the testsuite and source if is current opened before modify
ScriptEditorControls.save_an_open_script(source.resource_path)
ScriptEditorControls.save_an_open_script(test_suite_path, true)
Expand All @@ -17,4 +17,4 @@ static func create(source :Script, line_number :int) -> Result:
var func_name := parser.parse_func_name(current_line)
if func_name.is_empty():
return Result.error("No function found at line: %d." % line_number)
return _TestSuiteScanner.create_test_case(test_suite_path, func_name, source.resource_path)
return GdUnitTestSuiteScanner.create_test_case(test_suite_path, func_name, source.resource_path)
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
class_name _TestSuiteScanner
extends Node
class_name GdUnitTestSuiteScanner
extends RefCounted

const TEST_FUNC_TEMPLATE ="""
func test_${func_name}() -> void:
# remove this line and complete your test
assert_not_yet_implemented()
"""

var _script_parser := GdScriptParser.new()
var _extends_test_suite_classes := Array()


func scan_testsuite_classes() -> void:
# scan and cache extends GdUnitTestSuite by class name an resource paths
_extends_test_suite_classes.append("GdUnitTestSuite")
Expand All @@ -15,6 +22,7 @@ func scan_testsuite_classes() -> void:
if script_meta["base"] == "GdUnitTestSuite":
_extends_test_suite_classes.append(script_meta["class"])


func scan(resource_path :String) -> Array:
scan_testsuite_classes()
# if single testsuite requested
Expand All @@ -28,6 +36,7 @@ func scan(resource_path :String) -> Array:
return []
return _scan_test_suites(base_dir, [])


func _scan_test_suites(dir :DirAccess, collected_suites :Array) -> Array:
prints("Scanning for test suites in:", dir.get_current_dir())
dir.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
Expand All @@ -45,12 +54,14 @@ func _scan_test_suites(dir :DirAccess, collected_suites :Array) -> Array:
file_name = dir.get_next()
return collected_suites


static func _file(dir :DirAccess, file_name :String) -> String:
var current_dir := dir.get_current_dir()
if current_dir.ends_with("/"):
return current_dir + file_name
return current_dir + "/" + file_name


func _parse_is_test_suite(resource_path :String) -> Node:
if not _is_script_format_supported(resource_path):
return null
Expand All @@ -63,12 +74,14 @@ func _parse_is_test_suite(resource_path :String) -> Node:
return _parse_test_suite(script)
return null


static func _is_script_format_supported(resource_path :String) -> bool:
var ext := resource_path.get_extension()
if ext == "gd":
return true
return GdUnit3MonoAPI.is_csharp_file(resource_path)


func _parse_test_suite(script :GDScript) -> GdUnitTestSuite:
var test_suite = script.new()
test_suite.set_name(parse_test_suite_name(script))
Expand All @@ -87,6 +100,7 @@ func _parse_test_suite(script :GDScript) -> GdUnitTestSuite:
base_script = base_script.get_base_script()
return test_suite


func _extract_test_case_names(script :GDScript) -> PackedStringArray:
var names := PackedStringArray()
for method in script.get_script_method_list():
Expand All @@ -97,9 +111,11 @@ func _extract_test_case_names(script :GDScript) -> PackedStringArray:
names.append(funcName)
return names


static func parse_test_suite_name(script :Script) -> String:
return script.resource_path.get_file().replace(".gd", "")


func _parse_and_add_test_cases(test_suite, script :GDScript, test_case_names :PackedStringArray):
var test_cases_to_find = Array(test_case_names)
var source := _script_parser.load_source_code(script, [script.resource_path])
Expand Down Expand Up @@ -138,6 +154,7 @@ func _parse_and_add_test_cases(test_suite, script :GDScript, test_case_names :Pa
test.skip(true, error)
test.set_test_parameters(test_paramaters)


# converts given file name by configured naming convention
static func _to_naming_convention(file_name :String) -> String:
var nc :int = GdUnitSettings.get_setting(GdUnitSettings.TEST_SITE_NAMING_CONVENTION, 0)
Expand All @@ -153,6 +170,7 @@ static func _to_naming_convention(file_name :String) -> String:
push_error("Unexpected case")
return "-<Unexpected>-"


static func resolve_test_suite_path(source_script_path :String, test_root_folder :String = "test") -> String:
var file_extension := source_script_path.get_extension()
var file_name = source_script_path.get_basename().get_file()
Expand Down Expand Up @@ -183,6 +201,7 @@ static func resolve_test_suite_path(source_script_path :String, test_root_folder
test_suite_path += "/" + paths[index]
return test_suite_path.replace(file_name, suite_name)


static func create_test_suite(test_suite_path :String, source_path :String) -> Result:
# create directory if not exists
if not DirAccess.dir_exists_absolute(test_suite_path.get_base_dir()):
Expand All @@ -197,6 +216,7 @@ static func create_test_suite(test_suite_path :String, source_path :String) -> R
return Result.error("Can't create test suite at: %s. Error code %s" % [test_suite_path, error])
return Result.success(test_suite_path)


static func get_test_case_line_number(resource_path :String, func_name :String) -> int:
var file := FileAccess.open(resource_path, FileAccess.READ)
if file != null:
Expand All @@ -218,13 +238,16 @@ static func add_test_case(resource_path :String, func_name :String) -> Result:
var script := load(resource_path) as GDScript
# count all exiting lines and add two as space to add new test case
var line_number := count_lines(script) + 2
script.source_code +=\
"""
func test_${func_name}() -> void:
# remove this line and complete your test
assert_not_yet_implemented()
""".replace("${func_name}", func_name)
var func_body := TEST_FUNC_TEMPLATE.replace("${func_name}", func_name)
if Engine.is_editor_hint():
var ep := EditorPlugin.new()
var settings := ep.get_editor_interface().get_editor_settings()
ep.free()
var ident_type :int = settings.get_setting("text_editor/behavior/indent/type")
var ident_size :int = settings.get_setting("text_editor/behavior/indent/size")
if ident_type == 1:
func_body = func_body.replace(" ", "".lpad(ident_size, " "))
script.source_code += func_body
var error := ResourceSaver.save(script, resource_path)
if error != OK:
return Result.error("Can't add test case at: %s to '%s'. Error code %s" % [func_name, resource_path, error])
Expand Down
14 changes: 6 additions & 8 deletions addons/gdUnit4/test/GdUnitTestResourceLoader.gd
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,10 @@ static func load_test_suite_gd(resource_path :String) -> GdUnitTestSuite:
var test_suite :GdUnitTestSuite = script.new()
test_suite.set_name(new_resource_path.get_file().replace(".gd", ""))
# complete test suite wiht parsed test cases
var suite_parser := _TestSuiteScanner.new()
var test_case_names := suite_parser._extract_test_case_names(script)
var suite_scanner := GdUnitTestSuiteScanner.new()
var test_case_names := suite_scanner._extract_test_case_names(script)
# add test cases to test suite and parse test case line nummber
suite_parser._parse_and_add_test_cases(test_suite, script, test_case_names)
suite_parser.free()
suite_scanner._parse_and_add_test_cases(test_suite, script, test_case_names)
GdUnitTools.delete_directory("res://addons/gdUnit4/.tmp")
return test_suite

Expand All @@ -43,12 +42,11 @@ static func load_test_suite_gd_(resource_path :String) -> GdUnitTestSuite:
var test_suite :GdUnitTestSuite = script.new()
test_suite.set_name(resource_path.get_file().replace(".resource", "").replace(".gd", ""))
# complete test suite wiht parsed test cases
var suite_parser := _TestSuiteScanner.new()
var test_case_names := suite_parser._extract_test_case_names(script)
var suite_scanner := GdUnitTestSuiteScanner.new()
var test_case_names := suite_scanner._extract_test_case_names(script)
# add test cases to test suite and parse test case line nummber
script.resource_path = resource_path
suite_parser._parse_and_add_test_cases(test_suite, script, test_case_names)
suite_parser.free()
suite_scanner._parse_and_add_test_cases(test_suite, script, test_case_names)
return test_suite


Expand Down
Loading

0 comments on commit 162969c

Please sign in to comment.