From a0fcdc83cbc2b440a5836313b2afd1a35698f5ef Mon Sep 17 00:00:00 2001 From: HombreLaser Date: Tue, 12 Mar 2024 23:46:02 -0600 Subject: Añade pruebas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 18 ++++------------- src/arg_parser.py | 18 ++++++++++++++--- src/program.py | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ src/table.py | 11 +++-------- tests/__init__.py | 0 tests/conftest.py | 36 ++++++++++++++++++++++++++++++++++ tests/test_delete_at.py | 4 ++++ tests/test_get_rows.py | 4 ++++ tests/test_insert.py | 4 ++++ tests/test_row_at.py | 6 ++++++ tests/test_search.py | 4 ++++ 11 files changed, 132 insertions(+), 25 deletions(-) create mode 100644 src/program.py create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/test_delete_at.py create mode 100644 tests/test_get_rows.py create mode 100644 tests/test_insert.py create mode 100644 tests/test_row_at.py create mode 100644 tests/test_search.py diff --git a/main.py b/main.py index d785261..f4a1ea6 100644 --- a/main.py +++ b/main.py @@ -1,23 +1,13 @@ import sys from src.table import Table from src.arg_parser import ArgParser - - -help_string = """CSV utils - Usage: - python main.py -f file -c COMMAND ATTRIBUTES - file: ubicación del archivo csv - - Comandos disponibles: - row-at n: imprimir fila en n - get-rows n: imprimir primeras n filas - insert "csv string": insertar fila. La fila debe contener exactamente 3 elementos. - search "lookup": buscar texto lookup en la tabla. - """ +from src.program import Program def main(): - ArgParser() + program = Program() + program.run() + if __name__ == '__main__': main() \ No newline at end of file diff --git a/src/arg_parser.py b/src/arg_parser.py index c2db3bd..a5fdb40 100644 --- a/src/arg_parser.py +++ b/src/arg_parser.py @@ -1,4 +1,5 @@ import argparse +import sys AVAILABLE_COMMANDS_HELP_STRING = """Available commands: @@ -6,13 +7,24 @@ AVAILABLE_COMMANDS_HELP_STRING = """Available commands: get-rows n: print first n rows insert "csv string": insert row at the end, the row must have exactly 3 elements. search "lookup": search "lookup" in the table. + delete-at n: delete row at nth position """ class ArgParser: - def __init__(self): + def __init__(self, args=sys.argv): self.parser = argparse.ArgumentParser() self.parser.add_argument('-f', required=True, help='CSV file location') self.parser.add_argument('-c', required=True, help=AVAILABLE_COMMANDS_HELP_STRING, nargs=2) - self.args = self.parser.parse_args() - print(self.args) \ No newline at end of file + self.args = self.parser.parse_args(args) + + @property + def file(self): + return self.args.f + + @property + def command(self): + return self.args.c + + def print_help(self): + self.parser.print_help() \ No newline at end of file diff --git a/src/program.py b/src/program.py new file mode 100644 index 0000000..1c43ea7 --- /dev/null +++ b/src/program.py @@ -0,0 +1,52 @@ +from src.arg_parser import ArgParser +from src.table import Table +from src.exceptions import IncompatibleRowLengthError +import sys + +class Program(): + def __init__(self, args=sys.argv[1:]): + self.arg_parser = ArgParser(args=args) + self.table = Table(self.arg_parser.file) + + def _command_arg_to_int(self): + try: + return int(self.arg_parser.command[1]) + except ValueError: + self.arg_parser.print_help() + exit() + + def _print_table_result(self, table): + for row in table: + print(row) + + def run(self): + match self.arg_parser.command[0]: + case 'row-at': + print(self.table.row_at(self._command_arg_to_int())) + case 'get-rows': + result = self.table.get_rows(self._command_arg_to_int()) + + self._print_table_result(result) + case 'insert': + new_row = tuple(self.arg_parser.command[1].rsplit(',')) + + try: + self.table.insert(new_row) + print('Row added!') + except IncompatibleRowLengthError as error: + print(error) + case 'search': + result = self.table.search(self.arg_parser.command[1]) + + if result is not None: + print(result) + else: + print('Not found!') + case 'delete-at': + try: + self.table.delete_at(self._command_arg_to_int()) + print(f"Row at {self._command_arg_to_int()} deleted") + except IndexError: + print(f"Couldn't find row at {self._command_arg_to_int()}") + case _: + arg_parser.print_help() \ No newline at end of file diff --git a/src/table.py b/src/table.py index 798fc9f..004bd4d 100644 --- a/src/table.py +++ b/src/table.py @@ -9,8 +9,7 @@ ROW_SIZE = 3 class Table: def __init__(self, file_path: str): self.csv_params = { 'delimiter': ',', 'quotechar': '"' } - self.csv_file = open(file_path, 'r+', newline='') - self.writer = csv.writer(self.csv_file, **self.csv_params) + self.csv_file = open(file_path, 'r', newline='') self.rows = [tuple(row) for row in csv.reader(self.csv_file, **self.csv_params)] def __del__(self): @@ -18,7 +17,7 @@ class Table: self.csv_file.close() def __write_changes(self): - with open(f"new_{token_hex(8)}.csv", 'w', newline='') as new_table: + with open(f"./new_{token_hex(8)}.csv", 'w', newline='') as new_table: writer = csv.writer(new_table, **self.csv_params) for row in self.rows: writer.writerow(row) @@ -37,13 +36,9 @@ class Table: raise IncompatibleRowLengthError(len(new_row)) self.rows.append(new_row) - self.writer.writerow(new_row) def delete_at(self, to_delete: int): - try: - self.rows.pop(to_delete) - except IndexError: - return None + self.rows.pop(to_delete) def search(self, lookup: str): for row in self.rows: diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..f3dbc41 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,36 @@ +from src.program import Program +from glob import iglob +import os +import pytest + + +@pytest.fixture +def row_at_program(): + return Program(args=['-f', './tests/test_table.csv', '-c', 'row-at', '2']) + + +@pytest.fixture +def get_rows_program(): + return Program(args=['-f', './tests/test_table.csv', '-c', 'get-rows', '2']) + + +@pytest.fixture +def insert_program(): + return Program(args=['-f', './tests/test_table.csv', '-c', 'insert', '1969,Ubik,Philip K. Dick']) + + +@pytest.fixture +def search_program(): + return Program(args=['-f', './tests/test_table.csv', '-c', 'search', 'Ten Days that Shook the World']) + + +@pytest.fixture +def delete_at_program(): + return Program(args=['-f', './tests/test_table.csv', '-c', 'delete-at', '1']) + + +@pytest.fixture(scope='session', autouse=True) +def delete_created_csv_files(): + yield + for file in iglob("./new_*.csv"): + os.remove(file) \ No newline at end of file diff --git a/tests/test_delete_at.py b/tests/test_delete_at.py new file mode 100644 index 0000000..02471d1 --- /dev/null +++ b/tests/test_delete_at.py @@ -0,0 +1,4 @@ +def test_delete_at(capsys, delete_at_program): + delete_at_program.run() + + assert capsys.readouterr()[0] == 'Row at 1 deleted\n' \ No newline at end of file diff --git a/tests/test_get_rows.py b/tests/test_get_rows.py new file mode 100644 index 0000000..51b1c43 --- /dev/null +++ b/tests/test_get_rows.py @@ -0,0 +1,4 @@ +def test_get_rows(capsys, get_rows_program): + get_rows_program.run() + + assert capsys.readouterr()[0] == "('1985', 'Blood Meridian', 'Cormac McCarthy')\n('1851', 'Moby Dick', 'Herman Melville')\n" \ No newline at end of file diff --git a/tests/test_insert.py b/tests/test_insert.py new file mode 100644 index 0000000..caaf7ff --- /dev/null +++ b/tests/test_insert.py @@ -0,0 +1,4 @@ +def test_insert(capsys, insert_program): + insert_program.run() + + assert capsys.readouterr()[0] == 'Row added!\n' \ No newline at end of file diff --git a/tests/test_row_at.py b/tests/test_row_at.py new file mode 100644 index 0000000..6b7c379 --- /dev/null +++ b/tests/test_row_at.py @@ -0,0 +1,6 @@ +def test_row_at(capsys, row_at_program): + row_at_program.run() + + assert capsys.readouterr()[0].startswith( + "('1919', 'Ten Days that Shook the World', 'John Reed')" + ) \ No newline at end of file diff --git a/tests/test_search.py b/tests/test_search.py new file mode 100644 index 0000000..ecdc550 --- /dev/null +++ b/tests/test_search.py @@ -0,0 +1,4 @@ +def test_search(capsys, search_program): + search_program.run() + + assert capsys.readouterr()[0] == "('1919', 'Ten Days that Shook the World', 'John Reed')\n" \ No newline at end of file -- cgit v1.2.3