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: