From 8866d4a333f42f8d6eab1483735c132e4afb19be Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 24 Mar 2023 20:51:56 -0700 Subject: [PATCH] Bring Python formatting into Black code style compliance The Black code formatter tool is now used for formatting of the project's Python code. There are some differences between the standard Black code style and the previous code style used in the project. --- compilesketches/compilesketches.py | 489 ++-- compilesketches/tests/test_compilesketches.py | 2292 ++++++++++------- 2 files changed, 1551 insertions(+), 1230 deletions(-) diff --git a/compilesketches/compilesketches.py b/compilesketches/compilesketches.py index a9ec404..e1dee5f 100644 --- a/compilesketches/compilesketches.py +++ b/compilesketches/compilesketches.py @@ -27,18 +27,24 @@ def main(): print("::warning::The size-report-sketch input is no longer used") if "INPUT_SIZE-DELTAS-REPORT-FOLDER-NAME" in os.environ: - print("::warning::The size-deltas-report-folder-name input is deprecated. Use the equivalent input: " - "sketches-report-path instead.") + print( + "::warning::The size-deltas-report-folder-name input is deprecated. Use the equivalent input: " + "sketches-report-path instead." + ) os.environ["INPUT_SKETCHES-REPORT-PATH"] = os.environ["INPUT_SIZE-DELTAS-REPORT-FOLDER-NAME"] if "INPUT_ENABLE-SIZE-DELTAS-REPORT" in os.environ: - print("::warning::The enable-size-deltas-report input is deprecated. Use the equivalent input: " - "enable-deltas-report instead.") + print( + "::warning::The enable-size-deltas-report input is deprecated. Use the equivalent input: " + "enable-deltas-report instead." + ) os.environ["INPUT_ENABLE-DELTAS-REPORT"] = os.environ["INPUT_ENABLE-SIZE-DELTAS-REPORT"] if "INPUT_ENABLE-SIZE-TRENDS-REPORT" in os.environ: - print("::warning::The size trends report feature has been moved to a dedicated action. See the documentation " - "at https://github.com/arduino/actions/tree/report-size-trends-action/libraries/report-size-trends") + print( + "::warning::The size trends report feature has been moved to a dedicated action. See the documentation " + "at https://github.com/arduino/actions/tree/report-size-trends-action/libraries/report-size-trends" + ) compile_sketches = CompileSketches( cli_version=os.environ["INPUT_CLI-VERSION"], @@ -51,7 +57,7 @@ def main(): github_token=os.environ["INPUT_GITHUB-TOKEN"], enable_deltas_report=os.environ["INPUT_ENABLE-DELTAS-REPORT"], enable_warnings_report=os.environ["INPUT_ENABLE-WARNINGS-REPORT"], - sketches_report_path=os.environ["INPUT_SKETCHES-REPORT-PATH"] + sketches_report_path=os.environ["INPUT_SKETCHES-REPORT-PATH"], ) compile_sketches.compile_sketches() @@ -120,8 +126,20 @@ class ReportKeys: latest_release_indicator = "latest" - def __init__(self, cli_version, fqbn_arg, platforms, libraries, sketch_paths, cli_compile_flags, verbose, - github_token, enable_deltas_report, enable_warnings_report, sketches_report_path): + def __init__( + self, + cli_version, + fqbn_arg, + platforms, + libraries, + sketch_paths, + cli_compile_flags, + verbose, + github_token, + enable_deltas_report, + enable_warnings_report, + sketches_report_path, + ): """Process, store, and validate the action's inputs.""" self.cli_version = cli_version @@ -185,8 +203,10 @@ def get_pull_request_base_ref(self): try: repository_api = self.github_api.get_repo(full_name_or_id=os.environ["GITHUB_REPOSITORY"]) except github.UnknownObjectException: - print("::error::Unable to access repository data. Please specify the github-token input in your " - "workflow configuration.") + print( + "::error::Unable to access repository data. Please specify the github-token input in your " + "workflow configuration." + ) sys.exit(1) return repository_api.get_pull(number=pull_request_number).base.ref @@ -235,7 +255,7 @@ def install_arduino_cli(self): # The Arduino CLI has no root folder, so just install the arduino-cli executable from the archive root source_path="arduino-cli", destination_parent_path=self.arduino_cli_installation_path, - force=False + force=False, ) # Configure the location of the Arduino CLI user directory @@ -289,10 +309,12 @@ def install_from_download(self, url, source_path, destination_parent_path, desti print("::error::Archive source path:", source_path, "not found") sys.exit(1) - self.install_from_path(source_path=absolute_source_path, - destination_parent_path=destination_parent_path, - destination_name=destination_name, - force=force) + self.install_from_path( + source_path=absolute_source_path, + destination_parent_path=destination_parent_path, + destination_name=destination_name, + force=force, + ) def install_platforms(self): """Install Arduino boards platforms.""" @@ -338,14 +360,14 @@ def sort_dependency_list(self, dependency_list): if dependency is not None: if self.dependency_source_url_key in dependency: # Repositories are identified by the URL starting with git:// or ending in .git - if ( - dependency[self.dependency_source_url_key].rstrip("/").endswith(".git") - or dependency[self.dependency_source_url_key].startswith("git://") - ): + if dependency[self.dependency_source_url_key].rstrip("/").endswith(".git") or dependency[ + self.dependency_source_url_key + ].startswith("git://"): sorted_dependencies.repository.append(dependency) - elif re.match( - pattern=".*/package_.*index.json", string=dependency[self.dependency_source_url_key] - ) is not None: + elif ( + re.match(pattern=".*/package_.*index.json", string=dependency[self.dependency_source_url_key]) + is not None + ): # URLs that match the filename requirements of the package_index.json specification are assumed # to be additional Board Manager URLs (platform index) sorted_dependencies.manager.append(dependency) @@ -391,12 +413,14 @@ def install_platforms_from_board_manager(self, platform_list): core_install_command.append(self.get_manager_dependency_name(platform)) # Download the platform index for the platform - self.run_arduino_cli_command(command=core_update_index_command, - enable_output=self.get_run_command_output_level()) + self.run_arduino_cli_command( + command=core_update_index_command, enable_output=self.get_run_command_output_level() + ) # Install the platform - self.run_arduino_cli_command(command=core_install_command, - enable_output=self.get_run_command_output_level()) + self.run_arduino_cli_command( + command=core_install_command, enable_output=self.get_run_command_output_level() + ) def get_manager_dependency_name(self, dependency): """Return the appropriate name value for a manager dependency. This allows the NAME@VERSION syntax to be used @@ -438,9 +462,9 @@ def run_arduino_cli_command(self, command, enable_output=RunCommandOutput.ON_FAI full_command.extend(command) if self.verbose: full_command.extend(["--log-level", debug_output_log_level, "--verbose"]) - arduino_cli_output = self.run_command(command=full_command, - enable_output=enable_output, - exit_on_failure=exit_on_failure) + arduino_cli_output = self.run_command( + command=full_command, enable_output=enable_output, exit_on_failure=exit_on_failure + ) return arduino_cli_output @@ -458,15 +482,19 @@ def run_command(self, command, enable_output=RunCommandOutput.ON_FAILURE, exit_o command_data = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) # Print output if appropriate - if (enable_output == self.RunCommandOutput.ALWAYS - or (command_data.returncode != 0 - and (enable_output == self.RunCommandOutput.ON_FAILURE - or enable_output == self.RunCommandOutput.ALWAYS))): - + if enable_output == self.RunCommandOutput.ALWAYS or ( + command_data.returncode != 0 + and (enable_output == self.RunCommandOutput.ON_FAILURE or enable_output == self.RunCommandOutput.ALWAYS) + ): # Cast args to string and join them to form a string - print("::group::Running command:", list_to_string(command_data.args), "\n", - command_data.stdout, "\n", - "::endgroup::") + print( + "::group::Running command:", + list_to_string(command_data.args), + "\n", + command_data.stdout, + "\n", + "::endgroup::", + ) if command_data.returncode != 0: print("::error::Command failed") @@ -494,10 +522,12 @@ def install_platforms_from_path(self, platform_list): platform_installation_path = self.get_platform_installation_path(platform=platform) # Install the platform - self.install_from_path(source_path=source_path, - destination_parent_path=platform_installation_path.path.parent, - destination_name=platform_installation_path.path.name, - force=platform_installation_path.is_overwrite) + self.install_from_path( + source_path=source_path, + destination_parent_path=platform_installation_path.path.parent, + destination_name=platform_installation_path.path.name, + force=platform_installation_path.is_overwrite, + ) def get_platform_installation_path(self, platform): """Determines the correct installation path for the given platform and returns an object with the attributes: @@ -532,13 +562,11 @@ def __init__(self): for installed_platform in installed_platform_list: if installed_platform[self.cli_json_key("core list", "ID")] == platform[self.dependency_name_key]: # The platform has been installed via Board Manager, so do an overwrite - platform_installation_path.path = ( - self.board_manager_platforms_path.joinpath( - platform_vendor, - "hardware", - platform_architecture, - installed_platform[self.cli_json_key("core list", "Installed")] - ) + platform_installation_path.path = self.board_manager_platforms_path.joinpath( + platform_vendor, + "hardware", + platform_architecture, + installed_platform[self.cli_json_key("core list", "Installed")], ) platform_installation_path.is_overwrite = True @@ -600,12 +628,14 @@ def install_platforms_from_repository(self, platform_list): destination_path = self.get_platform_installation_path(platform=platform) - self.install_from_repository(url=platform[self.dependency_source_url_key], - git_ref=git_ref, - source_path=source_path, - destination_parent_path=destination_path.path.parent, - destination_name=destination_path.path.name, - force=destination_path.is_overwrite) + self.install_from_repository( + url=platform[self.dependency_source_url_key], + git_ref=git_ref, + source_path=source_path, + destination_parent_path=destination_path.path.parent, + destination_name=destination_path.path.name, + force=destination_path.is_overwrite, + ) def get_repository_dependency_ref(self, dependency): """Return the appropriate git ref value for a repository dependency @@ -620,13 +650,9 @@ def get_repository_dependency_ref(self, dependency): return git_ref - def install_from_repository(self, - url, - git_ref, - source_path, - destination_parent_path, - destination_name=None, - force=False): + def install_from_repository( + self, url, git_ref, source_path, destination_parent_path, destination_name=None, force=False + ): """Install by cloning a repository Keyword arguments: @@ -646,10 +672,12 @@ def install_from_repository(self, clone_folder = tempfile.mkdtemp(dir=self.temporary_directory.name, prefix="install_from_repository-") self.clone_repository(url=url, git_ref=git_ref, destination_path=clone_folder) # Install to the final location - self.install_from_path(source_path=pathlib.Path(clone_folder, source_path), - destination_parent_path=destination_parent_path, - destination_name=destination_name, - force=force) + self.install_from_path( + source_path=pathlib.Path(clone_folder, source_path), + destination_parent_path=destination_parent_path, + destination_name=destination_name, + force=force, + ) def clone_repository(self, url, git_ref, destination_path): """Clone a Git repository to a specified location and check out the specified ref @@ -695,11 +723,13 @@ def install_platforms_from_download(self, platform_list): destination_path = self.get_platform_installation_path(platform=platform) - self.install_from_download(url=platform[self.dependency_source_url_key], - source_path=source_path, - destination_parent_path=destination_path.path.parent, - destination_name=destination_path.path.name, - force=destination_path.is_overwrite) + self.install_from_download( + url=platform[self.dependency_source_url_key], + source_path=source_path, + destination_parent_path=destination_path.path.parent, + destination_name=destination_path.path.name, + force=destination_path.is_overwrite, + ) def install_libraries(self): """Install Arduino libraries.""" @@ -711,8 +741,7 @@ def install_libraries(self): library_list = self.sort_dependency_list(libraries.value) else: # libraries input uses the old space-separated list syntax - library_list.manager = [{self.dependency_name_key: library_name} - for library_name in libraries.value] + library_list.manager = [{self.dependency_name_key: library_name} for library_name in libraries.value] # The original behavior of the action was to assume the root of the repo is a library to be installed, so # that behavior is retained when using the old input syntax @@ -767,9 +796,7 @@ def install_libraries_from_path(self, library_list): if self.dependency_destination_name_key in library: # If a name was specified, use it destination_name = library[self.dependency_destination_name_key] - elif ( - source_path == absolute_path(os.environ["GITHUB_WORKSPACE"]) - ): + elif source_path == absolute_path(os.environ["GITHUB_WORKSPACE"]): # If source_path is the root of the workspace (i.e., repository root), name the folder according to the # repository name, otherwise it will unexpectedly be "workspace" destination_name = os.environ["GITHUB_REPOSITORY"].split(sep="/")[1] @@ -777,10 +804,12 @@ def install_libraries_from_path(self, library_list): # Use the existing folder name destination_name = None - self.install_from_path(source_path=source_path, - destination_parent_path=self.libraries_path, - destination_name=destination_name, - force=True) + self.install_from_path( + source_path=source_path, + destination_parent_path=self.libraries_path, + destination_name=destination_name, + force=True, + ) def install_libraries_from_repository(self, library_list): """Install libraries by cloning Git repositories @@ -806,12 +835,14 @@ def install_libraries_from_repository(self, library_list): else: source_path = "." - self.install_from_repository(url=library[self.dependency_source_url_key], - git_ref=git_ref, - source_path=source_path, - destination_parent_path=self.libraries_path, - destination_name=destination_name, - force=True) + self.install_from_repository( + url=library[self.dependency_source_url_key], + git_ref=git_ref, + source_path=source_path, + destination_parent_path=self.libraries_path, + destination_name=destination_name, + force=True, + ) def install_libraries_from_download(self, library_list): """Install libraries by downloading them @@ -831,11 +862,13 @@ def install_libraries_from_download(self, library_list): else: destination_name = None - self.install_from_download(url=library[self.dependency_source_url_key], - source_path=source_path, - destination_parent_path=self.libraries_path, - destination_name=destination_name, - force=True) + self.install_from_download( + url=library[self.dependency_source_url_key], + source_path=source_path, + destination_parent_path=self.libraries_path, + destination_name=destination_name, + force=True, + ) def find_sketches(self): """Return a list of all sketches under the paths specified in the sketch paths list recursively.""" @@ -896,7 +929,8 @@ def compile_sketch(self, sketch_path, clean_build_cache): shutil.rmtree(path=cache_path) start_time = time.monotonic() compilation_data = self.run_arduino_cli_command( - command=compilation_command, enable_output=self.RunCommandOutput.NONE, exit_on_failure=False) + command=compilation_command, enable_output=self.RunCommandOutput.NONE, exit_on_failure=False + ) diff_time = time.monotonic() - start_time # Group compilation output to make the log easy to read @@ -936,9 +970,9 @@ def get_sketch_report(self, compilation_result): current_warning_count = None previous_sizes = None previous_warning_count = None - if self.do_deltas_report(compilation_result=compilation_result, - current_sizes=current_sizes, - current_warnings=current_warning_count): + if self.do_deltas_report( + compilation_result=compilation_result, current_sizes=current_sizes, current_warnings=current_warning_count + ): # Get data for the sketch at the base ref # Get the head ref repository = git.Repo(path=os.environ["GITHUB_WORKSPACE"]) @@ -949,29 +983,28 @@ def get_sketch_report(self, compilation_result): # Compile the sketch again print("Compiling previous version of sketch to determine memory usage change") - previous_compilation_result = self.compile_sketch(sketch_path=compilation_result.sketch, - clean_build_cache=self.enable_warnings_report) + previous_compilation_result = self.compile_sketch( + sketch_path=compilation_result.sketch, clean_build_cache=self.enable_warnings_report + ) # git checkout the head ref to return the repository to its previous state repository.git.checkout(original_git_ref, recurse_submodules=True) previous_sizes = self.get_sizes_from_output(compilation_result=previous_compilation_result) if self.enable_warnings_report: - previous_warning_count = ( - self.get_warning_count_from_output(compilation_result=previous_compilation_result) + previous_warning_count = self.get_warning_count_from_output( + compilation_result=previous_compilation_result ) # Add global data for sketch to report sketch_report = { self.ReportKeys.name: str(path_relative_to_workspace(path=compilation_result.sketch)), self.ReportKeys.compilation_success: compilation_result.success, - self.ReportKeys.sizes: self.get_sizes_report(current_sizes=current_sizes, - previous_sizes=previous_sizes), + self.ReportKeys.sizes: self.get_sizes_report(current_sizes=current_sizes, previous_sizes=previous_sizes), } if self.enable_warnings_report: - sketch_report[self.ReportKeys.warnings] = ( - self.get_warnings_report(current_warnings=current_warning_count, - previous_warnings=previous_warning_count) + sketch_report[self.ReportKeys.warnings] = self.get_warnings_report( + current_warnings=current_warning_count, previous_warnings=previous_warning_count ) return sketch_report @@ -992,8 +1025,8 @@ def get_sizes_from_output(self, compilation_result): # The regular expression for the total memory self.ReportKeys.maximum: ( r"Sketch uses [0-9]+ bytes .*of program storage space\. Maximum is ([0-9]+) bytes." - ) - } + ), + }, }, { "name": "RAM for global variables", @@ -1001,9 +1034,9 @@ def get_sizes_from_output(self, compilation_result): self.ReportKeys.absolute: r"Global variables use ([0-9]+) bytes .*of dynamic memory", self.ReportKeys.maximum: ( r"Global variables use [0-9]+ bytes .*of dynamic memory.*\. Maximum is ([0-9]+) bytes." - ) - } - } + ), + }, + }, ] sizes = [] @@ -1013,26 +1046,30 @@ def get_sizes_from_output(self, compilation_result): # Set default memory usage value, to be used if memory usage can't be determined self.ReportKeys.absolute: self.not_applicable_indicator, self.ReportKeys.maximum: self.not_applicable_indicator, - self.ReportKeys.relative: self.not_applicable_indicator + self.ReportKeys.relative: self.not_applicable_indicator, } if compilation_result.success is True: # Determine memory usage of the sketch by parsing Arduino CLI's output - size_data = self.get_size_data_from_output(compilation_output=compilation_result.output, - memory_type=memory_type, - size_data_type=self.ReportKeys.absolute) + size_data = self.get_size_data_from_output( + compilation_output=compilation_result.output, + memory_type=memory_type, + size_data_type=self.ReportKeys.absolute, + ) if size_data: size[self.ReportKeys.absolute] = size_data - size_data = self.get_size_data_from_output(compilation_output=compilation_result.output, - memory_type=memory_type, - size_data_type=self.ReportKeys.maximum) + size_data = self.get_size_data_from_output( + compilation_output=compilation_result.output, + memory_type=memory_type, + size_data_type=self.ReportKeys.maximum, + ) if size_data: size[self.ReportKeys.maximum] = size_data size[self.ReportKeys.relative] = round( (100 * size[self.ReportKeys.absolute] / size[self.ReportKeys.maximum]), - self.relative_size_report_decimal_places + self.relative_size_report_decimal_places, ) sizes.append(size) @@ -1062,7 +1099,9 @@ def get_size_data_from_output(self, compilation_output, memory_type, size_data_t # - upload.maximum_size is not defined in boards.txt # RAM usage will not be reported in the Arduino CLI output self.verbose_print( - "::warning::Unable to determine the: \"" + size_data_type + "\" value for memory type: \"" + '::warning::Unable to determine the: "' + + size_data_type + + '" value for memory type: "' + memory_type["name"] + "\". The board's platform may not have been configured to provide this information." ) @@ -1096,12 +1135,8 @@ def do_deltas_report(self, compilation_result, current_sizes, current_warnings): self.enable_deltas_report and compilation_result.success and ( - any(size.get(self.ReportKeys.absolute) != self.not_applicable_indicator for - size in current_sizes) - or ( - current_warnings is not None - and current_warnings != self.not_applicable_indicator - ) + any(size.get(self.ReportKeys.absolute) != self.not_applicable_indicator for size in current_sizes) + or (current_warnings is not None and current_warnings != self.not_applicable_indicator) ) ) @@ -1111,12 +1146,14 @@ def checkout_deltas_base_ref(self): # git fetch the deltas base ref origin_remote = repository.remotes["origin"] - origin_remote.fetch(refspec=self.deltas_base_ref, - verbose=self.verbose, - no_tags=True, - prune=True, - depth=1, - recurse_submodules=True) + origin_remote.fetch( + refspec=self.deltas_base_ref, + verbose=self.verbose, + no_tags=True, + prune=True, + depth=1, + recurse_submodules=True, + ) # git checkout the deltas base ref repository.git.checkout(self.deltas_base_ref, recurse_submodules=True) @@ -1135,8 +1172,7 @@ def get_sizes_report(self, current_sizes, previous_sizes): sizes_report = [] for current_size, previous_size in zip(current_sizes, previous_sizes): - sizes_report.append(self.get_size_report(current_size=current_size, - previous_size=previous_size)) + sizes_report.append(self.get_size_report(current_size=current_size, previous_size=previous_size)) return sizes_report @@ -1153,8 +1189,8 @@ def get_size_report(self, current_size, previous_size): self.ReportKeys.maximum: current_size[self.ReportKeys.maximum], self.ReportKeys.current: { self.ReportKeys.absolute: current_size[self.ReportKeys.absolute], - self.ReportKeys.relative: current_size[self.ReportKeys.relative] - } + self.ReportKeys.relative: current_size[self.ReportKeys.relative], + }, } if previous_size is not None: @@ -1165,7 +1201,7 @@ def get_size_report(self, current_size, previous_size): ): absolute_delta = self.not_applicable_indicator else: - absolute_delta = (current_size[self.ReportKeys.absolute] - previous_size[self.ReportKeys.absolute]) + absolute_delta = current_size[self.ReportKeys.absolute] - previous_size[self.ReportKeys.absolute] if ( absolute_delta == self.not_applicable_indicator @@ -1174,8 +1210,10 @@ def get_size_report(self, current_size, previous_size): relative_delta = self.not_applicable_indicator else: # Calculate from absolute values to avoid rounding errors - relative_delta = round((100 * absolute_delta / size_report[self.ReportKeys.maximum]), - self.relative_size_report_decimal_places) + relative_delta = round( + (100 * absolute_delta / size_report[self.ReportKeys.maximum]), + self.relative_size_report_decimal_places, + ) # Size deltas reports are enabled # Print the memory usage change data to the log @@ -1186,11 +1224,11 @@ def get_size_report(self, current_size, previous_size): size_report[self.ReportKeys.previous] = { self.ReportKeys.absolute: previous_size[self.ReportKeys.absolute], - self.ReportKeys.relative: previous_size[self.ReportKeys.relative] + self.ReportKeys.relative: previous_size[self.ReportKeys.relative], } size_report[self.ReportKeys.delta] = { self.ReportKeys.absolute: absolute_delta, - self.ReportKeys.relative: relative_delta + self.ReportKeys.relative: relative_delta, } return size_report @@ -1211,10 +1249,7 @@ def get_warnings_report(self, current_warnings, previous_warnings): if previous_warnings is not None: # Deltas reports are enabled # Calculate the change in the warnings count - if ( - current_warnings == self.not_applicable_indicator - or previous_warnings == self.not_applicable_indicator - ): + if current_warnings == self.not_applicable_indicator or previous_warnings == self.not_applicable_indicator: warnings_delta = self.not_applicable_indicator else: warnings_delta = current_warnings - previous_warnings @@ -1222,12 +1257,8 @@ def get_warnings_report(self, current_warnings, previous_warnings): # Print the warning count change to the log print("Change in compiler warning count:", warnings_delta) - warnings_report[self.ReportKeys.previous] = { - self.ReportKeys.absolute: previous_warnings - } - warnings_report[self.ReportKeys.delta] = { - self.ReportKeys.absolute: warnings_delta - } + warnings_report[self.ReportKeys.previous] = {self.ReportKeys.absolute: previous_warnings} + warnings_report[self.ReportKeys.delta] = {self.ReportKeys.absolute: warnings_delta} return warnings_report @@ -1241,19 +1272,13 @@ def get_sketches_report(self, sketch_report_list): sketches_report = { self.ReportKeys.commit_hash: current_git_ref, - self.ReportKeys.commit_url: ("https://github.com/" - + os.environ["GITHUB_REPOSITORY"] - + "/commit/" - + current_git_ref), + self.ReportKeys.commit_url: ( + "https://github.com/" + os.environ["GITHUB_REPOSITORY"] + "/commit/" + current_git_ref + ), # The action is currently designed to only compile for one board per run, so the boards list will only have # a single element, but this provides a report format that can accommodate the possible addition of multiple # boards support - self.ReportKeys.boards: [ - { - self.ReportKeys.board: self.fqbn, - self.ReportKeys.sketches: sketch_report_list - } - ] + self.ReportKeys.boards: [{self.ReportKeys.board: self.fqbn, self.ReportKeys.sketches: sketch_report_list}], } sizes_summary_report = self.get_sizes_summary_report(sketch_report_list=sketch_report_list) @@ -1278,7 +1303,8 @@ def get_sizes_summary_report(self, sketch_report_list): if self.ReportKeys.delta in size_report: # Determine the sizes_summary_report index for this memory type size_summary_report_index_list = [ - index for index, size_summary in enumerate(sizes_summary_report) + index + for index, size_summary in enumerate(sizes_summary_report) if size_summary.get(self.ReportKeys.name) == size_report[self.ReportKeys.name] ] if not size_summary_report_index_list: @@ -1290,77 +1316,94 @@ def get_sizes_summary_report(self, sketch_report_list): self.ReportKeys.delta: { self.ReportKeys.absolute: { self.ReportKeys.minimum: size_report[self.ReportKeys.delta][ - self.ReportKeys.absolute], + self.ReportKeys.absolute + ], self.ReportKeys.maximum: size_report[self.ReportKeys.delta][ - self.ReportKeys.absolute] + self.ReportKeys.absolute + ], }, self.ReportKeys.relative: { self.ReportKeys.minimum: size_report[self.ReportKeys.delta][ - self.ReportKeys.relative], + self.ReportKeys.relative + ], self.ReportKeys.maximum: size_report[self.ReportKeys.delta][ - self.ReportKeys.relative] + self.ReportKeys.relative + ], }, - } + }, } ) else: size_summary_report_index = size_summary_report_index_list[0] if ( - sizes_summary_report[size_summary_report_index][ - self.ReportKeys.maximum] == self.not_applicable_indicator + sizes_summary_report[size_summary_report_index][self.ReportKeys.maximum] + == self.not_applicable_indicator ): - sizes_summary_report[size_summary_report_index][ - self.ReportKeys.maximum] = size_report[self.ReportKeys.maximum] + sizes_summary_report[size_summary_report_index][self.ReportKeys.maximum] = size_report[ + self.ReportKeys.maximum + ] if ( sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ - self.ReportKeys.absolute][self.ReportKeys.minimum] == self.not_applicable_indicator + self.ReportKeys.absolute + ][self.ReportKeys.minimum] + == self.not_applicable_indicator ): sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ - self.ReportKeys.absolute][self.ReportKeys.minimum] = size_report[self.ReportKeys.delta][ - self.ReportKeys.absolute] + self.ReportKeys.absolute + ][self.ReportKeys.minimum] = size_report[self.ReportKeys.delta][self.ReportKeys.absolute] sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ - self.ReportKeys.relative][self.ReportKeys.minimum] = size_report[self.ReportKeys.delta][ - self.ReportKeys.relative] + self.ReportKeys.relative + ][self.ReportKeys.minimum] = size_report[self.ReportKeys.delta][self.ReportKeys.relative] sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ - self.ReportKeys.absolute][self.ReportKeys.maximum] = size_report[self.ReportKeys.delta][ - self.ReportKeys.absolute] + self.ReportKeys.absolute + ][self.ReportKeys.maximum] = size_report[self.ReportKeys.delta][self.ReportKeys.absolute] sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ - self.ReportKeys.relative][self.ReportKeys.maximum] = size_report[self.ReportKeys.delta][ - self.ReportKeys.relative] + self.ReportKeys.relative + ][self.ReportKeys.maximum] = size_report[self.ReportKeys.delta][self.ReportKeys.relative] elif size_report[self.ReportKeys.delta][self.ReportKeys.absolute] != ( self.not_applicable_indicator ): - if (size_report[self.ReportKeys.delta][self.ReportKeys.absolute] + if ( + size_report[self.ReportKeys.delta][self.ReportKeys.absolute] < sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ - self.ReportKeys.absolute][self.ReportKeys.minimum]): + self.ReportKeys.absolute + ][self.ReportKeys.minimum] + ): sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ - self.ReportKeys.absolute][self.ReportKeys.minimum] = ( - size_report[self.ReportKeys.delta][self.ReportKeys.absolute] - ) + self.ReportKeys.absolute + ][self.ReportKeys.minimum] = size_report[self.ReportKeys.delta][ + self.ReportKeys.absolute + ] sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ - self.ReportKeys.relative][self.ReportKeys.minimum] = ( - size_report[self.ReportKeys.delta][self.ReportKeys.relative] - ) + self.ReportKeys.relative + ][self.ReportKeys.minimum] = size_report[self.ReportKeys.delta][ + self.ReportKeys.relative + ] - if (size_report[self.ReportKeys.delta][self.ReportKeys.absolute] + if ( + size_report[self.ReportKeys.delta][self.ReportKeys.absolute] > sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ - self.ReportKeys.absolute][self.ReportKeys.maximum]): + self.ReportKeys.absolute + ][self.ReportKeys.maximum] + ): sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ - self.ReportKeys.absolute][self.ReportKeys.maximum] = ( - size_report[self.ReportKeys.delta][self.ReportKeys.absolute] - ) + self.ReportKeys.absolute + ][self.ReportKeys.maximum] = size_report[self.ReportKeys.delta][ + self.ReportKeys.absolute + ] sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ - self.ReportKeys.relative][self.ReportKeys.maximum] = ( - size_report[self.ReportKeys.delta][self.ReportKeys.relative] - ) + self.ReportKeys.relative + ][self.ReportKeys.maximum] = size_report[self.ReportKeys.delta][ + self.ReportKeys.relative + ] return sizes_summary_report @@ -1377,14 +1420,11 @@ def get_warnings_summary_report(self, sketch_report_list): self.ReportKeys.warnings in sketch_report and self.ReportKeys.delta in sketch_report[self.ReportKeys.warnings] ): - sketch_report_delta = ( - sketch_report[self.ReportKeys.warnings][self.ReportKeys.delta][self.ReportKeys.absolute] - ) + sketch_report_delta = sketch_report[self.ReportKeys.warnings][self.ReportKeys.delta][ + self.ReportKeys.absolute + ] - if ( - summary_report_minimum is None - or summary_report_minimum == self.not_applicable_indicator - ): + if summary_report_minimum is None or summary_report_minimum == self.not_applicable_indicator: summary_report_minimum = sketch_report_delta elif ( sketch_report_delta != self.not_applicable_indicator @@ -1392,10 +1432,7 @@ def get_warnings_summary_report(self, sketch_report_list): ): summary_report_minimum = sketch_report_delta - if ( - summary_report_maximum is None - or summary_report_maximum == self.not_applicable_indicator - ): + if summary_report_maximum is None or summary_report_maximum == self.not_applicable_indicator: summary_report_maximum = sketch_report_delta elif ( sketch_report_delta != self.not_applicable_indicator @@ -1408,7 +1445,7 @@ def get_warnings_summary_report(self, sketch_report_list): self.ReportKeys.delta: { self.ReportKeys.absolute: { self.ReportKeys.minimum: summary_report_minimum, - self.ReportKeys.maximum: summary_report_maximum + self.ReportKeys.maximum: summary_report_maximum, } } } @@ -1431,8 +1468,9 @@ def create_sketches_report_file(self, sketches_report): sketches_report_path.mkdir(parents=True, exist_ok=True) # Write the memory usage data to a file named according to the FQBN - with open(file=sketches_report_path.joinpath(self.fqbn.replace(":", "-") + ".json"), mode="w", - encoding="utf-8") as report_file: + with open( + file=sketches_report_path.joinpath(self.fqbn.replace(":", "-") + ".json"), mode="w", encoding="utf-8" + ) as report_file: json.dump(obj=sketches_report, fp=report_file, indent=2) def cli_json_key(self, command, original_key_name): @@ -1453,13 +1491,9 @@ def cli_json_key(self, command, original_key_name): "websiteURL": "website_url", "archiveFileName": "archive_filename", "propertiesId": "properties_id", - "toolsDependencies": "tools_dependencies" - }, - "board list": { - "FQBN": "fqbn", - "VID": "vid", - "PID": "pid" + "toolsDependencies": "tools_dependencies", }, + "board list": {"FQBN": "fqbn", "VID": "vid", "PID": "pid"}, "board listall": { "FQBN": "fqbn", "Email": "email", @@ -1468,7 +1502,7 @@ def cli_json_key(self, command, original_key_name): "Latest": "latest", "Name": "name", "Maintainer": "maintainer", - "Website": "website" + "Website": "website", }, "board search": { "FQBN": "fqbn", @@ -1478,7 +1512,7 @@ def cli_json_key(self, command, original_key_name): "Latest": "latest", "Name": "name", "Maintainer": "maintainer", - "Website": "website" + "Website": "website", }, "core list": { "Boards": "boards", @@ -1488,7 +1522,7 @@ def cli_json_key(self, command, original_key_name): "Latest": "latest", "Maintainer": "maintainer", "Name": "name", - "Website": "website" + "Website": "website", }, "core search": { "Boards": "boards", @@ -1497,25 +1531,16 @@ def cli_json_key(self, command, original_key_name): "Latest": "latest", "Maintainer": "maintainer", "Name": "name", - "Website": "website" - }, - "lib deps": { - "versionRequired": "version_required", - "versionInstalled": "version_installed" + "Website": "website", }, - "lib search": { - "archivefilename": "archive_filename", - "cachepath": "cache_path" - } + "lib deps": {"versionRequired": "version_required", "versionInstalled": "version_installed"}, + "lib search": {"archivefilename": "archive_filename", "cachepath": "cache_path"}, } if ( - ( - not semver.VersionInfo.isvalid(version=self.cli_version) - or semver.compare(ver1=self.cli_version, ver2=final_original_interface_version) > 0 - ) - and (command in key_translation and original_key_name in key_translation[command]) - ): + not semver.VersionInfo.isvalid(version=self.cli_version) + or semver.compare(ver1=self.cli_version, ver2=final_original_interface_version) > 0 + ) and (command in key_translation and original_key_name in key_translation[command]): return key_translation[command][original_key_name] return original_key_name diff --git a/compilesketches/tests/test_compilesketches.py b/compilesketches/tests/test_compilesketches.py index 60b713d..21f51df 100644 --- a/compilesketches/tests/test_compilesketches.py +++ b/compilesketches/tests/test_compilesketches.py @@ -32,22 +32,24 @@ def get_compilesketches_object( deltas_base_ref="foodeltasbaseref", enable_deltas_report="false", enable_warnings_report="false", - sketches_report_path="foo report_folder_name" + sketches_report_path="foo report_folder_name", ): - with unittest.mock.patch("compilesketches.CompileSketches.get_deltas_base_ref", - autospec=True, - return_value=deltas_base_ref): - compilesketches_object = compilesketches.CompileSketches(cli_version=cli_version, - fqbn_arg=fqbn_arg, - platforms=platforms, - libraries=libraries, - sketch_paths=sketch_paths, - cli_compile_flags=cli_compile_flags, - verbose=verbose, - github_token=github_token, - enable_deltas_report=enable_deltas_report, - enable_warnings_report=enable_warnings_report, - sketches_report_path=sketches_report_path) + with unittest.mock.patch( + "compilesketches.CompileSketches.get_deltas_base_ref", autospec=True, return_value=deltas_base_ref + ): + compilesketches_object = compilesketches.CompileSketches( + cli_version=cli_version, + fqbn_arg=fqbn_arg, + platforms=platforms, + libraries=libraries, + sketch_paths=sketch_paths, + cli_compile_flags=cli_compile_flags, + verbose=verbose, + github_token=github_token, + enable_deltas_report=enable_deltas_report, + enable_warnings_report=enable_warnings_report, + sketches_report_path=sketches_report_path, + ) compilesketches_object.github_api = github_api @@ -74,13 +76,19 @@ def directories_are_same(left_directory, right_directory): def test_directories_are_same(): assert directories_are_same(left_directory=test_data_path, right_directory=test_data_path) is True - assert directories_are_same( - left_directory=test_data_path.joinpath("HasSketches"), right_directory=test_data_path.joinpath("NoSketches") - ) is False - assert directories_are_same( - left_directory=test_data_path.joinpath("HasSketches", "NoSketches"), - right_directory=test_data_path.joinpath("NoSketches") - ) is False + assert ( + directories_are_same( + left_directory=test_data_path.joinpath("HasSketches"), right_directory=test_data_path.joinpath("NoSketches") + ) + is False + ) + assert ( + directories_are_same( + left_directory=test_data_path.joinpath("HasSketches", "NoSketches"), + right_directory=test_data_path.joinpath("NoSketches"), + ) + is False + ) @pytest.fixture @@ -126,8 +134,9 @@ def compile_sketches(self): @pytest.mark.parametrize("use_size_report_sketch", [True, False]) -def test_main_size_report_sketch_deprecation_warning(capsys, monkeypatch, setup_action_inputs, - stub_compilesketches_object, use_size_report_sketch): +def test_main_size_report_sketch_deprecation_warning( + capsys, monkeypatch, setup_action_inputs, stub_compilesketches_object, use_size_report_sketch +): if use_size_report_sketch: monkeypatch.setenv("INPUT_SIZE-REPORT-SKETCH", "foo") @@ -141,8 +150,9 @@ def test_main_size_report_sketch_deprecation_warning(capsys, monkeypatch, setup_ @pytest.mark.parametrize("use_enable_size_trends_report", [True, False]) -def test_main_enable_size_trends_report_deprecation_warning(capsys, monkeypatch, setup_action_inputs, - stub_compilesketches_object, use_enable_size_trends_report): +def test_main_enable_size_trends_report_deprecation_warning( + capsys, monkeypatch, setup_action_inputs, stub_compilesketches_object, use_enable_size_trends_report +): if use_enable_size_trends_report: monkeypatch.setenv("INPUT_ENABLE-SIZE-TRENDS-REPORT", "true") @@ -151,19 +161,18 @@ def test_main_enable_size_trends_report_deprecation_warning(capsys, monkeypatch, expected_output = "" if use_enable_size_trends_report: expected_output = ( - expected_output - + "::warning::The size trends report feature has been moved to a dedicated action. See the " - "documentation at " - "https://github.com/arduino/actions/tree/report-size-trends-action/libraries/report-size-trends" + expected_output + "::warning::The size trends report feature has been moved to a dedicated action. See the " + "documentation at " + "https://github.com/arduino/actions/tree/report-size-trends-action/libraries/report-size-trends" ) assert capsys.readouterr().out.strip() == expected_output @pytest.mark.parametrize("use_size_deltas_report_folder_name", [True, False]) -def test_main_size_deltas_report_folder_name_deprecation(capsys, monkeypatch, setup_action_inputs, - stub_compilesketches_object, - use_size_deltas_report_folder_name): +def test_main_size_deltas_report_folder_name_deprecation( + capsys, monkeypatch, setup_action_inputs, stub_compilesketches_object, use_size_deltas_report_folder_name +): size_deltas_report_folder_name = "foo-size-deltas-report-folder-name" if use_size_deltas_report_folder_name: monkeypatch.setenv("INPUT_SIZE-DELTAS-REPORT-FOLDER-NAME", size_deltas_report_folder_name) @@ -175,7 +184,7 @@ def test_main_size_deltas_report_folder_name_deprecation(capsys, monkeypatch, se expected_output = ( expected_output + "::warning::The size-deltas-report-folder-name input is deprecated. Use the equivalent input: " - "sketches-report-path instead." + "sketches-report-path instead." ) assert capsys.readouterr().out.strip() == expected_output @@ -189,8 +198,9 @@ def test_main_size_deltas_report_folder_name_deprecation(capsys, monkeypatch, se @pytest.mark.parametrize("use_enable_size_deltas_report", [True, False]) -def test_main_enable_size_deltas_report_deprecation(capsys, monkeypatch, setup_action_inputs, - stub_compilesketches_object, use_enable_size_deltas_report): +def test_main_enable_size_deltas_report_deprecation( + capsys, monkeypatch, setup_action_inputs, stub_compilesketches_object, use_enable_size_deltas_report +): enable_size_deltas_report = "foo-enable-size-deltas-report" if use_enable_size_deltas_report: monkeypatch.setenv("INPUT_ENABLE-SIZE-DELTAS-REPORT", enable_size_deltas_report) @@ -200,9 +210,8 @@ def test_main_enable_size_deltas_report_deprecation(capsys, monkeypatch, setup_a expected_output = "" if use_enable_size_deltas_report: expected_output = ( - expected_output - + "::warning::The enable-size-deltas-report input is deprecated. Use the equivalent input: " - "enable-deltas-report instead." + expected_output + "::warning::The enable-size-deltas-report input is deprecated. Use the equivalent input: " + "enable-deltas-report instead." ) assert capsys.readouterr().out.strip() == expected_output @@ -236,7 +245,7 @@ def compile_sketches(self): github_token=setup_action_inputs.github_token, enable_deltas_report=setup_action_inputs.enable_deltas_report, enable_warnings_report=setup_action_inputs.enable_warnings_report, - sketches_report_path=setup_action_inputs.sketches_report_path + sketches_report_path=setup_action_inputs.sketches_report_path, ) CompileSketches.compile_sketches.assert_called_once() @@ -249,8 +258,10 @@ def test_compilesketches(): platforms = unittest.mock.sentinel.platforms libraries = unittest.mock.sentinel.libraries sketch_paths = "examples/FooSketchPath examples/BarSketchPath" - expected_sketch_paths_list = [compilesketches.absolute_path(path="examples/FooSketchPath"), - compilesketches.absolute_path(path="examples/BarSketchPath")] + expected_sketch_paths_list = [ + compilesketches.absolute_path(path="examples/FooSketchPath"), + compilesketches.absolute_path(path="examples/BarSketchPath"), + ] cli_compile_flags = "- --foo\n- --bar" expected_cli_compile_flags = ["--foo", "--bar"] verbose = "false" @@ -260,12 +271,12 @@ def test_compilesketches(): enable_warnings_report = "true" sketches_report_path = "FooSketchesReportFolder" - with unittest.mock.patch("compilesketches.CompileSketches.get_deltas_base_ref", - autospec=True, - return_value=expected_deltas_base_ref): + with unittest.mock.patch( + "compilesketches.CompileSketches.get_deltas_base_ref", autospec=True, return_value=expected_deltas_base_ref + ): compile_sketches = compilesketches.CompileSketches( cli_version=cli_version, - fqbn_arg="\'\"" + expected_fqbn + "\" \"" + expected_additional_url + "\"\'", + fqbn_arg="'\"" + expected_fqbn + '" "' + expected_additional_url + "\"'", platforms=platforms, libraries=libraries, sketch_paths=sketch_paths, @@ -274,7 +285,7 @@ def test_compilesketches(): github_token=github_token, enable_deltas_report=enable_deltas_report, enable_warnings_report=enable_warnings_report, - sketches_report_path=sketches_report_path + sketches_report_path=sketches_report_path, ) assert compile_sketches.cli_version == cli_version @@ -292,8 +303,10 @@ def test_compilesketches(): assert get_compilesketches_object(cli_compile_flags="").cli_compile_flags is None assert get_compilesketches_object(cli_compile_flags="- --foo").cli_compile_flags == ["--foo"] - assert get_compilesketches_object(cli_compile_flags="- --foo\n- \"bar baz\"").cli_compile_flags == ["--foo", - "bar baz"] + assert get_compilesketches_object(cli_compile_flags='- --foo\n- "bar baz"').cli_compile_flags == [ + "--foo", + "bar baz", + ] # Test invalid enable_deltas_report value with pytest.raises(expected_exception=SystemExit, match="1"): @@ -308,16 +321,24 @@ def test_compilesketches(): assert compile_sketches.deltas_base_ref is None -@pytest.mark.parametrize("event_name, expected_ref", - [("pull_request", unittest.mock.sentinel.pull_request_base_ref), - ("push", unittest.mock.sentinel.parent_commit_ref)]) +@pytest.mark.parametrize( + "event_name, expected_ref", + [ + ("pull_request", unittest.mock.sentinel.pull_request_base_ref), + ("push", unittest.mock.sentinel.parent_commit_ref), + ], +) def test_get_deltas_base_ref(monkeypatch, mocker, event_name, expected_ref): monkeypatch.setenv("GITHUB_EVENT_NAME", event_name) - mocker.patch("compilesketches.CompileSketches.get_pull_request_base_ref", autospec=True, - return_value=unittest.mock.sentinel.pull_request_base_ref) - mocker.patch("compilesketches.get_parent_commit_ref", autospec=True, - return_value=unittest.mock.sentinel.parent_commit_ref) + mocker.patch( + "compilesketches.CompileSketches.get_pull_request_base_ref", + autospec=True, + return_value=unittest.mock.sentinel.pull_request_base_ref, + ) + mocker.patch( + "compilesketches.get_parent_commit_ref", autospec=True, return_value=unittest.mock.sentinel.parent_commit_ref + ) compile_sketches = get_compilesketches_object() @@ -327,6 +348,7 @@ def test_get_deltas_base_ref(monkeypatch, mocker, event_name, expected_ref): def test_get_pull_request_base_ref(monkeypatch, mocker): class Github: """Stub""" + ref = unittest.mock.sentinel.pull_request_base_ref def __init__(self): @@ -352,9 +374,9 @@ def get_pull(self, number): github_api_object.get_repo.assert_called_once_with(full_name_or_id=os.environ["GITHUB_REPOSITORY"]) github_api_object.get_pull.assert_called_once_with(number=42) # PR number is hardcoded into test file - mocker.patch.object(Github, - "get_repo", - side_effect=github.UnknownObjectException(status=42, data="foo", headers=None)) + mocker.patch.object( + Github, "get_repo", side_effect=github.UnknownObjectException(status=42, data="foo", headers=None) + ) with pytest.raises(expected_exception=SystemExit, match="1"): compile_sketches.get_pull_request_base_ref() @@ -364,6 +386,7 @@ def test_get_parent_commit_ref(mocker): class Repo: """Stub""" + hexsha = parent_commit_ref def __init__(self): @@ -377,16 +400,19 @@ def __init__(self): git.Repo.assert_called_once_with(path=os.environ["GITHUB_WORKSPACE"]) -@pytest.mark.parametrize("enable_warnings_report, expected_clean_build_cache", - [("true", True), - ("false", False)]) -@pytest.mark.parametrize("compilation_success_list, expected_success", - [([True, True, True], True), - ([False, True, True], False), - ([True, False, True], False), - ([True, True, False], False)]) -def test_compile_sketches(mocker, enable_warnings_report, expected_clean_build_cache, compilation_success_list, - expected_success): +@pytest.mark.parametrize("enable_warnings_report, expected_clean_build_cache", [("true", True), ("false", False)]) +@pytest.mark.parametrize( + "compilation_success_list, expected_success", + [ + ([True, True, True], True), + ([False, True, True], False), + ([True, False, True], False), + ([True, True, False], False), + ], +) +def test_compile_sketches( + mocker, enable_warnings_report, expected_clean_build_cache, compilation_success_list, expected_success +): sketch_list = [unittest.mock.sentinel.sketch1, unittest.mock.sentinel.sketch2, unittest.mock.sentinel.sketch3] compilation_result_list = [] @@ -403,8 +429,7 @@ def test_compile_sketches(mocker, enable_warnings_report, expected_clean_build_c mocker.patch("compilesketches.CompileSketches.find_sketches", autospec=True, return_value=sketch_list) mocker.patch("compilesketches.CompileSketches.compile_sketch", autospec=True, side_effect=compilation_result_list) mocker.patch("compilesketches.CompileSketches.get_sketch_report", autospec=True, return_value=sketch_report) - mocker.patch("compilesketches.CompileSketches.get_sketches_report", autospec=True, - return_value=sketches_report) + mocker.patch("compilesketches.CompileSketches.get_sketches_report", autospec=True, return_value=sketches_report) mocker.patch("compilesketches.CompileSketches.create_sketches_report_file", autospec=True) if expected_success: @@ -422,21 +447,20 @@ def test_compile_sketches(mocker, enable_warnings_report, expected_clean_build_c get_sketch_report_calls = [] sketch_report_list = [] for sketch, compilation_result in zip(sketch_list, compilation_result_list): - compile_sketch_calls.append(unittest.mock.call(compile_sketches, - sketch_path=sketch, - clean_build_cache=expected_clean_build_cache)) - get_sketch_report_calls.append(unittest.mock.call(compile_sketches, - compilation_result=compilation_result)) + compile_sketch_calls.append( + unittest.mock.call(compile_sketches, sketch_path=sketch, clean_build_cache=expected_clean_build_cache) + ) + get_sketch_report_calls.append(unittest.mock.call(compile_sketches, compilation_result=compilation_result)) sketch_report_list.append(sketch_report) compile_sketches.compile_sketch.assert_has_calls(calls=compile_sketch_calls) compile_sketches.get_sketch_report.assert_has_calls(calls=get_sketch_report_calls) - compile_sketches.get_sketches_report.assert_called_once_with(compile_sketches, - sketch_report_list=sketch_report_list) + compile_sketches.get_sketches_report.assert_called_once_with( + compile_sketches, sketch_report_list=sketch_report_list + ) compile_sketches.create_sketches_report_file.assert_called_once_with( - compile_sketches, - sketches_report=sketches_report + compile_sketches, sketches_report=sketches_report ) @@ -460,7 +484,7 @@ def test_install_arduino_cli(mocker): url="https://downloads.arduino.cc/arduino-cli/arduino-cli_" + cli_version + "_Linux_64bit.tar.gz", source_path="arduino-cli", destination_parent_path=arduino_cli_installation_path, - force=False + force=False, ) assert os.environ["ARDUINO_DIRECTORIES_USER"] == str(arduino_cli_user_directory_path) @@ -485,12 +509,12 @@ def test_install_platforms(mocker, platforms): compile_sketches = get_compilesketches_object(platforms=platforms) - mocker.patch("compilesketches.CompileSketches.get_fqbn_platform_dependency", - autospec=True, - return_value=fqbn_platform_dependency) - mocker.patch("compilesketches.CompileSketches.sort_dependency_list", - autospec=True, - return_value=dependency_list) + mocker.patch( + "compilesketches.CompileSketches.get_fqbn_platform_dependency", + autospec=True, + return_value=fqbn_platform_dependency, + ) + mocker.patch("compilesketches.CompileSketches.sort_dependency_list", autospec=True, return_value=dependency_list) mocker.patch("compilesketches.CompileSketches.install_platforms_from_board_manager", autospec=True) mocker.patch("compilesketches.CompileSketches.install_platforms_from_path", autospec=True) mocker.patch("compilesketches.CompileSketches.install_platforms_from_repository", autospec=True) @@ -500,39 +524,39 @@ def test_install_platforms(mocker, platforms): if platforms == "": compile_sketches.install_platforms_from_board_manager.assert_called_once_with( - compile_sketches, - platform_list=[fqbn_platform_dependency] + compile_sketches, platform_list=[fqbn_platform_dependency] ) compile_sketches.install_platforms_from_path.assert_not_called() compile_sketches.install_platforms_from_repository.assert_not_called() compile_sketches.install_platforms_from_download.assert_not_called() else: compile_sketches.install_platforms_from_board_manager.assert_called_once_with( - compile_sketches, - platform_list=dependency_list_manager + compile_sketches, platform_list=dependency_list_manager ) compile_sketches.install_platforms_from_path.assert_called_once_with( - compile_sketches, - platform_list=dependency_list_path + compile_sketches, platform_list=dependency_list_path ) compile_sketches.install_platforms_from_repository.assert_called_once_with( - compile_sketches, - platform_list=dependency_list_repository + compile_sketches, platform_list=dependency_list_repository ) compile_sketches.install_platforms_from_download.assert_called_once_with( - compile_sketches, - platform_list=dependency_list_download + compile_sketches, platform_list=dependency_list_download ) @pytest.mark.parametrize( "fqbn_arg, expected_platform, expected_additional_url", - [("arduino:avr:uno", "arduino:avr", None), - # FQBN with space, additional Board Manager URL - ('\'"foo bar:baz:asdf" "https://example.com/platform_foo_index.json"\'', "foo bar:baz", - "https://example.com/platform_foo_index.json"), - # Custom board option - ("arduino:avr:nano:cpu=atmega328old", "arduino:avr", None)] + [ + ("arduino:avr:uno", "arduino:avr", None), + # FQBN with space, additional Board Manager URL + ( + '\'"foo bar:baz:asdf" "https://example.com/platform_foo_index.json"\'', + "foo bar:baz", + "https://example.com/platform_foo_index.json", + ), + # Custom board option + ("arduino:avr:nano:cpu=atmega328old", "arduino:avr", None), + ], ) def test_get_fqbn_platform_dependency(fqbn_arg, expected_platform, expected_additional_url): compile_sketches = get_compilesketches_object(fqbn_arg=fqbn_arg) @@ -548,86 +572,125 @@ def test_get_fqbn_platform_dependency(fqbn_arg, expected_platform, expected_addi @pytest.mark.parametrize( "dependency_list, expected_dependency_type_list", - [([None], []), - ([{compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/foo/bar.git"}], ["repository"]), - ( - [{compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/foo/bar.git/"}], - ["repository"]), - ([{compilesketches.CompileSketches.dependency_source_url_key: "git://example.com/foo/bar"}], ["repository"]), - ([{compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/foo/bar"}], ["download"]), - ([{compilesketches.CompileSketches.dependency_source_path_key: "foo/bar"}], ["path"]), - ([{compilesketches.CompileSketches.dependency_name_key: "FooBar"}], ["manager"]), - ([{compilesketches.CompileSketches.dependency_name_key: "FooBar", - compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/package_foo_index.json"}], - ["manager"]), - ([{compilesketches.CompileSketches.dependency_source_url_key: "git://example.com/foo/bar"}, - {compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/foo/bar"}, - {compilesketches.CompileSketches.dependency_source_path_key: "foo/bar"}, - {compilesketches.CompileSketches.dependency_name_key: "FooBar"}], - ["repository", "download", "path", "manager"]), - ([{compilesketches.CompileSketches.dependency_source_url_key: "git://example.com/foo/bar"}], ["repository"]), - ] + [ + ([None], []), + ( + [{compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/foo/bar.git"}], + ["repository"], + ), + ( + [{compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/foo/bar.git/"}], + ["repository"], + ), + ([{compilesketches.CompileSketches.dependency_source_url_key: "git://example.com/foo/bar"}], ["repository"]), + ([{compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/foo/bar"}], ["download"]), + ([{compilesketches.CompileSketches.dependency_source_path_key: "foo/bar"}], ["path"]), + ([{compilesketches.CompileSketches.dependency_name_key: "FooBar"}], ["manager"]), + ( + [ + { + compilesketches.CompileSketches.dependency_name_key: "FooBar", + compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/package_foo_index.json", + } + ], + ["manager"], + ), + ( + [ + {compilesketches.CompileSketches.dependency_source_url_key: "git://example.com/foo/bar"}, + {compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/foo/bar"}, + {compilesketches.CompileSketches.dependency_source_path_key: "foo/bar"}, + {compilesketches.CompileSketches.dependency_name_key: "FooBar"}, + ], + ["repository", "download", "path", "manager"], + ), + ([{compilesketches.CompileSketches.dependency_source_url_key: "git://example.com/foo/bar"}], ["repository"]), + ], ) def test_sort_dependency_list(dependency_list, expected_dependency_type_list): compile_sketches = get_compilesketches_object() for dependency, expected_dependency_type in zip(dependency_list, expected_dependency_type_list): - assert dependency in getattr(compile_sketches.sort_dependency_list(dependency_list=[dependency]), - expected_dependency_type) + assert dependency in getattr( + compile_sketches.sort_dependency_list(dependency_list=[dependency]), expected_dependency_type + ) @pytest.mark.parametrize( "platform_list, expected_core_update_index_command_list, expected_core_install_command_list", - [( - [{compilesketches.CompileSketches.dependency_name_key: "Foo"}, - {compilesketches.CompileSketches.dependency_name_key: "Bar"}], - [["core", "update-index"], ["core", "update-index"]], - [["core", "install", "Foo"], ["core", "install", "Bar"]] - ), ( - # Additional Board Manager URL - [{compilesketches.CompileSketches.dependency_name_key: "Foo", - compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/package_foo_index.json"}, - {compilesketches.CompileSketches.dependency_name_key: "Bar", - compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/package_bar_index.json"}], - [["core", "update-index", "--additional-urls", "https://example.com/package_foo_index.json"], - ["core", "update-index", "--additional-urls", "https://example.com/package_bar_index.json"]], - [["core", "install", "--additional-urls", "https://example.com/package_foo_index.json", "Foo"], - ["core", "install", "--additional-urls", "https://example.com/package_bar_index.json", "Bar"]] - )]) -def test_install_platforms_from_board_manager(mocker, - platform_list, - expected_core_update_index_command_list, - expected_core_install_command_list): + [ + ( + [ + {compilesketches.CompileSketches.dependency_name_key: "Foo"}, + {compilesketches.CompileSketches.dependency_name_key: "Bar"}, + ], + [["core", "update-index"], ["core", "update-index"]], + [["core", "install", "Foo"], ["core", "install", "Bar"]], + ), + ( + # Additional Board Manager URL + [ + { + compilesketches.CompileSketches.dependency_name_key: "Foo", + compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/package_foo_index.json", + }, + { + compilesketches.CompileSketches.dependency_name_key: "Bar", + compilesketches.CompileSketches.dependency_source_url_key: "https://example.com/package_bar_index.json", + }, + ], + [ + ["core", "update-index", "--additional-urls", "https://example.com/package_foo_index.json"], + ["core", "update-index", "--additional-urls", "https://example.com/package_bar_index.json"], + ], + [ + ["core", "install", "--additional-urls", "https://example.com/package_foo_index.json", "Foo"], + ["core", "install", "--additional-urls", "https://example.com/package_bar_index.json", "Bar"], + ], + ), + ], +) +def test_install_platforms_from_board_manager( + mocker, platform_list, expected_core_update_index_command_list, expected_core_install_command_list +): run_command_output_level = unittest.mock.sentinel.run_command_output_level compile_sketches = get_compilesketches_object() - mocker.patch("compilesketches.CompileSketches.get_run_command_output_level", autospec=True, - return_value=run_command_output_level) + mocker.patch( + "compilesketches.CompileSketches.get_run_command_output_level", + autospec=True, + return_value=run_command_output_level, + ) mocker.patch("compilesketches.CompileSketches.run_arduino_cli_command", autospec=True) compile_sketches.install_platforms_from_board_manager(platform_list=platform_list) run_arduino_cli_command_calls = [] for expected_core_update_index_command, expected_core_install_command in zip( - expected_core_update_index_command_list, - expected_core_install_command_list + expected_core_update_index_command_list, expected_core_install_command_list ): - run_arduino_cli_command_calls.extend([ - unittest.mock.call(compile_sketches, - command=expected_core_update_index_command, - enable_output=run_command_output_level), - unittest.mock.call(compile_sketches, - command=expected_core_install_command, - enable_output=run_command_output_level) - ]) + run_arduino_cli_command_calls.extend( + [ + unittest.mock.call( + compile_sketches, command=expected_core_update_index_command, enable_output=run_command_output_level + ), + unittest.mock.call( + compile_sketches, command=expected_core_install_command, enable_output=run_command_output_level + ), + ] + ) compile_sketches.run_arduino_cli_command.assert_has_calls(calls=run_arduino_cli_command_calls) -@pytest.mark.parametrize("verbose, expected_output_level", - [("true", compilesketches.CompileSketches.RunCommandOutput.ALWAYS), - ("false", compilesketches.CompileSketches.RunCommandOutput.ON_FAILURE)]) +@pytest.mark.parametrize( + "verbose, expected_output_level", + [ + ("true", compilesketches.CompileSketches.RunCommandOutput.ALWAYS), + ("false", compilesketches.CompileSketches.RunCommandOutput.ON_FAILURE), + ], +) def test_get_run_command_output_level(verbose, expected_output_level): compile_sketches = get_compilesketches_object(verbose=verbose) @@ -649,9 +712,12 @@ def test_run_arduino_cli_command(mocker, verbose): mocker.patch("compilesketches.CompileSketches.run_command", autospec=True, return_value=run_command_return) - assert compile_sketches.run_arduino_cli_command(command=command, - enable_output=enable_output, - exit_on_failure=exit_on_failure) == run_command_return + assert ( + compile_sketches.run_arduino_cli_command( + command=command, enable_output=enable_output, exit_on_failure=exit_on_failure + ) + == run_command_return + ) expected_run_command_command = [arduino_cli_installation_path.joinpath("arduino-cli")] expected_run_command_command.extend(command) @@ -661,18 +727,22 @@ def test_run_arduino_cli_command(mocker, verbose): compile_sketches, command=expected_run_command_command, enable_output=enable_output, - exit_on_failure=exit_on_failure + exit_on_failure=exit_on_failure, ) -@pytest.mark.parametrize("enable_output", [compilesketches.CompileSketches.RunCommandOutput.NONE, - compilesketches.CompileSketches.RunCommandOutput.ON_FAILURE, - compilesketches.CompileSketches.RunCommandOutput.ALWAYS]) -@pytest.mark.parametrize("exit_on_failure, returncode, expected_success", - [(False, 0, True), - (False, 1, True), - (True, 0, True), - (True, 1, False)]) +@pytest.mark.parametrize( + "enable_output", + [ + compilesketches.CompileSketches.RunCommandOutput.NONE, + compilesketches.CompileSketches.RunCommandOutput.ON_FAILURE, + compilesketches.CompileSketches.RunCommandOutput.ALWAYS, + ], +) +@pytest.mark.parametrize( + "exit_on_failure, returncode, expected_success", + [(False, 0, True), (False, 1, True), (True, 0, True), (True, 1, False)], +) def test_run_command(capsys, mocker, enable_output, exit_on_failure, returncode, expected_success): command = unittest.mock.sentinel.command @@ -690,23 +760,28 @@ class CommandData: mocker.patch("subprocess.run", autospec=True, return_value=command_data) if expected_success: - run_command_output = compile_sketches.run_command(command=command, - enable_output=enable_output, - exit_on_failure=exit_on_failure) + run_command_output = compile_sketches.run_command( + command=command, enable_output=enable_output, exit_on_failure=exit_on_failure + ) assert run_command_output == command_data else: with pytest.raises(expected_exception=SystemExit, match=str(returncode)): - compile_sketches.run_command(command=command, - enable_output=enable_output, - exit_on_failure=exit_on_failure) - - expected_output = ("::group::Running command: " + " ".join(command_data.args) + " \n " - + str(CommandData.stdout) + " \n " - + "::endgroup::") + compile_sketches.run_command(command=command, enable_output=enable_output, exit_on_failure=exit_on_failure) + + expected_output = ( + "::group::Running command: " + + " ".join(command_data.args) + + " \n " + + str(CommandData.stdout) + + " \n " + + "::endgroup::" + ) - if returncode != 0 and (enable_output == compilesketches.CompileSketches.RunCommandOutput.ON_FAILURE - or enable_output == compilesketches.CompileSketches.RunCommandOutput.ALWAYS): + if returncode != 0 and ( + enable_output == compilesketches.CompileSketches.RunCommandOutput.ON_FAILURE + or enable_output == compilesketches.CompileSketches.RunCommandOutput.ALWAYS + ): expected_output = expected_output + "\n::error::Command failed" elif enable_output == compilesketches.CompileSketches.RunCommandOutput.ALWAYS: expected_output = expected_output @@ -720,12 +795,25 @@ class CommandData: @pytest.mark.parametrize( "dependency, expected_name", - [({compilesketches.CompileSketches.dependency_name_key: "Foo", - compilesketches.CompileSketches.dependency_version_key: "1.2.3"}, "Foo@1.2.3"), - ({compilesketches.CompileSketches.dependency_name_key: "Foo", - compilesketches.CompileSketches.dependency_version_key: "latest"}, "Foo"), - ({compilesketches.CompileSketches.dependency_name_key: "Foo@1.2.3"}, "Foo@1.2.3"), - ({compilesketches.CompileSketches.dependency_name_key: "Foo"}, "Foo")]) + [ + ( + { + compilesketches.CompileSketches.dependency_name_key: "Foo", + compilesketches.CompileSketches.dependency_version_key: "1.2.3", + }, + "Foo@1.2.3", + ), + ( + { + compilesketches.CompileSketches.dependency_name_key: "Foo", + compilesketches.CompileSketches.dependency_version_key: "latest", + }, + "Foo", + ), + ({compilesketches.CompileSketches.dependency_name_key: "Foo@1.2.3"}, "Foo@1.2.3"), + ({compilesketches.CompileSketches.dependency_name_key: "Foo"}, "Foo"), + ], +) def test_get_manager_dependency_name(dependency, expected_name): compile_sketches = get_compilesketches_object() assert compile_sketches.get_manager_dependency_name(dependency=dependency) == expected_name @@ -733,8 +821,10 @@ def test_get_manager_dependency_name(dependency, expected_name): @pytest.mark.parametrize( "path_exists, platform_list", - [(False, [{compilesketches.CompileSketches.dependency_source_path_key: pathlib.Path("Foo")}]), - (True, [{compilesketches.CompileSketches.dependency_source_path_key: pathlib.Path("Foo")}])] + [ + (False, [{compilesketches.CompileSketches.dependency_source_path_key: pathlib.Path("Foo")}]), + (True, [{compilesketches.CompileSketches.dependency_source_path_key: pathlib.Path("Foo")}]), + ], ) def test_install_platforms_from_path(capsys, mocker, path_exists, platform_list): class PlatformInstallationPath: @@ -748,9 +838,11 @@ def __init__(self): compile_sketches = get_compilesketches_object() mocker.patch.object(pathlib.Path, "exists", autospec=True, return_value=path_exists) - mocker.patch("compilesketches.CompileSketches.get_platform_installation_path", - autospec=True, - return_value=platform_installation_path) + mocker.patch( + "compilesketches.CompileSketches.get_platform_installation_path", + autospec=True, + return_value=platform_installation_path, + ) mocker.patch("compilesketches.CompileSketches.install_from_path", autospec=True) if not path_exists: @@ -778,7 +870,7 @@ def __init__(self): ), destination_parent_path=platform_installation_path.path.parent, destination_name=platform_installation_path.path.name, - force=platform_installation_path.is_overwrite + force=platform_installation_path.is_overwrite, ) ) @@ -789,22 +881,23 @@ def __init__(self): @pytest.mark.parametrize( - "platform," - "command_data_stdout," - "expected_installation_path", + "platform," "command_data_stdout," "expected_installation_path", # No match to previously installed platforms - [({compilesketches.CompileSketches.dependency_name_key: "foo:bar"}, - "[{\"ID\": \"asdf:zxcv\"}]", - pathlib.PurePath("/foo/UserPlatformsPath/foo/bar")), - # Match with previously installed platform - ({compilesketches.CompileSketches.dependency_name_key: "foo:bar"}, - "[{\"ID\": \"foo:bar\", \"Installed\": \"1.2.3\"}]", - pathlib.PurePath("/foo/BoardManagerPlatformsPath/foo/hardware/bar/1.2.3"))] + [ + ( + {compilesketches.CompileSketches.dependency_name_key: "foo:bar"}, + '[{"ID": "asdf:zxcv"}]', + pathlib.PurePath("/foo/UserPlatformsPath/foo/bar"), + ), + # Match with previously installed platform + ( + {compilesketches.CompileSketches.dependency_name_key: "foo:bar"}, + '[{"ID": "foo:bar", "Installed": "1.2.3"}]', + pathlib.PurePath("/foo/BoardManagerPlatformsPath/foo/hardware/bar/1.2.3"), + ), + ], ) -def test_get_platform_installation_path(mocker, - platform, - command_data_stdout, - expected_installation_path): +def test_get_platform_installation_path(mocker, platform, command_data_stdout, expected_installation_path): class CommandData: def __init__(self, stdout): self.stdout = stdout @@ -820,17 +913,21 @@ def __init__(self, stdout): platform_installation_path = compile_sketches.get_platform_installation_path(platform=platform) assert platform_installation_path.path == expected_installation_path - run_arduino_cli_command_calls = [unittest.mock.call(compile_sketches, command=["core", "update-index"]), - unittest.mock.call(compile_sketches, command=["core", "list", "--format", "json"])] + run_arduino_cli_command_calls = [ + unittest.mock.call(compile_sketches, command=["core", "update-index"]), + unittest.mock.call(compile_sketches, command=["core", "list", "--format", "json"]), + ] compilesketches.CompileSketches.run_arduino_cli_command.assert_has_calls(calls=run_arduino_cli_command_calls) def test_install_platforms_from_repository(mocker): platform_list = [ - {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url, - compilesketches.CompileSketches.dependency_source_path_key: unittest.mock.sentinel.source_path, - compilesketches.CompileSketches.dependency_destination_name_key: unittest.mock.sentinel.destination_name}, - {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url2} + { + compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url, + compilesketches.CompileSketches.dependency_source_path_key: unittest.mock.sentinel.source_path, + compilesketches.CompileSketches.dependency_destination_name_key: unittest.mock.sentinel.destination_name, + }, + {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url2}, ] git_ref = unittest.mock.sentinel.git_ref @@ -849,9 +946,11 @@ def __init__(self): compile_sketches = get_compilesketches_object() mocker.patch("compilesketches.CompileSketches.get_repository_dependency_ref", autospec=True, return_value=git_ref) - mocker.patch("compilesketches.CompileSketches.get_platform_installation_path", - autospec=True, - return_value=platform_installation_path) + mocker.patch( + "compilesketches.CompileSketches.get_platform_installation_path", + autospec=True, + return_value=platform_installation_path, + ) mocker.patch("compilesketches.CompileSketches.install_from_repository", autospec=True, return_value=git_ref) compile_sketches.install_platforms_from_repository(platform_list=platform_list) @@ -859,19 +958,21 @@ def __init__(self): get_repository_dependency_ref_calls = [] get_platform_installation_path_calls = [] install_from_repository_calls = [] - for platform, expected_source_path, expected_destination_name in zip(platform_list, - expected_source_path_list, - expected_destination_name_list): + for platform, expected_source_path, expected_destination_name in zip( + platform_list, expected_source_path_list, expected_destination_name_list + ): get_repository_dependency_ref_calls.append(unittest.mock.call(compile_sketches, dependency=platform)) get_platform_installation_path_calls.append(unittest.mock.call(compile_sketches, platform=platform)) install_from_repository_calls.append( - unittest.mock.call(compile_sketches, - url=platform[compilesketches.CompileSketches.dependency_source_url_key], - git_ref=git_ref, - source_path=expected_source_path, - destination_parent_path=platform_installation_path.path.parent, - destination_name=platform_installation_path.path.name, - force=platform_installation_path.is_overwrite) + unittest.mock.call( + compile_sketches, + url=platform[compilesketches.CompileSketches.dependency_source_url_key], + git_ref=git_ref, + source_path=expected_source_path, + destination_parent_path=platform_installation_path.path.parent, + destination_name=platform_installation_path.path.name, + force=platform_installation_path.is_overwrite, + ) ) compile_sketches.get_repository_dependency_ref.assert_has_calls(calls=get_repository_dependency_ref_calls) @@ -880,8 +981,7 @@ def __init__(self): @pytest.mark.parametrize( "dependency, expected_ref", - [({compilesketches.CompileSketches.dependency_version_key: "1.2.3"}, "1.2.3"), - ({}, None)] + [({compilesketches.CompileSketches.dependency_version_key: "1.2.3"}, "1.2.3"), ({}, None)], ) def test_get_repository_dependency_ref(dependency, expected_ref): compile_sketches = get_compilesketches_object() @@ -890,10 +990,12 @@ def test_get_repository_dependency_ref(dependency, expected_ref): def test_install_platforms_from_download(mocker): platform_list = [ - {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url1, - compilesketches.CompileSketches.dependency_source_path_key: unittest.mock.sentinel.source_path, - compilesketches.CompileSketches.dependency_destination_name_key: unittest.mock.sentinel.destination_name}, - {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url2} + { + compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url1, + compilesketches.CompileSketches.dependency_source_path_key: unittest.mock.sentinel.source_path, + compilesketches.CompileSketches.dependency_destination_name_key: unittest.mock.sentinel.destination_name, + }, + {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url2}, ] class PlatformInstallationPath: @@ -908,75 +1010,97 @@ def __init__(self): compile_sketches = get_compilesketches_object() - mocker.patch("compilesketches.CompileSketches.get_platform_installation_path", - autospec=True, - return_value=platform_installation_path) + mocker.patch( + "compilesketches.CompileSketches.get_platform_installation_path", + autospec=True, + return_value=platform_installation_path, + ) mocker.patch("compilesketches.CompileSketches.install_from_download", autospec=True) compile_sketches.install_platforms_from_download(platform_list=platform_list) get_platform_installation_path_calls = [] install_from_download_calls = [] - for platform, expected_source_path, in zip(platform_list, expected_source_path_list): + for ( + platform, + expected_source_path, + ) in zip(platform_list, expected_source_path_list): get_platform_installation_path_calls.append(unittest.mock.call(compile_sketches, platform=platform)) install_from_download_calls.append( - unittest.mock.call(compile_sketches, - url=platform[compilesketches.CompileSketches.dependency_source_url_key], - source_path=expected_source_path, - destination_parent_path=platform_installation_path.path.parent, - destination_name=platform_installation_path.path.name, - force=platform_installation_path.is_overwrite) + unittest.mock.call( + compile_sketches, + url=platform[compilesketches.CompileSketches.dependency_source_url_key], + source_path=expected_source_path, + destination_parent_path=platform_installation_path.path.parent, + destination_name=platform_installation_path.path.name, + force=platform_installation_path.is_overwrite, + ) ) compile_sketches.install_from_download.assert_has_calls(calls=install_from_download_calls) @pytest.mark.parametrize( "libraries, expected_manager, expected_path, expected_repository, expected_download", - [("", - [], - [{compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"]}], - [], - []), - ("foo bar", - [{compilesketches.CompileSketches.dependency_name_key: "foo"}, - {compilesketches.CompileSketches.dependency_name_key: "bar"}], - [{compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"]}], - [], - []), - ("\"foo\" \"bar\"", - [{compilesketches.CompileSketches.dependency_name_key: "foo"}, - {compilesketches.CompileSketches.dependency_name_key: "bar"}], - [{compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"]}], - [], - []), - ("-", - [], - [], - [], - []), - ("- " + compilesketches.CompileSketches.dependency_name_key + ": foo", - [{compilesketches.CompileSketches.dependency_name_key: "foo"}], - [], - [], - []), - ("- " + compilesketches.CompileSketches.dependency_source_path_key + ": /foo/bar", - [], - [{compilesketches.CompileSketches.dependency_source_path_key: "/foo/bar"}], - [], - []), - ("- " + compilesketches.CompileSketches.dependency_source_url_key + ": https://example.com/foo.git", - [], - [], - [{"source-url": "https://example.com/foo.git"}], - []), - ("- " + compilesketches.CompileSketches.dependency_source_url_key + ": https://example.com/foo.zip", - [], - [], - [], - [{"source-url": "https://example.com/foo.zip"}])] + [ + ( + "", + [], + [{compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"]}], + [], + [], + ), + ( + "foo bar", + [ + {compilesketches.CompileSketches.dependency_name_key: "foo"}, + {compilesketches.CompileSketches.dependency_name_key: "bar"}, + ], + [{compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"]}], + [], + [], + ), + ( + '"foo" "bar"', + [ + {compilesketches.CompileSketches.dependency_name_key: "foo"}, + {compilesketches.CompileSketches.dependency_name_key: "bar"}, + ], + [{compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"]}], + [], + [], + ), + ("-", [], [], [], []), + ( + "- " + compilesketches.CompileSketches.dependency_name_key + ": foo", + [{compilesketches.CompileSketches.dependency_name_key: "foo"}], + [], + [], + [], + ), + ( + "- " + compilesketches.CompileSketches.dependency_source_path_key + ": /foo/bar", + [], + [{compilesketches.CompileSketches.dependency_source_path_key: "/foo/bar"}], + [], + [], + ), + ( + "- " + compilesketches.CompileSketches.dependency_source_url_key + ": https://example.com/foo.git", + [], + [], + [{"source-url": "https://example.com/foo.git"}], + [], + ), + ( + "- " + compilesketches.CompileSketches.dependency_source_url_key + ": https://example.com/foo.zip", + [], + [], + [], + [{"source-url": "https://example.com/foo.zip"}], + ), + ], ) -def test_install_libraries(mocker, libraries, expected_manager, expected_path, expected_repository, - expected_download): +def test_install_libraries(mocker, libraries, expected_manager, expected_path, expected_repository, expected_download): libraries_path = pathlib.Path("/foo/LibrariesPath") compile_sketches = get_compilesketches_object(libraries=libraries) @@ -991,29 +1115,29 @@ def test_install_libraries(mocker, libraries, expected_manager, expected_path, e if len(expected_manager) > 0: compile_sketches.install_libraries_from_library_manager.assert_called_once_with( - compile_sketches, - library_list=expected_manager) + compile_sketches, library_list=expected_manager + ) else: compile_sketches.install_libraries_from_library_manager.assert_not_called() if len(expected_path) > 0: compile_sketches.install_libraries_from_path.assert_called_once_with( - compile_sketches, - library_list=expected_path) + compile_sketches, library_list=expected_path + ) else: compile_sketches.install_libraries_from_path.assert_not_called() if len(expected_repository) > 0: compile_sketches.install_libraries_from_repository.assert_called_once_with( - compile_sketches, - library_list=expected_repository) + compile_sketches, library_list=expected_repository + ) else: compile_sketches.install_libraries_from_repository.assert_not_called() if len(expected_download) > 0: compile_sketches.install_libraries_from_download.assert_called_once_with( - compile_sketches, - library_list=expected_download) + compile_sketches, library_list=expected_download + ) else: compile_sketches.install_libraries_from_download.assert_not_called() @@ -1024,8 +1148,11 @@ def test_install_libraries_from_library_manager(mocker): library_list = [{compile_sketches.dependency_name_key: "foo"}, {compile_sketches.dependency_name_key: "bar"}] - mocker.patch("compilesketches.CompileSketches.get_run_command_output_level", autospec=True, - return_value=run_command_output_level) + mocker.patch( + "compilesketches.CompileSketches.get_run_command_output_level", + autospec=True, + return_value=run_command_output_level, + ) mocker.patch("compilesketches.CompileSketches.run_arduino_cli_command", autospec=True) compile_sketches.install_libraries_from_library_manager(library_list=library_list) @@ -1037,11 +1164,7 @@ def test_install_libraries_from_library_manager(mocker): lib_install_command = lib_install_base_command.copy() lib_install_command.append(library["name"]) run_arduino_cli_command_calls.append( - unittest.mock.call( - compile_sketches, - command=lib_install_command, - enable_output=run_command_output_level - ) + unittest.mock.call(compile_sketches, command=lib_install_command, enable_output=run_command_output_level) ) # noinspection PyUnresolvedReferences @@ -1050,22 +1173,43 @@ def test_install_libraries_from_library_manager(mocker): @pytest.mark.parametrize( "path_exists, library_list, expected_destination_name_list", - [(False, - [{compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"] + "/Nonexistent"}], - []), - (True, - [{compilesketches.CompileSketches.dependency_destination_name_key: "FooName", - compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"] + "/FooLibrary"}], - ["FooName"]), - (True, - [{compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"]}], - ["FooRepoName"]), - (True, - [{compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"] + "/Bar"}], - [None])] + [ + ( + False, + [ + { + compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"] + + "/Nonexistent" + } + ], + [], + ), + ( + True, + [ + { + compilesketches.CompileSketches.dependency_destination_name_key: "FooName", + compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"] + + "/FooLibrary", + } + ], + ["FooName"], + ), + ( + True, + [{compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"]}], + ["FooRepoName"], + ), + ( + True, + [{compilesketches.CompileSketches.dependency_source_path_key: os.environ["GITHUB_WORKSPACE"] + "/Bar"}], + [None], + ), + ], ) -def test_install_libraries_from_path(capsys, monkeypatch, mocker, path_exists, library_list, - expected_destination_name_list): +def test_install_libraries_from_path( + capsys, monkeypatch, mocker, path_exists, library_list, expected_destination_name_list +): libraries_path = pathlib.Path("/foo/LibrariesPath") monkeypatch.setenv("GITHUB_REPOSITORY", "foo/FooRepoName") @@ -1098,7 +1242,7 @@ def test_install_libraries_from_path(capsys, monkeypatch, mocker, path_exists, l ), destination_parent_path=libraries_path, destination_name=expected_destination_name, - force=True + force=True, ) ) @@ -1109,10 +1253,12 @@ def test_install_libraries_from_path(capsys, monkeypatch, mocker, path_exists, l def test_install_libraries_from_repository(mocker): git_ref = unittest.mock.sentinel.git_ref library_list = [ - {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url, - compilesketches.CompileSketches.dependency_source_path_key: unittest.mock.sentinel.source_path, - compilesketches.CompileSketches.dependency_destination_name_key: unittest.mock.sentinel.destination_name}, - {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url2} + { + compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url, + compilesketches.CompileSketches.dependency_source_path_key: unittest.mock.sentinel.source_path, + compilesketches.CompileSketches.dependency_destination_name_key: unittest.mock.sentinel.destination_name, + }, + {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url2}, ] expected_source_path_list = [unittest.mock.sentinel.source_path, "."] expected_destination_name_list = [unittest.mock.sentinel.destination_name, None] @@ -1126,18 +1272,20 @@ def test_install_libraries_from_repository(mocker): get_repository_dependency_ref_calls = [] install_from_repository_calls = [] - for library, expected_source_path, expected_destination_name in zip(library_list, - expected_source_path_list, - expected_destination_name_list): + for library, expected_source_path, expected_destination_name in zip( + library_list, expected_source_path_list, expected_destination_name_list + ): get_repository_dependency_ref_calls.append(unittest.mock.call(compile_sketches, dependency=library)) install_from_repository_calls.append( - unittest.mock.call(compile_sketches, - url=library[compilesketches.CompileSketches.dependency_source_url_key], - git_ref=git_ref, - source_path=expected_source_path, - destination_parent_path=compile_sketches.libraries_path, - destination_name=expected_destination_name, - force=True) + unittest.mock.call( + compile_sketches, + url=library[compilesketches.CompileSketches.dependency_source_url_key], + git_ref=git_ref, + source_path=expected_source_path, + destination_parent_path=compile_sketches.libraries_path, + destination_name=expected_destination_name, + force=True, + ) ) compile_sketches.get_repository_dependency_ref.assert_has_calls(calls=get_repository_dependency_ref_calls) @@ -1146,10 +1294,12 @@ def test_install_libraries_from_repository(mocker): def test_install_libraries_from_download(mocker): library_list = [ - {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url1, - compilesketches.CompileSketches.dependency_source_path_key: unittest.mock.sentinel.source_path, - compilesketches.CompileSketches.dependency_destination_name_key: unittest.mock.sentinel.destination_name}, - {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url2} + { + compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url1, + compilesketches.CompileSketches.dependency_source_path_key: unittest.mock.sentinel.source_path, + compilesketches.CompileSketches.dependency_destination_name_key: unittest.mock.sentinel.destination_name, + }, + {compilesketches.CompileSketches.dependency_source_url_key: unittest.mock.sentinel.source_url2}, ] expected_source_path_list = [unittest.mock.sentinel.source_path, "."] @@ -1162,15 +1312,18 @@ def test_install_libraries_from_download(mocker): compile_sketches.install_libraries_from_download(library_list=library_list) install_libraries_from_download_calls = [] - for library, expected_source_path, expected_destination_name in zip(library_list, expected_source_path_list, - expected_destination_name_list): + for library, expected_source_path, expected_destination_name in zip( + library_list, expected_source_path_list, expected_destination_name_list + ): install_libraries_from_download_calls.append( - unittest.mock.call(compile_sketches, - url=library[compilesketches.CompileSketches.dependency_source_url_key], - source_path=expected_source_path, - destination_parent_path=compilesketches.CompileSketches.libraries_path, - destination_name=expected_destination_name, - force=True) + unittest.mock.call( + compile_sketches, + url=library[compilesketches.CompileSketches.dependency_source_url_key], + source_path=expected_source_path, + destination_parent_path=compilesketches.CompileSketches.libraries_path, + destination_name=expected_destination_name, + force=True, + ) ) compile_sketches.install_from_download.assert_has_calls(calls=install_libraries_from_download_calls) @@ -1179,9 +1332,7 @@ def test_find_sketches(capsys): nonexistent_sketch_path = "/foo/NonexistentSketch" # Test sketch path doesn't exist - compile_sketches = get_compilesketches_object( - sketch_paths="\'\"" + nonexistent_sketch_path + "\"\'" - ) + compile_sketches = get_compilesketches_object(sketch_paths="'\"" + nonexistent_sketch_path + "\"'") with pytest.raises(expected_exception=SystemExit, match="1"): compile_sketches.find_sketches() assert capsys.readouterr().out.strip() == ( @@ -1192,53 +1343,49 @@ def test_find_sketches(capsys): # Test sketch path is a sketch file compile_sketches = get_compilesketches_object( - sketch_paths="\'" + str(test_data_path.joinpath("HasSketches", "Sketch1", "Sketch1.ino")) + "\'" + sketch_paths="'" + str(test_data_path.joinpath("HasSketches", "Sketch1", "Sketch1.ino")) + "'" ) - assert compile_sketches.find_sketches() == [ - test_data_path.joinpath("HasSketches", "Sketch1") - ] + assert compile_sketches.find_sketches() == [test_data_path.joinpath("HasSketches", "Sketch1")] # Test sketch path is a non-sketch file non_sketch_path = str(test_data_path.joinpath("NoSketches", "NotSketch", "NotSketch.foo")) - compile_sketches = get_compilesketches_object(sketch_paths="\'" + non_sketch_path + "\'") + compile_sketches = get_compilesketches_object(sketch_paths="'" + non_sketch_path + "'") with pytest.raises(expected_exception=SystemExit, match="1"): compile_sketches.find_sketches() assert capsys.readouterr().out.strip() == ("::error::Sketch path: " + non_sketch_path + " is not a sketch") # Test sketch path is a sketch folder compile_sketches = get_compilesketches_object( - sketch_paths="\'" + str(test_data_path.joinpath("HasSketches", "Sketch1")) + "\'" + sketch_paths="'" + str(test_data_path.joinpath("HasSketches", "Sketch1")) + "'" ) - assert compile_sketches.find_sketches() == [ - test_data_path.joinpath("HasSketches", "Sketch1") - ] + assert compile_sketches.find_sketches() == [test_data_path.joinpath("HasSketches", "Sketch1")] # Test sketch path does contain sketches - compile_sketches = get_compilesketches_object( - sketch_paths="\'" + str(test_data_path.joinpath("HasSketches")) + "\'") + compile_sketches = get_compilesketches_object(sketch_paths="'" + str(test_data_path.joinpath("HasSketches")) + "'") assert compile_sketches.find_sketches() == [ test_data_path.joinpath("HasSketches", "Sketch1"), - test_data_path.joinpath("HasSketches", "Sketch2") + test_data_path.joinpath("HasSketches", "Sketch2"), ] # Test sketch path doesn't contain any sketches no_sketches_path = str(test_data_path.joinpath("NoSketches")) - compile_sketches = get_compilesketches_object( - sketch_paths="\'" + no_sketches_path + "\'") + compile_sketches = get_compilesketches_object(sketch_paths="'" + no_sketches_path + "'") with pytest.raises(expected_exception=SystemExit, match="1"): compile_sketches.find_sketches() - assert capsys.readouterr().out.strip() == ("::error::No sketches were found in " - + no_sketches_path) + assert capsys.readouterr().out.strip() == ("::error::No sketches were found in " + no_sketches_path) @pytest.mark.parametrize( "input_value, expected_list, expected_was_yaml_list", - [("", [], False), - ("foo", ["foo"], False), - ("\'\"foo bar\" baz\'", ["foo bar", "baz"], False), - ("foo: bar", ["foo:", "bar"], False), - ("-", [None], True), - ("- foo: asdf\n bar: qwer\n- baz: zxcv", [{"foo": "asdf", "bar": "qwer"}, {"baz": "zxcv"}], True)]) + [ + ("", [], False), + ("foo", ["foo"], False), + ("'\"foo bar\" baz'", ["foo bar", "baz"], False), + ("foo: bar", ["foo:", "bar"], False), + ("-", [None], True), + ("- foo: asdf\n bar: qwer\n- baz: zxcv", [{"foo": "asdf", "bar": "qwer"}, {"baz": "zxcv"}], True), + ], +) def test_get_list_from_multiformat_input(input_value, expected_list, expected_was_yaml_list): input_list = compilesketches.get_list_from_multiformat_input(input_value=input_value) assert input_list.value == expected_list @@ -1248,26 +1395,30 @@ def test_get_list_from_multiformat_input(input_value, expected_list, expected_wa # noinspection PyUnresolvedReferences @pytest.mark.parametrize( "source_sub_path, destination_parent_sub_path, destination_name, expected_destination_sub_path", - [("foo/source-path", - "bar/destination-parent-path", - None, - "bar/destination-parent-path/source-path"), - ("foo/source-path", - "bar/destination-parent-path", - "destination-name", - "bar/destination-parent-path/destination-name")]) + [ + ("foo/source-path", "bar/destination-parent-path", None, "bar/destination-parent-path/source-path"), + ( + "foo/source-path", + "bar/destination-parent-path", + "destination-name", + "bar/destination-parent-path/destination-name", + ), + ], +) @pytest.mark.parametrize("exists", ["no", "yes", "symlink", "broken"]) @pytest.mark.parametrize("force", [True, False]) @pytest.mark.parametrize("is_dir", [True, False]) -def test_install_from_path(capsys, - tmp_path, - source_sub_path, - destination_parent_sub_path, - destination_name, - expected_destination_sub_path, - exists, - force, - is_dir): +def test_install_from_path( + capsys, + tmp_path, + source_sub_path, + destination_parent_sub_path, + destination_name, + expected_destination_sub_path, + exists, + force, + is_dir, +): source_path = tmp_path.joinpath(source_sub_path) # Generate source path @@ -1302,19 +1453,22 @@ def test_install_from_path(capsys, if exists != "no" and not force: with pytest.raises(expected_exception=SystemExit, match="1"): - compile_sketches.install_from_path(source_path=source_path, - destination_parent_path=destination_parent_path, - destination_name=destination_name, - force=force) + compile_sketches.install_from_path( + source_path=source_path, + destination_parent_path=destination_parent_path, + destination_name=destination_name, + force=force, + ) assert capsys.readouterr().out.strip() == ( - "::error::Installation already exists: " - + str(expected_destination_path) + "::error::Installation already exists: " + str(expected_destination_path) ) else: - compile_sketches.install_from_path(source_path=source_path, - destination_parent_path=destination_parent_path, - destination_name=destination_name, - force=force) + compile_sketches.install_from_path( + source_path=source_path, + destination_parent_path=destination_parent_path, + destination_name=destination_name, + force=force, + ) assert expected_destination_path.resolve() == source_path @@ -1338,37 +1492,38 @@ def prep_test_folders(): # Test existing destination_parent_path prep_test_folders() destination_parent_path.mkdir(parents=True) - compile_sketches.install_from_path(source_path=source_path, destination_parent_path=destination_parent_path, - destination_name=None) - assert directories_are_same(left_directory=source_path, - right_directory=destination_parent_path.joinpath(source_path.name)) + compile_sketches.install_from_path( + source_path=source_path, destination_parent_path=destination_parent_path, destination_name=None + ) + assert directories_are_same( + left_directory=source_path, right_directory=destination_parent_path.joinpath(source_path.name) + ) # Test custom folder name prep_test_folders() destination_name = "foo-destination-name" - compile_sketches.install_from_path(source_path=source_path, - destination_parent_path=destination_parent_path, - destination_name=destination_name) - assert directories_are_same(left_directory=source_path, - right_directory=destination_parent_path.joinpath(destination_name)) + compile_sketches.install_from_path( + source_path=source_path, destination_parent_path=destination_parent_path, destination_name=destination_name + ) + assert directories_are_same( + left_directory=source_path, right_directory=destination_parent_path.joinpath(destination_name) + ) # Test install of file # Test naming according to source prep_test_folders() - compile_sketches.install_from_path(source_path=test_file_path, - destination_parent_path=destination_parent_path, - destination_name=None) - assert filecmp.cmp(f1=test_file_path, - f2=destination_parent_path.joinpath(test_file_path.name)) + compile_sketches.install_from_path( + source_path=test_file_path, destination_parent_path=destination_parent_path, destination_name=None + ) + assert filecmp.cmp(f1=test_file_path, f2=destination_parent_path.joinpath(test_file_path.name)) # Test custom folder name prep_test_folders() destination_name = "foo-destination-name" - compile_sketches.install_from_path(source_path=test_file_path, - destination_parent_path=destination_parent_path, - destination_name=destination_name) - assert filecmp.cmp(f1=test_file_path, - f2=destination_parent_path.joinpath(destination_name)) + compile_sketches.install_from_path( + source_path=test_file_path, destination_parent_path=destination_parent_path, destination_name=destination_name + ) + assert filecmp.cmp(f1=test_file_path, f2=destination_parent_path.joinpath(destination_name)) def test_path_is_sketch(): @@ -1376,29 +1531,26 @@ def test_path_is_sketch(): assert compilesketches.path_is_sketch(path=test_data_path.joinpath("HasSketches", "Sketch1", "Sketch1.ino")) is True # Not a sketch file - assert compilesketches.path_is_sketch( - path=test_data_path.joinpath("NoSketches", "NotSketch", "NotSketch.foo")) is False + assert ( + compilesketches.path_is_sketch(path=test_data_path.joinpath("NoSketches", "NotSketch", "NotSketch.foo")) + is False + ) # Sketch folder with .ino sketch file - assert compilesketches.path_is_sketch( - path=test_data_path.joinpath("HasSketches", "Sketch1")) is True + assert compilesketches.path_is_sketch(path=test_data_path.joinpath("HasSketches", "Sketch1")) is True # Sketch folder with .pde sketch file - assert compilesketches.path_is_sketch( - path=test_data_path.joinpath("HasSketches", "Sketch2")) is True + assert compilesketches.path_is_sketch(path=test_data_path.joinpath("HasSketches", "Sketch2")) is True # No files in path - assert compilesketches.path_is_sketch( - path=test_data_path.joinpath("HasSketches")) is False + assert compilesketches.path_is_sketch(path=test_data_path.joinpath("HasSketches")) is False # Not a sketch folder - assert compilesketches.path_is_sketch( - path=test_data_path.joinpath("NoSketches", "NotSketch")) is False + assert compilesketches.path_is_sketch(path=test_data_path.joinpath("NoSketches", "NotSketch")) is False @pytest.mark.parametrize("clean_build_cache", [True, False]) -@pytest.mark.parametrize("returncode, expected_success", [(1, False), - (0, True)]) +@pytest.mark.parametrize("returncode, expected_success", [(1, False), (0, True)]) def test_compile_sketch(capsys, mocker, clean_build_cache, returncode, expected_success): stdout = unittest.mock.sentinel.stdout sketch_path = pathlib.Path("FooSketch", "FooSketch.ino").resolve() @@ -1414,15 +1566,13 @@ class CompilationData: compile_sketches = get_compilesketches_object() - mocker.patch("compilesketches.CompileSketches.run_arduino_cli_command", autospec=True, - return_value=CompilationData()) + mocker.patch( + "compilesketches.CompileSketches.run_arduino_cli_command", autospec=True, return_value=CompilationData() + ) mocker.patch.object(pathlib.Path, "glob", autospec=True, return_value=build_cache_paths) mocker.patch("shutil.rmtree", autospec=True) - compilation_result = compile_sketches.compile_sketch( - sketch_path=sketch_path, - clean_build_cache=clean_build_cache - ) + compilation_result = compile_sketches.compile_sketch(sketch_path=sketch_path, clean_build_cache=clean_build_cache) if clean_build_cache: rmtree_calls = [] @@ -1433,8 +1583,11 @@ class CompilationData: shutil.rmtree.assert_has_calls(calls=rmtree_calls) expected_stdout = ( - "::group::Compiling sketch: " + str(compilesketches.path_relative_to_workspace(path=sketch_path)) + "\n" - + str(stdout) + "\n" + "::group::Compiling sketch: " + + str(compilesketches.path_relative_to_workspace(path=sketch_path)) + + "\n" + + str(stdout) + + "\n" + "::endgroup::" ) if not expected_success: @@ -1483,16 +1636,16 @@ def checkout(self): compile_sketches = get_compilesketches_object(enable_warnings_report=enable_warnings_report) - mocker.patch("compilesketches.CompileSketches.get_sizes_from_output", autospec=True, - side_effect=sizes_list) - mocker.patch("compilesketches.CompileSketches.get_warning_count_from_output", autospec=True, - side_effect=warning_count_list) - mocker.patch("compilesketches.CompileSketches.do_deltas_report", autospec=True, - return_value=do_deltas_report) + mocker.patch("compilesketches.CompileSketches.get_sizes_from_output", autospec=True, side_effect=sizes_list) + mocker.patch( + "compilesketches.CompileSketches.get_warning_count_from_output", autospec=True, side_effect=warning_count_list + ) + mocker.patch("compilesketches.CompileSketches.do_deltas_report", autospec=True, return_value=do_deltas_report) mocker.patch("git.Repo", autospec=True, return_value=Repo()) mocker.patch("compilesketches.CompileSketches.checkout_deltas_base_ref", autospec=True) - mocker.patch("compilesketches.CompileSketches.compile_sketch", autospec=True, - return_value=previous_compilation_result) + mocker.patch( + "compilesketches.CompileSketches.compile_sketch", autospec=True, return_value=previous_compilation_result + ) mocker.patch.object(Repo, "checkout") mocker.patch("compilesketches.CompileSketches.get_sizes_report", autospec=True, return_value=sizes_report) mocker.patch("compilesketches.CompileSketches.get_warnings_report", autospec=True, return_value=warnings_report) @@ -1502,7 +1655,8 @@ def checkout(self): get_sizes_from_output_calls = [unittest.mock.call(compile_sketches, compilation_result=compilation_result)] if enable_warnings_report == "true": get_warning_count_from_output_calls = [ - unittest.mock.call(compile_sketches, compilation_result=compilation_result)] + unittest.mock.call(compile_sketches, compilation_result=compilation_result) + ] else: get_warning_count_from_output_calls = [] @@ -1511,22 +1665,28 @@ def checkout(self): else: expected_current_warnings = None # noinspection PyUnresolvedReferences - compilesketches.CompileSketches.do_deltas_report.assert_called_once_with(compile_sketches, - compilation_result=compilation_result, - current_sizes=sizes_list[0], - current_warnings=expected_current_warnings) + compilesketches.CompileSketches.do_deltas_report.assert_called_once_with( + compile_sketches, + compilation_result=compilation_result, + current_sizes=sizes_list[0], + current_warnings=expected_current_warnings, + ) if do_deltas_report: git.Repo.assert_called_once_with(path=os.environ["GITHUB_WORKSPACE"]) compile_sketches.checkout_deltas_base_ref.assert_called_once() - compile_sketches.compile_sketch.assert_called_once_with(compile_sketches, - sketch_path=compilation_result.sketch, - clean_build_cache=(enable_warnings_report == "true")) + compile_sketches.compile_sketch.assert_called_once_with( + compile_sketches, + sketch_path=compilation_result.sketch, + clean_build_cache=(enable_warnings_report == "true"), + ) Repo.checkout.assert_called_once_with(original_git_ref, recurse_submodules=True) get_sizes_from_output_calls.append( - unittest.mock.call(compile_sketches, compilation_result=previous_compilation_result)) + unittest.mock.call(compile_sketches, compilation_result=previous_compilation_result) + ) if enable_warnings_report == "true": get_warning_count_from_output_calls.append( - unittest.mock.call(compile_sketches, compilation_result=previous_compilation_result)) + unittest.mock.call(compile_sketches, compilation_result=previous_compilation_result) + ) expected_previous_sizes = sizes_list[1] expected_previous_warnings = warning_count_list[1] @@ -1534,20 +1694,20 @@ def checkout(self): expected_previous_sizes = None expected_previous_warnings = None - compilesketches.CompileSketches.get_sizes_from_output.assert_has_calls( - calls=get_sizes_from_output_calls) + compilesketches.CompileSketches.get_sizes_from_output.assert_has_calls(calls=get_sizes_from_output_calls) compilesketches.CompileSketches.get_warning_count_from_output.assert_has_calls( - calls=get_warning_count_from_output_calls) + calls=get_warning_count_from_output_calls + ) - compile_sketches.get_sizes_report.assert_called_once_with(compile_sketches, - current_sizes=sizes_list[0], - previous_sizes=expected_previous_sizes) + compile_sketches.get_sizes_report.assert_called_once_with( + compile_sketches, current_sizes=sizes_list[0], previous_sizes=expected_previous_sizes + ) if enable_warnings_report == "true": # noinspection PyUnresolvedReferences - compile_sketches.get_warnings_report.assert_called_once_with(compile_sketches, - current_warnings=warning_count_list[0], - previous_warnings=expected_previous_warnings) + compile_sketches.get_warnings_report.assert_called_once_with( + compile_sketches, current_warnings=warning_count_list[0], previous_warnings=expected_previous_warnings + ) expected_sketch_report = { compile_sketches.ReportKeys.name: ( @@ -1563,130 +1723,140 @@ def checkout(self): @pytest.mark.parametrize( "compilation_success, compilation_output, flash, maximum_flash, relative_flash, ram, maximum_ram, relative_ram", - [(False, - "foo output", - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator), - (True, - "/home/per/.arduino15/packages/arduino/hardware/megaavr/1.8.5/cores/arduino/NANO_compat.cpp:23:2: warning: #warni" - "ng \"ATMEGA328 registers emulation is enabled. You may encounter some speed issue. Please consider to disable it" - " in the Tools menu\" [-Wcpp]\n" - " #warning \"ATMEGA328 registers emulation is enabled. You may encounter some speed issue. Please consider to dis" - "able it in the Tools menu\"\n" - " ^~~~~~~\n" - "Sketch uses {flash} bytes (1%) of program storage space. Maximum is {maximum_flash} bytes.\n" - "Global variables use {ram} bytes (0%) of dynamic memory, leaving 6122 bytes for local variables. Maximum is" - " {maximum_ram} bytes.\n", - 802, 1604, 50.0, 22, 33, 66.67), - (True, - "In file included from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd21/in" - "clude/samd21.h:69:0,\n" - " from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd.h:10" - "5,\n" - " from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/sam.h:540" - ",\n" - " from /home/per/.arduino15/packages/arduino/hardware/samd/1.8.6/cores/arduino/Arduino.h:48,\n" - " from /home/per/Arduino/libraries/Arduino_MKRGPS/src/GPS.h:23,\n" - " from /home/per/Arduino/libraries/Arduino_MKRGPS/src/GPS.cpp:28:\n" - "/home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd21/include/samd21g18a.h:226" - ":0: warning: \"LITTLE_ENDIAN\" redefined\n" - " #define LITTLE_ENDIAN 1\n" - " \n" - "In file included from /home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/inclu" - "de/sys/types.h:67:0,\n" - " from /home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/inclu" - "de/stdio.h:61,\n" - " from /home/per/Arduino/libraries/Arduino_MKRGPS/src/minmea/minmea.h:16,\n" - " from /home/per/Arduino/libraries/Arduino_MKRGPS/src/GPS.cpp:23:\n" - "/home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/include/machine/endian.h:17" - ":0: note: this is the location of the previous definition\n" - " #define LITTLE_ENDIAN _LITTLE_ENDIAN\n" - " \n" - "Sketch uses {flash} bytes (12%) of program storage space. Maximum is {maximum_flash} bytes.\n" - "Global variables use {ram} bytes of dynamic memory.\n", - 32740, - 32740, - 100.0, - 3648, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator), - (True, - "/home/per/Arduino/libraries/Servo/src/samd/Servo.cpp: In function 'void _initISR(Tc*, uint8_t, uint32_t, IRQn_Ty" - "pe, uint8_t, uint8_t)':\n" - "/home/per/Arduino/libraries/Servo/src/samd/Servo.cpp:120:56: warning: unused parameter 'id' [-Wunused-parameter]" - "\n" - " static void _initISR(Tc *tc, uint8_t channel, uint32_t id, IRQn_Type irqn, uint8_t gcmForTimer, uint8_t intEnab" - " leBit)\n" - " ^~\n" - "/home/per/Arduino/libraries/Servo/src/samd/Servo.cpp: In function 'void finISR(timer16_Sequence_t)':\n" - "/home/per/Arduino/libraries/Servo/src/samd/Servo.cpp:174:39: warning: unused parameter 'timer' [-Wunused-paramet" - "er]\n" - " static void finISR(timer16_Sequence_t timer)\n" - " ^~~~~\n" - "Sketch uses {flash} bytes (4%) of program storage space. Maximum is {maximum_flash} bytes.\n", - 12636, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator), - (True, - "In file included from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd21/in" - "clude/samd21.h:69:0,\n" - " from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd.h:10" - "5,\n" - " from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/sam.h:540" - ",\n" - " from /home/per/.arduino15/packages/arduino/hardware/samd/1.8.6/cores/arduino/Arduino.h:48,\n" - " from /home/per/Arduino/libraries/RTCZero/src/RTCZero.h:23,\n" - " from /home/per/Arduino/libraries/RTCZero/src/RTCZero.cpp:22:\n" - "/home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd21/include/samd21g18a.h:226" - ":0: warning: \"LITTLE_ENDIAN\" redefined\n" - " #define LITTLE_ENDIAN 1\n" - " \n" - "In file included from /home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/inclu" - "de/sys/types.h:67:0,\n" - " from /home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/inclu" - "de/time.h:28,\n" - " from /home/per/Arduino/libraries/RTCZero/src/RTCZero.cpp:20:\n" - "/home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/include/machine/endian.h:17" - ":0: note: this is the location of the previous definition\n" - " #define LITTLE_ENDIAN _LITTLE_ENDIAN\n" - " \n" - "/home/per/Arduino/libraries/RTCZero/src/RTCZero.cpp: In member function 'void RTCZero::begin(bool)':\n" - "/home/per/Arduino/libraries/RTCZero/src/RTCZero.cpp:96:26: warning: 'oldTime.RTC_MODE2_CLOCK_Type::reg' may be u" - "sed uninitialized in this function [-Wmaybe-uninitialized]\n" - " RTC->MODE2.CLOCK.reg = oldTime.reg;\n" - "Couldn't determine program size", - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator, - get_compilesketches_object().not_applicable_indicator)] + [ + ( + False, + "foo output", + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + ), + ( + True, + "/home/per/.arduino15/packages/arduino/hardware/megaavr/1.8.5/cores/arduino/NANO_compat.cpp:23:2: warning: #warni" + 'ng "ATMEGA328 registers emulation is enabled. You may encounter some speed issue. Please consider to disable it' + ' in the Tools menu" [-Wcpp]\n' + ' #warning "ATMEGA328 registers emulation is enabled. You may encounter some speed issue. Please consider to dis' + 'able it in the Tools menu"\n' + " ^~~~~~~\n" + "Sketch uses {flash} bytes (1%) of program storage space. Maximum is {maximum_flash} bytes.\n" + "Global variables use {ram} bytes (0%) of dynamic memory, leaving 6122 bytes for local variables. Maximum is" + " {maximum_ram} bytes.\n", + 802, + 1604, + 50.0, + 22, + 33, + 66.67, + ), + ( + True, + "In file included from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd21/in" + "clude/samd21.h:69:0,\n" + " from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd.h:10" + "5,\n" + " from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/sam.h:540" + ",\n" + " from /home/per/.arduino15/packages/arduino/hardware/samd/1.8.6/cores/arduino/Arduino.h:48,\n" + " from /home/per/Arduino/libraries/Arduino_MKRGPS/src/GPS.h:23,\n" + " from /home/per/Arduino/libraries/Arduino_MKRGPS/src/GPS.cpp:28:\n" + "/home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd21/include/samd21g18a.h:226" + ':0: warning: "LITTLE_ENDIAN" redefined\n' + " #define LITTLE_ENDIAN 1\n" + " \n" + "In file included from /home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/inclu" + "de/sys/types.h:67:0,\n" + " from /home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/inclu" + "de/stdio.h:61,\n" + " from /home/per/Arduino/libraries/Arduino_MKRGPS/src/minmea/minmea.h:16,\n" + " from /home/per/Arduino/libraries/Arduino_MKRGPS/src/GPS.cpp:23:\n" + "/home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/include/machine/endian.h:17" + ":0: note: this is the location of the previous definition\n" + " #define LITTLE_ENDIAN _LITTLE_ENDIAN\n" + " \n" + "Sketch uses {flash} bytes (12%) of program storage space. Maximum is {maximum_flash} bytes.\n" + "Global variables use {ram} bytes of dynamic memory.\n", + 32740, + 32740, + 100.0, + 3648, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + ), + ( + True, + "/home/per/Arduino/libraries/Servo/src/samd/Servo.cpp: In function 'void _initISR(Tc*, uint8_t, uint32_t, IRQn_Ty" + "pe, uint8_t, uint8_t)':\n" + "/home/per/Arduino/libraries/Servo/src/samd/Servo.cpp:120:56: warning: unused parameter 'id' [-Wunused-parameter]" + "\n" + " static void _initISR(Tc *tc, uint8_t channel, uint32_t id, IRQn_Type irqn, uint8_t gcmForTimer, uint8_t intEnab" + " leBit)\n" + " ^~\n" + "/home/per/Arduino/libraries/Servo/src/samd/Servo.cpp: In function 'void finISR(timer16_Sequence_t)':\n" + "/home/per/Arduino/libraries/Servo/src/samd/Servo.cpp:174:39: warning: unused parameter 'timer' [-Wunused-paramet" + "er]\n" + " static void finISR(timer16_Sequence_t timer)\n" + " ^~~~~\n" + "Sketch uses {flash} bytes (4%) of program storage space. Maximum is {maximum_flash} bytes.\n", + 12636, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + ), + ( + True, + "In file included from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd21/in" + "clude/samd21.h:69:0,\n" + " from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd.h:10" + "5,\n" + " from /home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/sam.h:540" + ",\n" + " from /home/per/.arduino15/packages/arduino/hardware/samd/1.8.6/cores/arduino/Arduino.h:48,\n" + " from /home/per/Arduino/libraries/RTCZero/src/RTCZero.h:23,\n" + " from /home/per/Arduino/libraries/RTCZero/src/RTCZero.cpp:22:\n" + "/home/per/.arduino15/packages/arduino/tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd21/include/samd21g18a.h:226" + ':0: warning: "LITTLE_ENDIAN" redefined\n' + " #define LITTLE_ENDIAN 1\n" + " \n" + "In file included from /home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/inclu" + "de/sys/types.h:67:0,\n" + " from /home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/inclu" + "de/time.h:28,\n" + " from /home/per/Arduino/libraries/RTCZero/src/RTCZero.cpp:20:\n" + "/home/per/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/include/machine/endian.h:17" + ":0: note: this is the location of the previous definition\n" + " #define LITTLE_ENDIAN _LITTLE_ENDIAN\n" + " \n" + "/home/per/Arduino/libraries/RTCZero/src/RTCZero.cpp: In member function 'void RTCZero::begin(bool)':\n" + "/home/per/Arduino/libraries/RTCZero/src/RTCZero.cpp:96:26: warning: 'oldTime.RTC_MODE2_CLOCK_Type::reg' may be u" + "sed uninitialized in this function [-Wmaybe-uninitialized]\n" + " RTC->MODE2.CLOCK.reg = oldTime.reg;\n" + "Couldn't determine program size", + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + get_compilesketches_object().not_applicable_indicator, + ), + ], ) -def test_get_sizes_from_output(compilation_success, - compilation_output, - flash, - maximum_flash, - relative_flash, - ram, - maximum_ram, - relative_ram): +def test_get_sizes_from_output( + compilation_success, compilation_output, flash, maximum_flash, relative_flash, ram, maximum_ram, relative_ram +): sketch_path = pathlib.PurePath("foo/bar") - compilation_output = compilation_output.format(flash=str(flash), - maximum_flash=str(maximum_flash), - ram=str(ram), - maximum_ram=str(maximum_ram)) + compilation_output = compilation_output.format( + flash=str(flash), maximum_flash=str(maximum_flash), ram=str(ram), maximum_ram=str(maximum_ram) + ) compile_sketches = get_compilesketches_object() - compilation_result = type("CompilationResult", (), - {"sketch": sketch_path, - "success": compilation_success, - "output": compilation_output}) + compilation_result = type( + "CompilationResult", (), {"sketch": sketch_path, "success": compilation_success, "output": compilation_output} + ) sizes = compile_sketches.get_sizes_from_output(compilation_result=compilation_result) @@ -1695,42 +1865,48 @@ def test_get_sizes_from_output(compilation_success, compile_sketches.ReportKeys.name: "flash", compile_sketches.ReportKeys.absolute: flash, compile_sketches.ReportKeys.maximum: maximum_flash, - compile_sketches.ReportKeys.relative: relative_flash + compile_sketches.ReportKeys.relative: relative_flash, }, { compile_sketches.ReportKeys.name: "RAM for global variables", compile_sketches.ReportKeys.absolute: ram, compile_sketches.ReportKeys.maximum: maximum_ram, - compile_sketches.ReportKeys.relative: relative_ram - } + compile_sketches.ReportKeys.relative: relative_ram, + }, ] @pytest.mark.parametrize( "compilation_output, memory_type, size_data_type, expected_output", - [("foo output", - { - "name": "RAM for global variables", - "regex": { - get_compilesketches_object().ReportKeys.maximum: ( - r"Global variables use [0-9]+ bytes .*of dynamic memory.*\. Maximum is ([0-9]+) bytes." - ) - } - }, - get_compilesketches_object().ReportKeys.maximum, - None), - ("Global variables use 11 bytes (0%) of dynamic memory, leaving 22 bytes for local variables. Maximum is" - + " {expected_output} bytes.", - { - "name": "RAM for global variables", - "regex": { - get_compilesketches_object().ReportKeys.maximum: ( - r"Global variables use [0-9]+ bytes .*of dynamic memory.*\. Maximum is ([0-9]+) bytes." - ) - } - }, - get_compilesketches_object().ReportKeys.maximum, - 42)] + [ + ( + "foo output", + { + "name": "RAM for global variables", + "regex": { + get_compilesketches_object().ReportKeys.maximum: ( + r"Global variables use [0-9]+ bytes .*of dynamic memory.*\. Maximum is ([0-9]+) bytes." + ) + }, + }, + get_compilesketches_object().ReportKeys.maximum, + None, + ), + ( + "Global variables use 11 bytes (0%) of dynamic memory, leaving 22 bytes for local variables. Maximum is" + + " {expected_output} bytes.", + { + "name": "RAM for global variables", + "regex": { + get_compilesketches_object().ReportKeys.maximum: ( + r"Global variables use [0-9]+ bytes .*of dynamic memory.*\. Maximum is ([0-9]+) bytes." + ) + }, + }, + get_compilesketches_object().ReportKeys.maximum, + 42, + ), + ], ) def test_get_size_data_from_output(capsys, compilation_output, memory_type, size_data_type, expected_output): compilation_output = compilation_output.format(expected_output=str(expected_output)) @@ -1742,7 +1918,9 @@ def test_get_size_data_from_output(capsys, compilation_output, memory_type, size assert size_data == expected_output if expected_output is None: expected_stdout = ( - "::warning::Unable to determine the: \"" + str(size_data_type) + "\" value for memory type: \"" + '::warning::Unable to determine the: "' + + str(size_data_type) + + '" value for memory type: "' + memory_type["name"] + "\". The board's platform may not have been configured to provide this information." ) @@ -1751,21 +1929,23 @@ def test_get_size_data_from_output(capsys, compilation_output, memory_type, size @pytest.mark.parametrize( "compilation_success, test_compilation_output_filename, expected_warning_count", - [(True, - pathlib.Path("test_get_warning_count_from_output", "has-warnings.txt"), - 45), - (True, - pathlib.Path("test_get_warning_count_from_output", "no-warnings.txt"), - 0), - (False, - pathlib.Path("test_get_warning_count_from_output", "has-warnings.txt"), - get_compilesketches_object().not_applicable_indicator)]) + [ + (True, pathlib.Path("test_get_warning_count_from_output", "has-warnings.txt"), 45), + (True, pathlib.Path("test_get_warning_count_from_output", "no-warnings.txt"), 0), + ( + False, + pathlib.Path("test_get_warning_count_from_output", "has-warnings.txt"), + get_compilesketches_object().not_applicable_indicator, + ), + ], +) def test_get_warning_count_from_output(compilation_success, test_compilation_output_filename, expected_warning_count): compile_sketches = get_compilesketches_object() - with open(file=test_data_path.joinpath(test_compilation_output_filename), - mode='r', - encoding="utf-8") as test_compilation_output_file: + with open( + file=test_data_path.joinpath(test_compilation_output_filename), mode="r", encoding="utf-8" + ) as test_compilation_output_file: + class CompilationResult: success = compilation_success output = test_compilation_output_file.read() @@ -1774,72 +1954,114 @@ class CompilationResult: @pytest.mark.parametrize( - "enable_deltas_report," - "compilation_success," - "current_sizes," - "current_warnings," - "do_deltas_report_expected", - [("true", - True, - [{compilesketches.CompileSketches.ReportKeys.name: "foo", - compilesketches.CompileSketches.ReportKeys.absolute: 24}, - {compilesketches.CompileSketches.ReportKeys.name: "bar", - compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator}], - compilesketches.CompileSketches.not_applicable_indicator, - True), - ("true", - True, - [{compilesketches.CompileSketches.ReportKeys.name: "foo", - compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator}, - {compilesketches.CompileSketches.ReportKeys.name: "bar", - compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator}], - 42, - True), - ("false", - True, - [{compilesketches.CompileSketches.ReportKeys.name: "foo", - compilesketches.CompileSketches.ReportKeys.absolute: 24}], - True, - False), - ("true", - False, - [{compilesketches.CompileSketches.ReportKeys.name: "foo", - compilesketches.CompileSketches.ReportKeys.absolute: 24}], - 42, - False), - ("true", - True, - [{compilesketches.CompileSketches.ReportKeys.name: "foo", - compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator}, - {compilesketches.CompileSketches.ReportKeys.name: "bar", - compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator}], - compilesketches.CompileSketches.not_applicable_indicator, - False), - ("true", - True, - [{compilesketches.CompileSketches.ReportKeys.name: "foo", - compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator}, - {compilesketches.CompileSketches.ReportKeys.name: "bar", - compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator}], - None, - False) - ] + "enable_deltas_report," "compilation_success," "current_sizes," "current_warnings," "do_deltas_report_expected", + [ + ( + "true", + True, + [ + { + compilesketches.CompileSketches.ReportKeys.name: "foo", + compilesketches.CompileSketches.ReportKeys.absolute: 24, + }, + { + compilesketches.CompileSketches.ReportKeys.name: "bar", + compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator, + }, + ], + compilesketches.CompileSketches.not_applicable_indicator, + True, + ), + ( + "true", + True, + [ + { + compilesketches.CompileSketches.ReportKeys.name: "foo", + compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator, + }, + { + compilesketches.CompileSketches.ReportKeys.name: "bar", + compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator, + }, + ], + 42, + True, + ), + ( + "false", + True, + [ + { + compilesketches.CompileSketches.ReportKeys.name: "foo", + compilesketches.CompileSketches.ReportKeys.absolute: 24, + } + ], + True, + False, + ), + ( + "true", + False, + [ + { + compilesketches.CompileSketches.ReportKeys.name: "foo", + compilesketches.CompileSketches.ReportKeys.absolute: 24, + } + ], + 42, + False, + ), + ( + "true", + True, + [ + { + compilesketches.CompileSketches.ReportKeys.name: "foo", + compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator, + }, + { + compilesketches.CompileSketches.ReportKeys.name: "bar", + compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator, + }, + ], + compilesketches.CompileSketches.not_applicable_indicator, + False, + ), + ( + "true", + True, + [ + { + compilesketches.CompileSketches.ReportKeys.name: "foo", + compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator, + }, + { + compilesketches.CompileSketches.ReportKeys.name: "bar", + compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator, + }, + ], + None, + False, + ), + ], ) -def test_do_deltas_report(monkeypatch, - enable_deltas_report, - compilation_success, - current_sizes, - current_warnings, - do_deltas_report_expected): +def test_do_deltas_report( + monkeypatch, enable_deltas_report, compilation_success, current_sizes, current_warnings, do_deltas_report_expected +): compile_sketches = get_compilesketches_object(enable_deltas_report=enable_deltas_report) - compilation_result = type("CompilationResult", (), - {"sketch": "/foo/SketchName", - "success": compilation_success, - "output": "foo compilation output"}) - assert compile_sketches.do_deltas_report(compilation_result=compilation_result, - current_sizes=current_sizes, - current_warnings=current_warnings) == do_deltas_report_expected + compilation_result = type( + "CompilationResult", + (), + {"sketch": "/foo/SketchName", "success": compilation_success, "output": "foo compilation output"}, + ) + assert ( + compile_sketches.do_deltas_report( + compilation_result=compilation_result, current_sizes=current_sizes, current_warnings=current_warnings + ) + == do_deltas_report_expected + ) def test_checkout_deltas_base_ref(monkeypatch, mocker): @@ -1866,12 +2088,14 @@ def checkout(self): compile_sketches.checkout_deltas_base_ref() git.Repo.assert_called_once_with(path=os.environ["GITHUB_WORKSPACE"]) - Repo.fetch.assert_called_once_with(refspec=deltas_base_ref, - verbose=compile_sketches.verbose, - no_tags=True, - prune=True, - depth=1, - recurse_submodules=True) + Repo.fetch.assert_called_once_with( + refspec=deltas_base_ref, + verbose=compile_sketches.verbose, + no_tags=True, + prune=True, + depth=1, + recurse_submodules=True, + ) Repo.checkout.assert_called_once_with(deltas_base_ref, recurse_submodules=True) @@ -1888,9 +2112,9 @@ def test_get_sizes_report(mocker): get_size_report_calls = [] for current_size, previous_size in zip(current_sizes, previous_sizes): - get_size_report_calls.append(unittest.mock.call(compile_sketches, - current_size=current_size, - previous_size=previous_size)) + get_size_report_calls.append( + unittest.mock.call(compile_sketches, current_size=current_size, previous_size=previous_size) + ) compile_sketches.get_size_report.assert_has_calls(get_size_report_calls) @@ -1902,60 +2126,67 @@ def test_get_sizes_report(mocker): get_size_report_calls = [] for current_size in current_sizes: - get_size_report_calls.append(unittest.mock.call(compile_sketches, - current_size=current_size, - previous_size=None)) + get_size_report_calls.append( + unittest.mock.call(compile_sketches, current_size=current_size, previous_size=None) + ) compile_sketches.get_size_report.assert_has_calls(get_size_report_calls) @pytest.mark.parametrize( "size_maximum, current_absolute, previous_size, expected_absolute_delta, expected_relative_delta", - [(compilesketches.CompileSketches.not_applicable_indicator, - compilesketches.CompileSketches.not_applicable_indicator, - {compilesketches.CompileSketches.ReportKeys.absolute: 11, - compilesketches.CompileSketches.ReportKeys.relative: 9.91}, - compilesketches.CompileSketches.not_applicable_indicator, - compilesketches.CompileSketches.not_applicable_indicator), - (111, - 42, - {compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator, - compilesketches.CompileSketches.ReportKeys.relative: compilesketches.CompileSketches.not_applicable_indicator}, - compilesketches.CompileSketches.not_applicable_indicator, - compilesketches.CompileSketches.not_applicable_indicator), - (111, - 42, - {compilesketches.CompileSketches.ReportKeys.absolute: 11, - compilesketches.CompileSketches.ReportKeys.relative: 9.91}, - 31, - 27.93), - (111, - 42, - None, - None, - None)] + [ + ( + compilesketches.CompileSketches.not_applicable_indicator, + compilesketches.CompileSketches.not_applicable_indicator, + { + compilesketches.CompileSketches.ReportKeys.absolute: 11, + compilesketches.CompileSketches.ReportKeys.relative: 9.91, + }, + compilesketches.CompileSketches.not_applicable_indicator, + compilesketches.CompileSketches.not_applicable_indicator, + ), + ( + 111, + 42, + { + compilesketches.CompileSketches.ReportKeys.absolute: compilesketches.CompileSketches.not_applicable_indicator, + compilesketches.CompileSketches.ReportKeys.relative: compilesketches.CompileSketches.not_applicable_indicator, + }, + compilesketches.CompileSketches.not_applicable_indicator, + compilesketches.CompileSketches.not_applicable_indicator, + ), + ( + 111, + 42, + { + compilesketches.CompileSketches.ReportKeys.absolute: 11, + compilesketches.CompileSketches.ReportKeys.relative: 9.91, + }, + 31, + 27.93, + ), + (111, 42, None, None, None), + ], ) -def test_get_size_report(capsys, - size_maximum, - current_absolute, - previous_size, - expected_absolute_delta, - expected_relative_delta): +def test_get_size_report( + capsys, size_maximum, current_absolute, previous_size, expected_absolute_delta, expected_relative_delta +): size_name = "Foo size name" current_relative = 42 current_size = { compilesketches.CompileSketches.ReportKeys.name: size_name, compilesketches.CompileSketches.ReportKeys.maximum: size_maximum, compilesketches.CompileSketches.ReportKeys.absolute: current_absolute, - compilesketches.CompileSketches.ReportKeys.relative: current_relative + compilesketches.CompileSketches.ReportKeys.relative: current_relative, } expected_size_report = { compilesketches.CompileSketches.ReportKeys.name: size_name, compilesketches.CompileSketches.ReportKeys.maximum: size_maximum, compilesketches.CompileSketches.ReportKeys.current: { compilesketches.CompileSketches.ReportKeys.absolute: current_absolute, - compilesketches.CompileSketches.ReportKeys.relative: current_relative - } + compilesketches.CompileSketches.ReportKeys.relative: current_relative, + }, } compile_sketches = get_compilesketches_object() @@ -1967,19 +2198,26 @@ def test_get_size_report(capsys, else: expected_size_report[compilesketches.CompileSketches.ReportKeys.previous] = { compilesketches.CompileSketches.ReportKeys.absolute: previous_size[ - compilesketches.CompileSketches.ReportKeys.absolute], + compilesketches.CompileSketches.ReportKeys.absolute + ], compilesketches.CompileSketches.ReportKeys.relative: previous_size[ - compilesketches.CompileSketches.ReportKeys.relative] + compilesketches.CompileSketches.ReportKeys.relative + ], } expected_size_report[compilesketches.CompileSketches.ReportKeys.delta] = { compilesketches.CompileSketches.ReportKeys.absolute: expected_absolute_delta, - compilesketches.CompileSketches.ReportKeys.relative: expected_relative_delta + compilesketches.CompileSketches.ReportKeys.relative: expected_relative_delta, } if expected_relative_delta == compilesketches.CompileSketches.not_applicable_indicator: assert capsys.readouterr().out.strip() == ("Change in " + size_name + ": " + str(expected_absolute_delta)) else: assert capsys.readouterr().out.strip() == ( - "Change in " + size_name + ": " + str(expected_absolute_delta) + " (" + str(expected_relative_delta) + "Change in " + + size_name + + ": " + + str(expected_absolute_delta) + + " (" + + str(expected_relative_delta) + "%)" ) @@ -1988,49 +2226,58 @@ def test_get_size_report(capsys, @pytest.mark.parametrize( "current_warnings, previous_warnings, expected_report", - [(42, - None, - { - compilesketches.CompileSketches.ReportKeys.current: { - compilesketches.CompileSketches.ReportKeys.absolute: 42 - } - }), - (42, - compilesketches.CompileSketches.not_applicable_indicator, - { - compilesketches.CompileSketches.ReportKeys.current: { - compilesketches.CompileSketches.ReportKeys.absolute: 42 - }, - compilesketches.CompileSketches.ReportKeys.previous: { - compilesketches.CompileSketches.ReportKeys.absolute: ( - compilesketches.CompileSketches.not_applicable_indicator - ) - }, - compilesketches.CompileSketches.ReportKeys.delta: { - compilesketches.CompileSketches.ReportKeys.absolute: ( - compilesketches.CompileSketches.not_applicable_indicator - ) - } - }), - (42, - 43, - { - compilesketches.CompileSketches.ReportKeys.current: { - compilesketches.CompileSketches.ReportKeys.absolute: 42 - }, - compilesketches.CompileSketches.ReportKeys.previous: { - compilesketches.CompileSketches.ReportKeys.absolute: 43 - }, - compilesketches.CompileSketches.ReportKeys.delta: { - compilesketches.CompileSketches.ReportKeys.absolute: -1 - } - })]) + [ + ( + 42, + None, + { + compilesketches.CompileSketches.ReportKeys.current: { + compilesketches.CompileSketches.ReportKeys.absolute: 42 + } + }, + ), + ( + 42, + compilesketches.CompileSketches.not_applicable_indicator, + { + compilesketches.CompileSketches.ReportKeys.current: { + compilesketches.CompileSketches.ReportKeys.absolute: 42 + }, + compilesketches.CompileSketches.ReportKeys.previous: { + compilesketches.CompileSketches.ReportKeys.absolute: ( + compilesketches.CompileSketches.not_applicable_indicator + ) + }, + compilesketches.CompileSketches.ReportKeys.delta: { + compilesketches.CompileSketches.ReportKeys.absolute: ( + compilesketches.CompileSketches.not_applicable_indicator + ) + }, + }, + ), + ( + 42, + 43, + { + compilesketches.CompileSketches.ReportKeys.current: { + compilesketches.CompileSketches.ReportKeys.absolute: 42 + }, + compilesketches.CompileSketches.ReportKeys.previous: { + compilesketches.CompileSketches.ReportKeys.absolute: 43 + }, + compilesketches.CompileSketches.ReportKeys.delta: { + compilesketches.CompileSketches.ReportKeys.absolute: -1 + }, + }, + ), + ], +) def test_get_warnings_report(current_warnings, previous_warnings, expected_report): compile_sketches = get_compilesketches_object() - assert compile_sketches.get_warnings_report( - current_warnings=current_warnings, - previous_warnings=previous_warnings - ) == expected_report + assert ( + compile_sketches.get_warnings_report(current_warnings=current_warnings, previous_warnings=previous_warnings) + == expected_report + ) def test_get_sketches_report(monkeypatch, mocker): @@ -2046,38 +2293,41 @@ def test_get_sketches_report(monkeypatch, mocker): warnings_summary_report = unittest.mock.sentinel.warnings_summary_report sketch_report_list = unittest.mock.sentinel.sketch_report_list - mocker.patch("compilesketches.CompileSketches.get_sizes_summary_report", - autospec=True, - return_value=sizes_summary_report) + mocker.patch( + "compilesketches.CompileSketches.get_sizes_summary_report", autospec=True, return_value=sizes_summary_report + ) - mocker.patch("compilesketches.CompileSketches.get_warnings_summary_report", - autospec=True, - return_value=warnings_summary_report) + mocker.patch( + "compilesketches.CompileSketches.get_warnings_summary_report", + autospec=True, + return_value=warnings_summary_report, + ) compile_sketches = get_compilesketches_object(fqbn_arg=fqbn_arg) assert compile_sketches.get_sketches_report(sketch_report_list=sketch_report_list) == { compilesketches.CompileSketches.ReportKeys.commit_hash: current_git_ref, - compilesketches.CompileSketches.ReportKeys.commit_url: ("https://github.com/" - + github_repository - + "/commit/" - + current_git_ref), + compilesketches.CompileSketches.ReportKeys.commit_url: ( + "https://github.com/" + github_repository + "/commit/" + current_git_ref + ), compilesketches.CompileSketches.ReportKeys.boards: [ { compilesketches.CompileSketches.ReportKeys.board: compile_sketches.fqbn, compilesketches.CompileSketches.ReportKeys.sizes: sizes_summary_report, compilesketches.CompileSketches.ReportKeys.warnings: warnings_summary_report, - compilesketches.CompileSketches.ReportKeys.sketches: sketch_report_list + compilesketches.CompileSketches.ReportKeys.sketches: sketch_report_list, } - ] + ], } - compile_sketches.get_sizes_summary_report.assert_called_once_with(compile_sketches, - sketch_report_list=sketch_report_list) + compile_sketches.get_sizes_summary_report.assert_called_once_with( + compile_sketches, sketch_report_list=sketch_report_list + ) # noinspection PyUnresolvedReferences - compile_sketches.get_warnings_summary_report.assert_called_once_with(compile_sketches, - sketch_report_list=sketch_report_list) + compile_sketches.get_warnings_summary_report.assert_called_once_with( + compile_sketches, sketch_report_list=sketch_report_list + ) # Test no summary report data (size deltas not enabled) compilesketches.CompileSketches.get_sizes_summary_report.return_value = [] @@ -2085,16 +2335,15 @@ def test_get_sketches_report(monkeypatch, mocker): assert compile_sketches.get_sketches_report(sketch_report_list=sketch_report_list) == { compilesketches.CompileSketches.ReportKeys.commit_hash: current_git_ref, - compilesketches.CompileSketches.ReportKeys.commit_url: ("https://github.com/" - + github_repository - + "/commit/" - + current_git_ref), + compilesketches.CompileSketches.ReportKeys.commit_url: ( + "https://github.com/" + github_repository + "/commit/" + current_git_ref + ), compilesketches.CompileSketches.ReportKeys.boards: [ { compilesketches.CompileSketches.ReportKeys.board: compile_sketches.fqbn, - compilesketches.CompileSketches.ReportKeys.sketches: sketch_report_list + compilesketches.CompileSketches.ReportKeys.sketches: sketch_report_list, } - ] + ], } @@ -2107,17 +2356,17 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.maximum: 111, compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: 42, - compilesketches.CompileSketches.ReportKeys.relative: 5.142 - } + compilesketches.CompileSketches.ReportKeys.relative: 5.142, + }, }, { compilesketches.CompileSketches.ReportKeys.name: "Bar memory type", compilesketches.CompileSketches.ReportKeys.maximum: 222, compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: 11, - compilesketches.CompileSketches.ReportKeys.relative: 2.242 - } - } + compilesketches.CompileSketches.ReportKeys.relative: 2.242, + }, + }, ] }, { @@ -2127,19 +2376,19 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.maximum: 111, compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: 8, - compilesketches.CompileSketches.ReportKeys.relative: 1.542 - } + compilesketches.CompileSketches.ReportKeys.relative: 1.542, + }, }, { compilesketches.CompileSketches.ReportKeys.name: "Bar memory type", compilesketches.CompileSketches.ReportKeys.maximum: 222, compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: 33, - compilesketches.CompileSketches.ReportKeys.relative: 10.042 - } - } + compilesketches.CompileSketches.ReportKeys.relative: 10.042, + }, + }, ] - } + }, ] expected_sizes_summary_report = [ @@ -2149,13 +2398,13 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: { compilesketches.CompileSketches.ReportKeys.minimum: 8, - compilesketches.CompileSketches.ReportKeys.maximum: 42 + compilesketches.CompileSketches.ReportKeys.maximum: 42, }, compilesketches.CompileSketches.ReportKeys.relative: { compilesketches.CompileSketches.ReportKeys.minimum: 1.542, - compilesketches.CompileSketches.ReportKeys.maximum: 5.142 - } - } + compilesketches.CompileSketches.ReportKeys.maximum: 5.142, + }, + }, }, { compilesketches.CompileSketches.ReportKeys.name: "Bar memory type", @@ -2163,14 +2412,14 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: { compilesketches.CompileSketches.ReportKeys.minimum: 11, - compilesketches.CompileSketches.ReportKeys.maximum: 33 + compilesketches.CompileSketches.ReportKeys.maximum: 33, }, compilesketches.CompileSketches.ReportKeys.relative: { compilesketches.CompileSketches.ReportKeys.minimum: 2.242, - compilesketches.CompileSketches.ReportKeys.maximum: 10.042 - } - } - } + compilesketches.CompileSketches.ReportKeys.maximum: 10.042, + }, + }, + }, ] compile_sketches = get_compilesketches_object() @@ -2188,17 +2437,17 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.maximum: "N/A", compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: "N/A", - compilesketches.CompileSketches.ReportKeys.relative: "N/A" - } + compilesketches.CompileSketches.ReportKeys.relative: "N/A", + }, }, { compilesketches.CompileSketches.ReportKeys.name: "Bar memory type", compilesketches.CompileSketches.ReportKeys.maximum: 222, compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: 11, - compilesketches.CompileSketches.ReportKeys.relative: 2.742 - } - } + compilesketches.CompileSketches.ReportKeys.relative: 2.742, + }, + }, ] }, { @@ -2208,19 +2457,19 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.maximum: 111, compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: 8, - compilesketches.CompileSketches.ReportKeys.relative: 2.442 - } + compilesketches.CompileSketches.ReportKeys.relative: 2.442, + }, }, { compilesketches.CompileSketches.ReportKeys.name: "Bar memory type", compilesketches.CompileSketches.ReportKeys.maximum: 222, compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: 33, - compilesketches.CompileSketches.ReportKeys.relative: 4.942 - } - } + compilesketches.CompileSketches.ReportKeys.relative: 4.942, + }, + }, ] - } + }, ] expected_sizes_summary_report = [ @@ -2230,13 +2479,13 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: { compilesketches.CompileSketches.ReportKeys.minimum: 8, - compilesketches.CompileSketches.ReportKeys.maximum: 8 + compilesketches.CompileSketches.ReportKeys.maximum: 8, }, compilesketches.CompileSketches.ReportKeys.relative: { compilesketches.CompileSketches.ReportKeys.minimum: 2.442, - compilesketches.CompileSketches.ReportKeys.maximum: 2.442 - } - } + compilesketches.CompileSketches.ReportKeys.maximum: 2.442, + }, + }, }, { compilesketches.CompileSketches.ReportKeys.name: "Bar memory type", @@ -2244,14 +2493,14 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: { compilesketches.CompileSketches.ReportKeys.minimum: 11, - compilesketches.CompileSketches.ReportKeys.maximum: 33 + compilesketches.CompileSketches.ReportKeys.maximum: 33, }, compilesketches.CompileSketches.ReportKeys.relative: { compilesketches.CompileSketches.ReportKeys.minimum: 2.742, - compilesketches.CompileSketches.ReportKeys.maximum: 4.942 - } - } - } + compilesketches.CompileSketches.ReportKeys.maximum: 4.942, + }, + }, + }, ] assert compile_sketches.get_sizes_summary_report(sketch_report_list=sketch_report_list) == ( @@ -2267,17 +2516,17 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.maximum: "N/A", compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: "N/A", - compilesketches.CompileSketches.ReportKeys.relative: "N/A" - } + compilesketches.CompileSketches.ReportKeys.relative: "N/A", + }, }, { compilesketches.CompileSketches.ReportKeys.name: "Bar memory type", compilesketches.CompileSketches.ReportKeys.maximum: 222, compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: 11, - compilesketches.CompileSketches.ReportKeys.relative: 0.842 - } - } + compilesketches.CompileSketches.ReportKeys.relative: 0.842, + }, + }, ] }, { @@ -2287,19 +2536,19 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.maximum: "N/A", compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: "N/A", - compilesketches.CompileSketches.ReportKeys.relative: "N/A" - } + compilesketches.CompileSketches.ReportKeys.relative: "N/A", + }, }, { compilesketches.CompileSketches.ReportKeys.name: "Bar memory type", compilesketches.CompileSketches.ReportKeys.maximum: 222, compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: 33, - compilesketches.CompileSketches.ReportKeys.relative: 7.742 - } - } + compilesketches.CompileSketches.ReportKeys.relative: 7.742, + }, + }, ] - } + }, ] expected_sizes_summary_report = [ @@ -2309,13 +2558,13 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: { compilesketches.CompileSketches.ReportKeys.minimum: "N/A", - compilesketches.CompileSketches.ReportKeys.maximum: "N/A" + compilesketches.CompileSketches.ReportKeys.maximum: "N/A", }, compilesketches.CompileSketches.ReportKeys.relative: { compilesketches.CompileSketches.ReportKeys.minimum: "N/A", - compilesketches.CompileSketches.ReportKeys.maximum: "N/A" - } - } + compilesketches.CompileSketches.ReportKeys.maximum: "N/A", + }, + }, }, { compilesketches.CompileSketches.ReportKeys.name: "Bar memory type", @@ -2323,14 +2572,14 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: { compilesketches.CompileSketches.ReportKeys.minimum: 11, - compilesketches.CompileSketches.ReportKeys.maximum: 33 + compilesketches.CompileSketches.ReportKeys.maximum: 33, }, compilesketches.CompileSketches.ReportKeys.relative: { compilesketches.CompileSketches.ReportKeys.minimum: 0.842, - compilesketches.CompileSketches.ReportKeys.maximum: 7.742 - } - } - } + compilesketches.CompileSketches.ReportKeys.maximum: 7.742, + }, + }, + }, ] assert compile_sketches.get_sizes_summary_report(sketch_report_list=sketch_report_list) == ( @@ -2346,17 +2595,17 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.maximum: 111, compilesketches.CompileSketches.ReportKeys.current: { compilesketches.CompileSketches.ReportKeys.absolute: 42, - compilesketches.CompileSketches.ReportKeys.relative: 2.342 - } + compilesketches.CompileSketches.ReportKeys.relative: 2.342, + }, }, { compilesketches.CompileSketches.ReportKeys.name: "Bar memory type", compilesketches.CompileSketches.ReportKeys.maximum: 222, compilesketches.CompileSketches.ReportKeys.current: { compilesketches.CompileSketches.ReportKeys.absolute: 11, - compilesketches.CompileSketches.ReportKeys.relative: 1.142 - } - } + compilesketches.CompileSketches.ReportKeys.relative: 1.142, + }, + }, ] }, { @@ -2366,19 +2615,19 @@ def test_get_sizes_summary_report(): compilesketches.CompileSketches.ReportKeys.maximum: 111, compilesketches.CompileSketches.ReportKeys.current: { compilesketches.CompileSketches.ReportKeys.absolute: 5, - compilesketches.CompileSketches.ReportKeys.relative: 0.542 - } + compilesketches.CompileSketches.ReportKeys.relative: 0.542, + }, }, { compilesketches.CompileSketches.ReportKeys.name: "Bar memory type", compilesketches.CompileSketches.ReportKeys.maximum: 111, compilesketches.CompileSketches.ReportKeys.current: { compilesketches.CompileSketches.ReportKeys.absolute: 33, - compilesketches.CompileSketches.ReportKeys.relative: 3.342 - } - } + compilesketches.CompileSketches.ReportKeys.relative: 3.342, + }, + }, ] - } + }, ] expected_sizes_summary_report = [] @@ -2405,14 +2654,14 @@ def test_get_warnings_summary_report(): compilesketches.CompileSketches.ReportKeys.absolute: 3 } } - } + }, ] expected_warnings_summary_report = { compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: { compilesketches.CompileSketches.ReportKeys.minimum: 3, - compilesketches.CompileSketches.ReportKeys.maximum: 42 + compilesketches.CompileSketches.ReportKeys.maximum: 42, } } } @@ -2435,14 +2684,14 @@ def test_get_warnings_summary_report(): compilesketches.CompileSketches.ReportKeys.absolute: 42 } } - } + }, ] expected_warnings_summary_report = { compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: { compilesketches.CompileSketches.ReportKeys.minimum: 3, - compilesketches.CompileSketches.ReportKeys.maximum: 42 + compilesketches.CompileSketches.ReportKeys.maximum: 42, } } } @@ -2466,14 +2715,14 @@ def test_get_warnings_summary_report(): compilesketches.CompileSketches.ReportKeys.absolute: 3 } } - } + }, ] expected_warnings_summary_report = { compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: { compilesketches.CompileSketches.ReportKeys.minimum: 3, - compilesketches.CompileSketches.ReportKeys.maximum: 3 + compilesketches.CompileSketches.ReportKeys.maximum: 3, } } } @@ -2496,14 +2745,14 @@ def test_get_warnings_summary_report(): compilesketches.CompileSketches.ReportKeys.absolute: compile_sketches.not_applicable_indicator } } - } + }, ] expected_warnings_summary_report = { compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: { compilesketches.CompileSketches.ReportKeys.minimum: 42, - compilesketches.CompileSketches.ReportKeys.maximum: 42 + compilesketches.CompileSketches.ReportKeys.maximum: 42, } } } @@ -2526,14 +2775,14 @@ def test_get_warnings_summary_report(): compilesketches.CompileSketches.ReportKeys.absolute: compile_sketches.not_applicable_indicator } } - } + }, ] expected_warnings_summary_report = { compilesketches.CompileSketches.ReportKeys.delta: { compilesketches.CompileSketches.ReportKeys.absolute: { compilesketches.CompileSketches.ReportKeys.minimum: compile_sketches.not_applicable_indicator, - compilesketches.CompileSketches.ReportKeys.maximum: compile_sketches.not_applicable_indicator + compilesketches.CompileSketches.ReportKeys.maximum: compile_sketches.not_applicable_indicator, } } } @@ -2557,7 +2806,7 @@ def test_get_warnings_summary_report(): compilesketches.CompileSketches.ReportKeys.absolute: 3 } } - } + }, ] expected_warnings_summary_report = {} @@ -2578,20 +2827,23 @@ def test_get_warnings_summary_report(): def test_create_sketches_report_file(monkeypatch, tmp_path): sketches_report_path = tmp_path - sketches_report = [{ - "sketch": "examples/Foo", - "compilation_success": True, - "flash": 444, - "ram": 9, - "previous_flash": 1438, - "previous_ram": 184, - "flash_delta": -994, - "ram_delta": -175, - "fqbn": "arduino:avr:uno" - }] - - compile_sketches = get_compilesketches_object(sketches_report_path=str(sketches_report_path), - fqbn_arg="arduino:avr:uno") + sketches_report = [ + { + "sketch": "examples/Foo", + "compilation_success": True, + "flash": 444, + "ram": 9, + "previous_flash": 1438, + "previous_ram": 184, + "flash_delta": -994, + "ram_delta": -175, + "fqbn": "arduino:avr:uno", + } + ] + + compile_sketches = get_compilesketches_object( + sketches_report_path=str(sketches_report_path), fqbn_arg="arduino:avr:uno" + ) compile_sketches.create_sketches_report_file(sketches_report=sketches_report) @@ -2599,13 +2851,17 @@ def test_create_sketches_report_file(monkeypatch, tmp_path): assert json.load(sketch_report_file) == sketches_report -@pytest.mark.parametrize("cli_version, command, original_key, expected_key", - [("latest", "core list", "ID", "id"), # Non-semver - ("1.0.0", "core list", "ID", "id"), # > - ("0.17.0", "core list", "ID", "ID"), # == - ("0.14.0-rc2", "core list", "ID", "ID"), # < - ("1.0.0", "foo", "ID", "ID"), # Command has no translation - ("1.0.0", "core list", "foo", "foo")]) # Key has no translation +@pytest.mark.parametrize( + "cli_version, command, original_key, expected_key", + [ + ("latest", "core list", "ID", "id"), # Non-semver + ("1.0.0", "core list", "ID", "id"), # > + ("0.17.0", "core list", "ID", "ID"), # == + ("0.14.0-rc2", "core list", "ID", "ID"), # < + ("1.0.0", "foo", "ID", "ID"), # Command has no translation + ("1.0.0", "core list", "foo", "foo"), + ], +) # Key has no translation def test_cli_json_key(cli_version, command, original_key, expected_key): compile_sketches = get_compilesketches_object(cli_version=cli_version) @@ -2623,36 +2879,48 @@ def test_verbose_print(capsys, verbose): compile_sketches.verbose_print(string_print_argument, int_print_argument, path_print_argument) if verbose == "true": - assert capsys.readouterr().out.strip() == (string_print_argument + " " - + str(int_print_argument) + " " - + str(path_print_argument)) + assert capsys.readouterr().out.strip() == ( + string_print_argument + " " + str(int_print_argument) + " " + str(path_print_argument) + ) else: assert capsys.readouterr().out.strip() == "" -@pytest.mark.parametrize("list_argument, expected_list", - [("", []), - ("foobar", ["foobar"]), - ("foo bar", ["foo", "bar"]), - ("\"foo bar\"", ["foo bar"]), - ("\'foo bar\'", ["foo bar"]), - ("\'\"foo bar\" \"baz\"\'", ["foo bar", "baz"]), - ("\'\"foo bar\" baz\'", ["foo bar", "baz"])]) +@pytest.mark.parametrize( + "list_argument, expected_list", + [ + ("", []), + ("foobar", ["foobar"]), + ("foo bar", ["foo", "bar"]), + ('"foo bar"', ["foo bar"]), + ("'foo bar'", ["foo bar"]), + ('\'"foo bar" "baz"\'', ["foo bar", "baz"]), + ("'\"foo bar\" baz'", ["foo bar", "baz"]), + ], +) def test_parse_list_input(list_argument, expected_list): assert compilesketches.parse_list_input(list_argument) == expected_list -@pytest.mark.parametrize("fqbn_arg, expected_fqbn, expected_additional_url", - [("foo:bar:baz", "foo:bar:baz", None), - ("\"foo:bar:baz\"", "foo:bar:baz", None), - ("\"foo asdf:bar:baz\"", "foo asdf:bar:baz", None), - ("\'foo:bar:baz\'", "foo:bar:baz", None), - ("\'\"foo asdf:bar:baz\" https://example.com/package_foo_index.json\'", - "foo asdf:bar:baz", - "https://example.com/package_foo_index.json"), - ("\'\"foo asdf:bar:baz\" \"https://example.com/package_foo_index.json\"\'", - "foo asdf:bar:baz", - "https://example.com/package_foo_index.json")]) +@pytest.mark.parametrize( + "fqbn_arg, expected_fqbn, expected_additional_url", + [ + ("foo:bar:baz", "foo:bar:baz", None), + ('"foo:bar:baz"', "foo:bar:baz", None), + ('"foo asdf:bar:baz"', "foo asdf:bar:baz", None), + ("'foo:bar:baz'", "foo:bar:baz", None), + ( + "'\"foo asdf:bar:baz\" https://example.com/package_foo_index.json'", + "foo asdf:bar:baz", + "https://example.com/package_foo_index.json", + ), + ( + '\'"foo asdf:bar:baz" "https://example.com/package_foo_index.json"\'', + "foo asdf:bar:baz", + "https://example.com/package_foo_index.json", + ), + ], +) def test_parse_fqbn_arg_input(fqbn_arg, expected_fqbn, expected_additional_url): parsed_fqbn_arg = compilesketches.parse_fqbn_arg_input(fqbn_arg=fqbn_arg) @@ -2660,32 +2928,41 @@ def test_parse_fqbn_arg_input(fqbn_arg, expected_fqbn, expected_additional_url): assert parsed_fqbn_arg["additional_url"] == expected_additional_url -@pytest.mark.parametrize("boolean_input, expected_output", - [("true", True), ("True", True), ("false", False), ("False", False), ("foo", None)]) +@pytest.mark.parametrize( + "boolean_input, expected_output", + [("true", True), ("True", True), ("false", False), ("False", False), ("foo", None)], +) def test_parse_boolean_input(boolean_input, expected_output): assert compilesketches.parse_boolean_input(boolean_input=boolean_input) == expected_output -@pytest.mark.parametrize("path, expected_relative_path", - # Path under workspace - [(os.environ["GITHUB_WORKSPACE"] + "/baz", pathlib.PurePath("baz")), - # Path outside workspace - ("/bar/foo", pathlib.Path("/").resolve().joinpath("bar", "foo"))]) +@pytest.mark.parametrize( + "path, expected_relative_path", + # Path under workspace + [ + (os.environ["GITHUB_WORKSPACE"] + "/baz", pathlib.PurePath("baz")), + # Path outside workspace + ("/bar/foo", pathlib.Path("/").resolve().joinpath("bar", "foo")), + ], +) def test_path_relative_to_workspace(path, expected_relative_path): assert compilesketches.path_relative_to_workspace(path=path) == expected_relative_path assert compilesketches.path_relative_to_workspace(path=pathlib.PurePath(path)) == expected_relative_path -@pytest.mark.parametrize("path, expected_absolute_path", - # Absolute path - [("/asdf", pathlib.Path("/").resolve().joinpath("asdf")), - # Relative path - ("asdf", pathlib.Path(os.environ["GITHUB_WORKSPACE"]).resolve().joinpath("asdf")), - # Use of ~ - ("~/foo", pathlib.Path.home().joinpath("foo")), - # Use of .. - ("/foo/bar/../baz", pathlib.Path("/").resolve().joinpath("foo", "baz")) - ]) +@pytest.mark.parametrize( + "path, expected_absolute_path", + # Absolute path + [ + ("/asdf", pathlib.Path("/").resolve().joinpath("asdf")), + # Relative path + ("asdf", pathlib.Path(os.environ["GITHUB_WORKSPACE"]).resolve().joinpath("asdf")), + # Use of ~ + ("~/foo", pathlib.Path.home().joinpath("foo")), + # Use of .. + ("/foo/bar/../baz", pathlib.Path("/").resolve().joinpath("foo", "baz")), + ], +) def test_absolute_path(path, expected_absolute_path): assert compilesketches.absolute_path(path=path) == expected_absolute_path assert compilesketches.absolute_path(path=pathlib.PurePath(path)) == expected_absolute_path @@ -2693,15 +2970,13 @@ def test_absolute_path(path, expected_absolute_path): @pytest.mark.parametrize( "path, expected_path", - [("foo/bar-relative-path", pathlib.PurePath("foo/bar-relative-path")), - ("/foo/bar-absolute-path", pathlib.Path("/").resolve().joinpath("foo", "bar-absolute-path"))] + [ + ("foo/bar-relative-path", pathlib.PurePath("foo/bar-relative-path")), + ("/foo/bar-absolute-path", pathlib.Path("/").resolve().joinpath("foo", "bar-absolute-path")), + ], ) def test_absolute_relative_path_conversion(path, expected_path): - assert compilesketches.path_relative_to_workspace( - path=compilesketches.absolute_path( - path=path - ) - ) == expected_path + assert compilesketches.path_relative_to_workspace(path=compilesketches.absolute_path(path=path)) == expected_path def test_list_to_string(): @@ -2709,19 +2984,19 @@ def test_list_to_string(): assert compilesketches.list_to_string([42, path]) == "42 " + str(path) -@pytest.mark.parametrize("arcname, source_path, destination_name, expected_destination_name, expected_success", - [("FooArcname", ".", None, "FooArcname", True), - ("FooArcname", "./Sketch1", "FooDestinationName", "FooDestinationName", True), - ("FooArcname", "Sketch1", None, "Sketch1", True), - (".", "Sketch1", None, "Sketch1", True), - ("FooArcname", "Nonexistent", None, "", False), ]) -def test_install_from_download(capsys, - tmp_path, - arcname, - source_path, - destination_name, - expected_destination_name, - expected_success): +@pytest.mark.parametrize( + "arcname, source_path, destination_name, expected_destination_name, expected_success", + [ + ("FooArcname", ".", None, "FooArcname", True), + ("FooArcname", "./Sketch1", "FooDestinationName", "FooDestinationName", True), + ("FooArcname", "Sketch1", None, "Sketch1", True), + (".", "Sketch1", None, "Sketch1", True), + ("FooArcname", "Nonexistent", None, "", False), + ], +) +def test_install_from_download( + capsys, tmp_path, arcname, source_path, destination_name, expected_destination_name, expected_success +): url_source_path = test_data_path.joinpath("HasSketches") compile_sketches = get_compilesketches_object() @@ -2739,39 +3014,58 @@ def test_install_from_download(capsys, destination_parent_path = tmp_path.joinpath("destination_parent_path") if expected_success: - compile_sketches.install_from_download(url=url, - source_path=source_path, - destination_parent_path=destination_parent_path, - destination_name=destination_name) + compile_sketches.install_from_download( + url=url, + source_path=source_path, + destination_parent_path=destination_parent_path, + destination_name=destination_name, + ) # Verify that the installation matches the source - assert directories_are_same(left_directory=url_source_path.joinpath(source_path), - right_directory=destination_parent_path.joinpath(expected_destination_name)) + assert directories_are_same( + left_directory=url_source_path.joinpath(source_path), + right_directory=destination_parent_path.joinpath(expected_destination_name), + ) else: with pytest.raises(expected_exception=SystemExit, match="1"): - compile_sketches.install_from_download(url=url, - source_path=source_path, - destination_parent_path=destination_parent_path, - destination_name=destination_name) + compile_sketches.install_from_download( + url=url, + source_path=source_path, + destination_parent_path=destination_parent_path, + destination_name=destination_name, + ) assert capsys.readouterr().out.strip() == ("::error::Archive source path: " + source_path + " not found") -@pytest.mark.parametrize("archive_extract_path, expected_archive_root_path", - [(test_data_path.joinpath("test_get_archive_root_folder_name", "has-root"), - test_data_path.joinpath("test_get_archive_root_folder_name", "has-root", "root")), - (test_data_path.joinpath("test_get_archive_root_folder_name", "has-file"), - test_data_path.joinpath("test_get_archive_root_folder_name", "has-file")), - (test_data_path.joinpath("test_get_archive_root_folder_name", "has-folders"), - test_data_path.joinpath("test_get_archive_root_folder_name", "has-folders"))]) +@pytest.mark.parametrize( + "archive_extract_path, expected_archive_root_path", + [ + ( + test_data_path.joinpath("test_get_archive_root_folder_name", "has-root"), + test_data_path.joinpath("test_get_archive_root_folder_name", "has-root", "root"), + ), + ( + test_data_path.joinpath("test_get_archive_root_folder_name", "has-file"), + test_data_path.joinpath("test_get_archive_root_folder_name", "has-file"), + ), + ( + test_data_path.joinpath("test_get_archive_root_folder_name", "has-folders"), + test_data_path.joinpath("test_get_archive_root_folder_name", "has-folders"), + ), + ], +) def test_get_archive_root_path(archive_extract_path, expected_archive_root_path): assert compilesketches.get_archive_root_path(archive_extract_path) == expected_archive_root_path -@pytest.mark.parametrize("url, source_path, destination_name, expected_destination_name", - [("https://example.com/foo/FooRepositoryName.git", ".", None, "FooRepositoryName"), - ("https://example.com/foo/FooRepositoryName.git/", "./examples", "FooDestinationName", - "FooDestinationName"), - ("git://example.com/foo/FooRepositoryName", "examples", None, None)]) +@pytest.mark.parametrize( + "url, source_path, destination_name, expected_destination_name", + [ + ("https://example.com/foo/FooRepositoryName.git", ".", None, "FooRepositoryName"), + ("https://example.com/foo/FooRepositoryName.git/", "./examples", "FooDestinationName", "FooDestinationName"), + ("git://example.com/foo/FooRepositoryName", "examples", None, None), + ], +) def test_install_from_repository(mocker, url, source_path, destination_name, expected_destination_name): git_ref = unittest.mock.sentinel.git_ref destination_parent_path = unittest.mock.sentinel.destination_parent_path @@ -2784,27 +3078,29 @@ def test_install_from_repository(mocker, url, source_path, destination_name, exp compile_sketches = get_compilesketches_object() - compile_sketches.install_from_repository(url=url, - git_ref=git_ref, - source_path=source_path, - destination_parent_path=destination_parent_path, - destination_name=destination_name, - force=force) + compile_sketches.install_from_repository( + url=url, + git_ref=git_ref, + source_path=source_path, + destination_parent_path=destination_parent_path, + destination_name=destination_name, + force=force, + ) # noinspection PyUnresolvedReferences - tempfile.mkdtemp.assert_called_once_with(dir=compile_sketches.temporary_directory.name, - prefix="install_from_repository-") - compile_sketches.clone_repository.assert_called_once_with(compile_sketches, - url=url, - git_ref=git_ref, - destination_path=clone_path) + tempfile.mkdtemp.assert_called_once_with( + dir=compile_sketches.temporary_directory.name, prefix="install_from_repository-" + ) + compile_sketches.clone_repository.assert_called_once_with( + compile_sketches, url=url, git_ref=git_ref, destination_path=clone_path + ) # noinspection PyUnresolvedReferences compile_sketches.install_from_path.assert_called_once_with( compile_sketches, source_path=clone_path.joinpath(source_path), destination_parent_path=destination_parent_path, destination_name=expected_destination_name, - force=force + force=force, ) @@ -2832,12 +3128,12 @@ def test_clone_repository(tmp_path, git_ref): cloned_repository.git.checkout(git_ref) # Verify that the installation matches the test clone - assert directories_are_same(left_directory=destination_path, - right_directory=test_clone_path) + assert directories_are_same(left_directory=destination_path, right_directory=test_clone_path) -@pytest.mark.parametrize("github_event, expected_hash", - [("pull_request", "pull_request-head-sha"), ("push", "push-head-sha")]) +@pytest.mark.parametrize( + "github_event, expected_hash", [("pull_request", "pull_request-head-sha"), ("push", "push-head-sha")] +) def test_get_head_commit_hash(monkeypatch, mocker, github_event, expected_hash): # Stub class Repo: