6
\$\begingroup\$

TestAssignment is a Python class designed to check certain conditions in a Git repository. It has several methods that check for the existence of required files, the initialization of a Git repository, the status of untracked files, and the status of committed files.

The constructor takes several arguments, including the name of the folder, a boolean value indicating if the repository is initialized, lists of files that should exist, files that should be committed, and files that should be untracked.

The methods in the class raise a SystemExit if certain conditions are not met and store information about whether each check has passed or failed in a dictionary.

Finally, the run_test() method calls all the other methods to check if all the conditions are met and prints the results. This class can be useful for automated testing of Git repositories to ensure that they meet specific requirements.

import git
import os
import json 



class TestAssignment:
    completed_milestones = {"hasPassed": False,
                            "folderCreated":"Not checked",
                            "filesCreated":"Not checked",
                            "initedRepo":"Not checked",
                            "untrackedFiles":"Not checked",
                            "addedFiles":"Not checked",
                            "modifiedFiles":"Not checked",
                            "committedFiles":"Not checked"
                            } 

    def __init__(self, folder_name, is_initialized, files, committed_files, added_files, modified_files=None, untracked_files=None):
        self.folder_name        = folder_name
        self.is_initialized     = is_initialized
        self.files              = files
        self.committed_files    = committed_files
        self.added_files        = added_files 
        self.modified_files     = modified_files
        self.untracked_files    = untracked_files
    
    def folder_exists(self):
        """
        Check if the folder exists.

        Raises:
            SystemExit: If there are no folder on the path,the function exits with completed_milestones as json
        """
        if not os.path.isdir(self.folder_name):
            self.completed_milestones["folderCreated"] = f"Failed: The folder {self.folder_name} does not exist."
            raise SystemExit(json.dumps(self.completed_milestones))
        else:
            self.completed_milestones["folderCreated"] = "Passed"
        
    
    def files_exists(self):
        """
        Check if all the required files exist.
        """
        for file in self.files:
            if not os.path.isfile(file):
                self.completed_milestones["filesCreated"] = f"Failed: The file {file} does not exist on path."
                return
        self.completed_milestones["filesCreated"] = "Passed"
    
    
    def check_git_initialized(self):
        """
        Check if the Git repository is initialized.

        Returns:
            git.Repo: The Git repository object if initialized

        Raises:
            SystemExit: If there are no Git repository initialized on the path,the function exits 
        """
        try:
            repo = git.Repo(self.folder_name)
            self.completed_milestones["initedRepo"] = "Passed"
            return repo
        except git.InvalidGitRepositoryError:
            self.completed_milestones["initedRepo"] = f"Failed: The repository is not initialized in {self.folder_name}."
            raise SystemExit(json.dumps(self.completed_milestones))
    

    def check_untracked_files(self, repo):
        """
        Check if untracked files in the repository match the expected list.

        Args:
            repo (git.Repo): Git repository object.

        """
        untracked_files = repo.untracked_files
        if untracked_files != self.untracked_files:
            self.completed_milestone["untrackedFiles"] = f"Failed: Only these files should be untracked {self.untracked_files}, but these files are untracked {untracked_files}."
        else:
            self.completed_milestone["untrackedFiles"] = "Passed"
        
    
    def check_status_files(self,repo,status_type,files,milestone_type):
        """
        Check if the status of the files in the repository match the expected list.

        Args:
            repo (git.Repo): Git repository object.

            status_type str : Symbol for staus

            files list[str]: List of file names.

            milestone_type str : Name of which milestone.

        """
    

        diff_index = repo.index.diff(None)
        # get the modified files
        modified_files = [diff.a_blob.path for diff in diff_index if diff.change_type == status_type]
        if modified_files != files:
            self.completed_milestone[milestone_type] = f"Failed: Only these files should be {status_type} {self.modified_files}, but these files are {status_type} {modified_files}."
        else:
            self.completed_milestone[milestone_type] = "Passed"
         


    def check_most_recently_committed_files(self, repo):
        """
        Check if the most recently committed files in the repository match the expected list.

        Args:
            repo (git.Repo): Git repository object.

        """
        commit = repo.head.commit
        for file in self.committed_files:
            if file not in commit.tree:
                self.completed_milestone["committedFiles"] = f"Failed: This file should be committed but isn't: {file}."
                return
        
        self.completed_milestone["committedFiles"] = "Passed"

        
    def run_test(self): 
        self.folder_exists()
        self.files_exists()
        repo = self.check_git_initialized()
        self.check_untracked_files(repo)
        self.check_status_files(repo,"M",self.modified_files,"modifiedFiles")
        self.check_status_files(repo,"A",self.added_files,"addedFiles")
        self.check_most_recently_committed_files(repo)
        self.completed_milestones["hasPassed"] = True
        print(self.completed_milestones)
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Overview

The code layout is good, and you used meaningful names for functions and variables. There is not much to improve.

Documentation

The function docstrings are great.

Add a docstring for class TestAssignment:

"""
Check certain conditions in a Git repository:
    the existence of required files
    the initialization of a Git repository
    the status of untracked files
    the status of committed files
"""

TestAssignment is not a very descriptive name. The name should probably have "Git" in it somewhere.

Simpler

This if/else:

    if not os.path.isdir(self.folder_name):
    else:

would be simpler if the condition was "positive" logic (without not):

    if os.path.isdir(self.folder_name):
    else:

Obviously, the code executed by each condition should be swapped.

Layout

The code would be easier to read if the colons are aligned vertically:

completed_milestones = {
    "hasPassed"         : False,
    "folderCreated"     : "Not checked",
    "filesCreated"      : "Not checked",
    "initedRepo"        : "Not checked",
    "untrackedFiles"    : "Not checked",
    "addedFiles"        : "Not checked",
    "modifiedFiles"     : "Not checked",
    "committedFiles"    : "Not checked",
}

There is some inconsitent vertical whitespace (blank lines). The black program can be used to automatically format the code.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.