Claudio Maggioni 2023-12-21 23:54:39 +01:00
parent 27438c280f
commit c3c4095450
20 changed files with 234 additions and 221 deletions

1
.gitignore vendored
View file

@ -124,6 +124,7 @@ celerybeat.pid
.env .env
.venv .venv
env/ env/
env37/
venv/ venv/
ENV/ ENV/
env.bak/ env.bak/

View file

@ -13,12 +13,31 @@ Note: Feel free to modify this file according to the project's necessities.
## Environment setup ## Environment setup
To install the required dependencies make sure `python3` points to a Python 3.10 or 3.11 installation and then run: To install the required dependencies the Python version manager `pyenv` must be installed and in `$PATH`.
To set up a Python 3.11 virtualenv to execute parts 1, 2, and 3 of the project run:
```shell ```shell
python3.8 -m venv env deactivate || true # deactivate existing environment
pyenv install -s 3.11
pyenv shell 3.11
python3.11 -m venv env
source env/bin/activate source env/bin/activate
pip install -r requirements.txt pip3.11 install -r requirements.txt
```
To set up Python 3.7 (last version supported by `mut.py`) to execute part 4 of the project run:
```shell
deactivate || true # deactivate existing environment
pyenv install -s 3.7
pyenv shell 3.7
python3.7 -m venv env37
source env37/bin/activate
pip3.7 install MutPy==0.6.1
pip3.7 install -r requirements.txt
``` ```
## Instrumentation (Part 1) ## Instrumentation (Part 1)
@ -26,7 +45,12 @@ pip install -r requirements.txt
To generate the instrumented code for all the files in the benchmark run the command: To generate the instrumented code for all the files in the benchmark run the command:
```shell ```shell
python3 ./instrument.py # Reset Python to latest (system) version
deactivate || true
pyenv shell 3.11
source env/bin/activate
python3.11 ./instrument.py
``` ```
The generated files are created in the directory `instrumented`. Each file name matches the file name of the The generated files are created in the directory `instrumented`. Each file name matches the file name of the
@ -37,7 +61,12 @@ corresponding source file in `benchmark`.
To generate test cases for all files in the benchmark run the command: To generate test cases for all files in the benchmark run the command:
```shell ```shell
python3 ./genetic.py # Reset Python to latest (system) version
deactivate || true
pyenv shell 3.11
source env/bin/activate
python3.11 ./genetic.py
``` ```
The test suite is created in the directory `tests`. One test file is generated for each file present in the The test suite is created in the directory `tests`. One test file is generated for each file present in the
@ -46,5 +75,23 @@ The test suite is created in the directory `tests`. One test file is generated f
The test suite can be then executed over the benchmark code with the command: The test suite can be then executed over the benchmark code with the command:
```shell ```shell
python3 -m unittest discover tests # Reset Python to latest (system) version
deactivate || true
pyenv shell 3.11
source env/bin/activate
python3.11 -m unittest discover tests
```
## Mutation testing (Part 4)
To run `mut.py` use Python 3.7 and run:
```shell
# Reset Python to 3.7 version
deactivate || true
pyenv shell 3.7
source env37/bin/activate
python3.7 muttest.py
``` ```

View file

@ -34,8 +34,15 @@ class Archive:
def build_suite(self) -> Set[instrument.Params]: def build_suite(self) -> Set[instrument.Params]:
return set(list(self.true_branches.values()) + list(self.false_branches.values())) return set(list(self.true_branches.values()) + list(self.false_branches.values()))
def suite_str(self):
suite = self.build_suite()
return " ".join([",".join([f'{k}={repr(v)}' for k, v in test.items()]) for test in suite])
def consider_test(self, test_case: frozendict): def consider_test(self, test_case: frozendict):
instrument.invoke(self.f_name, test_case) try:
instrument.invoke(self.f_name, test_case)
except AssertionError:
return
range_start, range_end = instrument.n_of_branches[self.f_name] range_start, range_end = instrument.n_of_branches[self.f_name]
@ -47,7 +54,7 @@ class Archive:
operators.distances_false[branch] == 0 and branch not in self.false_branches): operators.distances_false[branch] == 0 and branch not in self.false_branches):
self.false_branches[branch] = test_case self.false_branches[branch] = test_case
def satisfies_branch(self, test_case: frozendict) -> Optional[str]: def satisfies_unseen_branch(self, test_case: frozendict) -> Optional[str]:
try: try:
instrument.invoke(self.f_name, test_case) instrument.invoke(self.f_name, test_case)
except AssertionError: except AssertionError:

View file

@ -138,16 +138,18 @@ def crossover(chosen_test: Params, other_chosen_test: Params, arguments: List[Ar
def generate_test_case(f_name: str, arguments: List[Arg], archive: Archive) -> Params: def generate_test_case(f_name: str, arguments: List[Arg], archive: Archive) -> Params:
pool: List[Params] = get_pool(arguments) pool: List[Params] = get_pool(arguments)
attempts = 20 # attempts to generate a random test that satisfies a new branch
while True: while True:
test = sample(pool, 1)[0] test = sample(pool, 1)[0]
is_new = archive.satisfies_branch(test) is_new = archive.satisfies_unseen_branch(test)
if is_new is None: attempts -= 1
if is_new is None and attempts > 0:
# print(f"Not new: {test}") # print(f"Not new: {test}")
continue continue
print(f"New {is_new}!: {test}")
try: try:
invoke(f_name, test) invoke(f_name, test)
return test # return only test cases that satisfy assertions return test # return only test cases that satisfy assertions

View file

@ -71,29 +71,18 @@ def generate(orig_name: str) -> Set[instrument.Params]:
population = toolbox.population(n=NPOP) population = toolbox.population(n=NPOP)
# Create statistics object # Create statistics object
stats = tools.Statistics(lambda ind: ind.fitness.values) population, _ = algorithms.eaSimple(population, toolbox, CXPROB, MUPROB, NGEN, verbose=False)
stats.register("min", min)
stats.register("max", max)
population, logbook = algorithms.eaSimple(population, toolbox, CXPROB, MUPROB, NGEN, verbose=False, stats=stats)
print("population:\n" +
"\n".join([f"{str(p)} {compute_fitness(f_name, archive, p)[0]}" for p in population]) +
"\n")
for member in population: for member in population:
archive.consider_test(frozendict.frozendict(member)) archive.consider_test(frozendict.frozendict(member))
for gen, record in enumerate(logbook):
print(f"Generation {gen}: min={record['min']} max={record['max']}")
tot_covered = archive.branches_covered() tot_covered = archive.branches_covered()
cov: float = (tot_covered / total_branches) * 100 cov: float = (tot_covered / total_branches) * 100
branches = archive.branches_str() branches = archive.branches_str()
print(f"{orig_name}: rep #{i:02d}: Cov: {cov:02.02f}% ({tot_covered}/{total_branches} branches): {branches}") print(f"{orig_name}: rep #{i:02d}: Cov: {cov:02.02f}% ({tot_covered}/{total_branches} branches): {branches}")
print(archive.build_suite()) print(archive.suite_str())
if cov > top_coverage: if cov > top_coverage:
top_result = archive.build_suite() top_result = archive.build_suite()

61
mutmuttest.py Normal file
View file

@ -0,0 +1,61 @@
import argparse
import os
from mutmut.__main__ import do_run, run_mutation_tests
from mutmut import mutations_by_type
ROOT_DIR = os.path.dirname(__file__)
IN_SOURCE_DIR = os.path.join(ROOT_DIR, "benchmark")
IN_TEST_DIR = os.path.join(ROOT_DIR, "tests")
OUT_DIR = os.path.join(ROOT_DIR, "tests")
def run_mutmut(test_path: str, source_path: str):
run_mutation_tests(config=config, progress=progress, mutations_by_file=mutations_by_file)
do_run(None, source_path, None, None,
'python -m unittest ' + test_path, os.path.dirname(test_path), 0.0, 0.0,
False, False, '', None, None,
None, '', True, False, False, True)
# def run_mutpy(test_path: str, source_path: str):
# # run_genetic([source_path], random.randint(0, 500))
#
# argv = ['-t', source_path, '-u', test_path, '-m']
# argv = ['-t', source_path, '-u', test_path, '-m']
# cfg = commandline.build_parser().parse_args(args=argv)
#
# mutation_controller = commandline.build_controller(cfg)
# mutation_controller.run()
#
# # stream = os.popen(f'mut.py --target \'{source_path}\' --unit-test \'{test_path}\' -m | tee log.txt')
# # output = stream.read()
# # score = re.search('Mutation score \\[.*\\]: (\d+\.\d+)\%', output).group(1)
# # print(output, file=sys.stderr)
# # print(f"Score is: {score}")
def main():
parser = argparse.ArgumentParser(prog='mutmuttest.py',
description='Runs MutPy over generated test suite.')
parser.add_argument('file', type=str, help="Source file to test",
nargs="*")
files = parser.parse_args().file
if len(files) == 0:
files = [os.path.splitext(f) for f in os.listdir(IN_SOURCE_DIR)]
to_test = [file[0] for file in files if file[1] == ".py"]
else:
to_test = [os.path.splitext(os.path.basename(file))[0] for file in files]
for filename in to_test:
for i in range(10):
source_path = os.path.join(IN_SOURCE_DIR, f"{filename}.py")
test_path = os.path.join(IN_TEST_DIR, f"test_{filename}.py")
run_mutmut(test_path, source_path)
break
break
if __name__ == "__main__":
main()

View file

@ -1,12 +1,7 @@
import argparse import argparse
import os import os
import random from mutmut.__main__ import do_run, run_mutation_tests
import re from mutmut import mutations_by_type
import sys
import instrument
from genetic import run_genetic
from mutpy import commandline from mutpy import commandline
ROOT_DIR = os.path.dirname(__file__) ROOT_DIR = os.path.dirname(__file__)
@ -18,7 +13,6 @@ OUT_DIR = os.path.join(ROOT_DIR, "tests")
def run_mutpy(test_path: str, source_path: str): def run_mutpy(test_path: str, source_path: str):
# run_genetic([source_path], random.randint(0, 500)) # run_genetic([source_path], random.randint(0, 500))
argv = ['-t', source_path, '-u', test_path, '-m']
argv = ['-t', source_path, '-u', test_path, '-m'] argv = ['-t', source_path, '-u', test_path, '-m']
cfg = commandline.build_parser().parse_args(args=argv) cfg = commandline.build_parser().parse_args(args=argv)
@ -33,7 +27,7 @@ def run_mutpy(test_path: str, source_path: str):
def main(): def main():
parser = argparse.ArgumentParser(prog='muttest.py', parser = argparse.ArgumentParser(prog='mutmuttest.py',
description='Runs MutPy over generated test suite.') description='Runs MutPy over generated test suite.')
parser.add_argument('file', type=str, help="Source file to test", parser.add_argument('file', type=str, help="Source file to test",
nargs="*") nargs="*")
@ -50,8 +44,6 @@ def main():
source_path = os.path.join(IN_SOURCE_DIR, f"{filename}.py") source_path = os.path.join(IN_SOURCE_DIR, f"{filename}.py")
test_path = os.path.join(IN_TEST_DIR, f"test_{filename}.py") test_path = os.path.join(IN_TEST_DIR, f"test_{filename}.py")
run_mutpy(test_path, source_path) run_mutpy(test_path, source_path)
break
break
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -3,4 +3,4 @@ deap==1.4.1
astunparse==1.6.3 astunparse==1.6.3
frozendict==2.3.8 frozendict==2.3.8
tqdm==4.66.1 tqdm==4.66.1
MutPy==0.6.1 mutmut==2.4.4

View file

@ -1,5 +1,5 @@
[mutmut] [mutmut]
paths_to_mutate=benchmark/anagram_check.py paths_to_mutate=benchmark/
backup=False backup=False
runner=python -m unittest runner=python -m unittest discover tests
tests_dir=tests/ tests_dir=tests/

View file

@ -1,113 +0,0 @@
anagram_check: rep #00: Cov: 87.50% (7/8 branches): 1F 1T 2F 2T 3F 3T 4F
anagram_check: rep #01: Cov: 87.50% (7/8 branches): 1F 1T 2F 2T 3F 3T 4F
anagram_check: rep #02: Cov: 100.00% (8/8 branches): 1F 1T 2F 2T 3F 3T 4F 4T
anagram_check: rep #03: Cov: 87.50% (7/8 branches): 1F 1T 2F 2T 3F 3T 4F
anagram_check: rep #04: Cov: 87.50% (7/8 branches): 1F 1T 2F 2T 3F 3T 4F
anagram_check: rep #05: Cov: 87.50% (7/8 branches): 1F 1T 2F 2T 3F 3T 4F
anagram_check: rep #06: Cov: 100.00% (8/8 branches): 1F 1T 2F 2T 3F 3T 4F 4T
anagram_check: rep #07: Cov: 100.00% (8/8 branches): 1F 1T 2F 2T 3F 3T 4F 4T
anagram_check: rep #08: Cov: 87.50% (7/8 branches): 1F 1T 2F 2T 3F 3T 4F
anagram_check: rep #09: Cov: 100.00% (8/8 branches): 1F 1T 2F 2T 3F 3T 4F 4T
cd_count: rep #00: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
cd_count: rep #01: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
cd_count: rep #02: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
cd_count: rep #03: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
cd_count: rep #04: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
cd_count: rep #05: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
cd_count: rep #06: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
cd_count: rep #07: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
cd_count: rep #08: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
cd_count: rep #09: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
check_armstrong: rep #00: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
check_armstrong: rep #01: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
check_armstrong: rep #02: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
check_armstrong: rep #03: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
check_armstrong: rep #04: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
check_armstrong: rep #05: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
check_armstrong: rep #06: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
check_armstrong: rep #07: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
check_armstrong: rep #08: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
check_armstrong: rep #09: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
decrypt: rep #00: Cov: 100.00% (2/2 branches): 2F 2T
decrypt: rep #01: Cov: 100.00% (2/2 branches): 2F 2T
decrypt: rep #02: Cov: 100.00% (2/2 branches): 2F 2T
decrypt: rep #03: Cov: 100.00% (2/2 branches): 2F 2T
decrypt: rep #04: Cov: 100.00% (2/2 branches): 2F 2T
decrypt: rep #05: Cov: 100.00% (2/2 branches): 2F 2T
decrypt: rep #06: Cov: 100.00% (2/2 branches): 2F 2T
decrypt: rep #07: Cov: 100.00% (2/2 branches): 2F 2T
decrypt: rep #08: Cov: 100.00% (2/2 branches): 2F 2T
decrypt: rep #09: Cov: 100.00% (2/2 branches): 2F 2T
encrypt: rep #00: Cov: 100.00% (2/2 branches): 1F 1T
encrypt: rep #01: Cov: 100.00% (2/2 branches): 1F 1T
encrypt: rep #02: Cov: 100.00% (2/2 branches): 1F 1T
encrypt: rep #03: Cov: 100.00% (2/2 branches): 1F 1T
encrypt: rep #04: Cov: 100.00% (2/2 branches): 1F 1T
encrypt: rep #05: Cov: 100.00% (2/2 branches): 1F 1T
encrypt: rep #06: Cov: 100.00% (2/2 branches): 1F 1T
encrypt: rep #07: Cov: 100.00% (2/2 branches): 1F 1T
encrypt: rep #08: Cov: 100.00% (2/2 branches): 1F 1T
encrypt: rep #09: Cov: 100.00% (2/2 branches): 1F 1T
exponentiation: rep #00: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
exponentiation: rep #01: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
exponentiation: rep #02: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
exponentiation: rep #03: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
exponentiation: rep #04: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
exponentiation: rep #05: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
exponentiation: rep #06: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
exponentiation: rep #07: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
exponentiation: rep #08: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
gcd: rep #00: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
gcd: rep #01: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
gcd: rep #02: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
gcd: rep #03: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
gcd: rep #04: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
gcd: rep #05: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
gcd: rep #06: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
gcd: rep #07: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
gcd: rep #08: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
gcd: rep #09: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
longest_sorted_substr: rep #00: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
longest_sorted_substr: rep #01: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
longest_sorted_substr: rep #02: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
longest_sorted_substr: rep #03: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
longest_sorted_substr: rep #04: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
longest_sorted_substr: rep #05: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
longest_sorted_substr: rep #06: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
longest_sorted_substr: rep #07: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
longest_sorted_substr: rep #08: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
longest_sorted_substr: rep #09: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
rabin_karp_search: rep #00: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
rabin_karp_search: rep #01: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
rabin_karp_search: rep #02: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
rabin_karp_search: rep #03: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
rabin_karp_search: rep #04: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
rabin_karp_search: rep #05: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
rabin_karp_search: rep #06: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
rabin_karp_search: rep #07: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
rabin_karp_search: rep #08: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
rabin_karp_search: rep #09: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
raildecrypt: rep #00: Cov: 87.50% (14/16 branches): 5F 5T 6F 6T 7F 8F 8T 9T 10F 10T 11F 11T 12F 12T
raildecrypt: rep #01: Cov: 93.75% (15/16 branches): 5F 5T 6F 6T 7F 7T 8F 8T 9T 10F 10T 11F 11T 12F 12T
raildecrypt: rep #02: Cov: 93.75% (15/16 branches): 5F 5T 6F 6T 7F 7T 8F 8T 9T 10F 10T 11F 11T 12F 12T
raildecrypt: rep #03: Cov: 87.50% (14/16 branches): 5F 5T 6F 6T 7F 8F 8T 9T 10F 10T 11F 11T 12F 12T
raildecrypt: rep #04: Cov: 87.50% (14/16 branches): 5F 5T 6F 6T 7F 8F 8T 9T 10F 10T 11F 11T 12F 12T
raildecrypt: rep #05: Cov: 87.50% (14/16 branches): 5F 5T 6F 6T 7F 8F 8T 9T 10F 10T 11F 11T 12F 12T
raildecrypt: rep #06: Cov: 93.75% (15/16 branches): 5F 5T 6F 6T 7F 7T 8F 8T 9T 10F 10T 11F 11T 12F 12T
raildecrypt: rep #07: Cov: 93.75% (15/16 branches): 5F 5T 6F 6T 7F 7T 8F 8T 9T 10F 10T 11F 11T 12F 12T
raildecrypt: rep #08: Cov: 93.75% (15/16 branches): 5F 5T 6F 6T 7F 7T 8F 8T 9T 10F 10T 11F 11T 12F 12T
raildecrypt: rep #09: Cov: 68.75% (11/16 branches): 5T 6F 6T 8F 8T 9T 10F 10T 11F 11T 12T
railencrypt: rep #00: Cov: 100.00% (8/8 branches): 1F 1T 2F 2T 3F 3T 4F 4T
railencrypt: rep #01: Cov: 100.00% (8/8 branches): 1F 1T 2F 2T 3F 3T 4F 4T
railencrypt: rep #02: Cov: 62.50% (5/8 branches): 1T 2F 2T 4F 4T
railencrypt: rep #03: Cov: 100.00% (8/8 branches): 1F 1T 2F 2T 3F 3T 4F 4T
zeller: rep #00: Cov: 93.75% (15/16 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6T 7F 7T 8F 8T
zeller: rep #01: Cov: 93.75% (15/16 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6T 7F 7T 8F 8T
zeller: rep #02: Cov: 93.75% (15/16 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6T 7F 7T 8F 8T
zeller: rep #03: Cov: 93.75% (15/16 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6T 7F 7T 8F 8T
zeller: rep #04: Cov: 93.75% (15/16 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6T 7F 7T 8F 8T
zeller: rep #05: Cov: 93.75% (15/16 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6T 7F 7T 8F 8T
zeller: rep #06: Cov: 93.75% (15/16 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6T 7F 7T 8F 8T
zeller: rep #07: Cov: 93.75% (15/16 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6T 7F 7T 8F 8T
zeller: rep #08: Cov: 93.75% (15/16 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6T 7F 7T 8F 8T
zeller: rep #09: Cov: 93.75% (15/16 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6T 7F 7T 8F 8T

View file

@ -1,22 +1,19 @@
from unittest import TestCase from unittest import TestCase
from benchmark.anagram_check import anagram_check from benchmark.anagram_check import anagram_check
import inspect
class Test_anagram_check(TestCase): class Test_anagram_check(TestCase):
# distances_true = {1: [0], 2: [0]} # distances_true = {1: [0], 2: [0]}
# distances_false = {1: [1], 2: [1]} # distances_false = {1: [1], 2: [1]}
def test_anagram_check_1(self): def test_anagram_check_1(self):
print(f"aaaaa {inspect.getsource(anagram_check)}") assert anagram_check(s1='/', s2='6') == False
self.assertTrue(anagram_check(s1='e', s2='4') == False)
# distances_true = {1: [1], 3: [0]}
# distances_false = {1: [0], 3: [1]}
def test_anagram_check_2(self):
print(f"aaaaa {inspect.getsource(anagram_check)}")
self.assertTrue(anagram_check(s1='|:', s2=',=U') == False)
# distances_true = {1: [1], 3: [1], 4: [0]} # distances_true = {1: [1], 3: [1], 4: [0]}
# distances_false = {1: [0], 3: [0], 4: [1]} # distances_false = {1: [0], 3: [0], 4: [1]}
def test_anagram_check_2(self):
assert anagram_check(s1='', s2='') == True
# distances_true = {1: [1], 3: [0]}
# distances_false = {1: [0], 3: [1]}
def test_anagram_check_3(self): def test_anagram_check_3(self):
print(f"aaaaa {inspect.getsource(anagram_check)}") assert anagram_check(s1='md', s2='p') == False
self.assertTrue(anagram_check(s1='', s2='') == True)

View file

@ -4,14 +4,14 @@ from benchmark.caesar_cipher import decrypt
class Test_encrypt(TestCase): class Test_encrypt(TestCase):
# distances_true = {1: [16, 0, 17, 0, 0, 41, 31]} # distances_true = {1: [0, 0, 0, 0, 40, 0, 31, 22]}
# distances_false = {1: [0, 42, 0, 13, 52, 0, 0]} # distances_false = {1: [33, 14, 23, 29, 0, 28, 0, 0]}
def test_encrypt_1(self): def test_encrypt_1(self):
assert encrypt(strng=';t:W~",', key=52) == 'oIn,SV`' assert encrypt(strng='vclr.q7@', key=41) == '@-6<W;`i'
class Test_decrypt(TestCase): class Test_decrypt(TestCase):
# distances_true = {2: [215, 0, 6, 0, 25, 0, 0, 223]} # distances_true = {2: [0, 0, 1, 0, 0, 3, 1, 18, 48]}
# distances_false = {2: [0, 6, 0, 18, 0, 19, 27, 0]} # distances_false = {2: [1, 3, 0, 15, 6, 0, 0, 0, 0]}
def test_decrypt_1(self): def test_decrypt_1(self):
assert decrypt(strng="'KV?i>6/", key=49) == 'öy%m8ldþ' assert decrypt(strng='203$-53Db', key=19) == '~| py" 1O'

View file

@ -3,22 +3,27 @@ from benchmark.check_armstrong import check_armstrong
class Test_check_armstrong(TestCase): class Test_check_armstrong(TestCase):
# distances_true = {1: [977], 2: [976], 3: [827], 4: [0, 0, 0, 1], 5: [438]} # distances_true = {1: [2], 2: [1], 3: [0]}
# distances_false = {1: [0], 2: [0], 3: [0], 4: [977, 97, 9, 0], 5: [0]} # distances_false = {1: [0], 2: [0], 3: [149]}
def test_check_armstrong_1(self): def test_check_armstrong_1(self):
assert check_armstrong(n=977) == False assert check_armstrong(n=2) == False
# distances_true = {1: [0]} # distances_true = {1: [0]}
# distances_false = {1: [1]} # distances_false = {1: [1]}
def test_check_armstrong_2(self): def test_check_armstrong_2(self):
assert check_armstrong(n=0) == True assert check_armstrong(n=0) == True
# distances_true = {1: [140], 2: [139], 3: [0]} # distances_true = {1: [380], 2: [379], 3: [230], 4: [0, 0, 0, 1], 5: [159]}
# distances_false = {1: [0], 2: [0], 3: [11]} # distances_false = {1: [0], 2: [0], 3: [0], 4: [380, 38, 3, 0], 5: [0]}
def test_check_armstrong_3(self): def test_check_armstrong_3(self):
assert check_armstrong(n=140) == False assert check_armstrong(n=380) == False
# distances_true = {1: [3], 2: [2], 3: [0]} # distances_true = {1: [153], 2: [152], 3: [3], 4: [0, 0, 0, 1], 5: [0]}
# distances_false = {1: [0], 2: [0], 3: [148]} # distances_false = {1: [0], 2: [0], 3: [0], 4: [153, 15, 1, 0], 5: [1]}
def test_check_armstrong_4(self): def test_check_armstrong_4(self):
assert check_armstrong(n=3) == False assert check_armstrong(n=153) == True
# distances_true = {1: [1], 2: [0]}
# distances_false = {1: [0], 2: [1]}
def test_check_armstrong_5(self):
assert check_armstrong(n=1) == True

View file

@ -3,32 +3,32 @@ from benchmark.common_divisor_count import cd_count
class Test_cd_count(TestCase): class Test_cd_count(TestCase):
# distances_true = {1: [7], 2: [561], 3: [8], 4: [0], 5: [0, 0, 1], 6: [0], 7: [0]} # distances_true = {1: [5], 2: [618], 3: [6], 4: [619], 5: [0, 0, 0, 0, 1], 6: [0], 7: [0]}
# distances_false = {1: [0], 2: [0], 3: [0], 4: [561], 5: [7, 1, 0], 6: [1], 7: [1]} # distances_false = {1: [0], 2: [0], 3: [0], 4: [0], 5: [5, 3, 2, 1, 0], 6: [1], 7: [1]}
def test_cd_count_1(self): def test_cd_count_1(self):
assert cd_count(a=7, b=-561) == 1 assert cd_count(a=5, b=618) == 1
# distances_true = {1: [496], 2: [9], 3: [0], 4: [10], 5: [0, 0, 0, 1], 6: [0], 7: [0]} # distances_true = {1: [0]}
# distances_false = {1: [0], 2: [0], 3: [496], 4: [0], 5: [496, 9, 1, 0], 6: [1], 7: [1]} # distances_false = {1: [1]}
def test_cd_count_2(self): def test_cd_count_2(self):
assert cd_count(a=-496, b=9) == 1 assert cd_count(a=0, b=-49) == 2
# distances_true = {1: [1090], 2: [810], 3: [0], 4: [0], 5: [0, 0, 0, 0, 0, 0, 1], 6: [0, 0, 1], 7: [9, 3]} # distances_true = {1: [4], 2: [101], 3: [5], 4: [0], 5: [0, 0, 1], 6: [0], 7: [0]}
# distances_false = {1: [0], 2: [0], 3: [1090], 4: [810], 5: [1090, 810, 280, 250, 30, 10, 0], 6: [1, 1, 0], 7: [0, 0]} # distances_false = {1: [0], 2: [0], 3: [0], 4: [101], 5: [4, 1, 0], 6: [1], 7: [1]}
def test_cd_count_3(self): def test_cd_count_3(self):
assert cd_count(a=-1090, b=-810) == 4 assert cd_count(a=4, b=-101) == 1
# distances_true = {1: [771], 2: [0]} # distances_true = {1: [10], 2: [52], 3: [0], 4: [0], 5: [0, 0, 1], 6: [0], 7: [1]}
# distances_false = {1: [0], 2: [1]} # distances_false = {1: [0], 2: [0], 3: [10], 4: [52], 5: [10, 2, 0], 6: [1], 7: [0]}
def test_cd_count_4(self): def test_cd_count_4(self):
assert cd_count(a=771, b=0) == 2 assert cd_count(a=-10, b=-52) == 2
# distances_true = {1: [0]} # distances_true = {1: [9], 2: [0]}
# distances_false = {1: [1]} # distances_false = {1: [0], 2: [1]}
def test_cd_count_5(self): def test_cd_count_5(self):
assert cd_count(a=0, b=-504) == 2 assert cd_count(a=9, b=0) == 2
# distances_true = {1: [0]} # distances_true = {1: [10], 2: [150], 3: [0], 4: [0], 5: [0, 1], 6: [0, 0, 1], 7: [9, 3]}
# distances_false = {1: [1]} # distances_false = {1: [0], 2: [0], 3: [10], 4: [150], 5: [10, 0], 6: [1, 1, 0], 7: [0, 0]}
def test_cd_count_6(self): def test_cd_count_6(self):
assert cd_count(a=0, b=346) == 2 assert cd_count(a=-10, b=-150) == 4

View file

@ -3,7 +3,7 @@ from benchmark.exponentiation import exponentiation
class Test_exponentiation(TestCase): class Test_exponentiation(TestCase):
# distances_true = {1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 3: [0], 2: [1, 1, 1, 0, 1, 0, 1, 0, 0]} # distances_true = {1: [0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 3: [0], 2: [1, 1, 0, 1, 0, 1, 1, 1, 1]}
# distances_false = {1: [554, 276, 137, 68, 33, 16, 7, 3, 1, 0], 3: [1], 2: [0, 0, 0, 1, 0, 1, 0, 1, 1]} # distances_false = {1: [591, 295, 147, 73, 36, 17, 8, 3, 1, 0], 3: [1], 2: [0, 0, 1, 0, 1, 0, 0, 0, 0]}
def test_exponentiation_1(self): def test_exponentiation_1(self):
assert exponentiation(baseNumber=46, power=555) == 67701233776950740204942019458828678585228142727678765936712535724840687550392116600906870144545698010222155411454260850560248023622100924992829889775933434061810832462573875369185421327277159309564167510534321885543792397713571903199824376891708112137193105827711458802486745550166352806857564334946534837344031123784629760780542963072605426968444846293162755227316493959098410341690649453984690766001914535282833132048115400743640541717271552222480474321128912084160330658824454957670614550610057315309451870771464295316404482951582420308563847120161312137794517827199490374669737373326830613443532865503190040204882188234457906737870995608971298860024320484356074519686361893084826607266908460838607722699711920001088429651680486816904830482100545984931012988682700360948582560942831753442007911350372119223160722859489509754277036741791779555164722595786304251143106041689420581326006007810981939096858483944366828158976 assert exponentiation(baseNumber=748, power=592) == 2237411859567305228712820969577177889399507688925863669623492970046756800811752671771192642266754818786206883016528099952656873068236573570940727536208482507787576742117892529716174302439216500172363521344994812494798736599216689085381729125165667408413134378577619291662064250215391547791138001022452137862778730264821893010999654434708983063321061487758219131875157534566833176981850918287964729665626846138477133321680757074668758491790945198601054224199588300081988215907925870651530562786845054260705838873377721118111382749970684115994163428904242940249188932413043444079730697574946438556722431973692672316117631662669780447322962255376036216266360170992797300680863608151678208837497803629559832285706122751678247068182933676547879825690946817522731921058001762116141626296741021042361970731691972888241818460142317141771780073548156492405406490981515425290002128649234461825789947573119368985161153262332388808724131879060867880473096842000650483632521058294479344879944564436266652927131107918428149402925778007533423162302903655859402260228366219008304205413113994847339399353552421491921433679173463981507810853240889014970942564956030433528528976883729747234323037570498652835167034147294039927751837932259353682824119565000780453933743514380393121666554146174425347788804096581718436380869076273595714279596282320033858652789005508958162362572551844879419089353500606113442189427958545044465106509994666028492893004614086892576645413919934301813479926994631172622364458500761310743512340332065554689760340750349754142540650730287762939301975905339162897423087384712675419496189151357961520127467940210297313531487397450555066413386239184330770939775155310643870407646031104489325011664896

View file

@ -2,3 +2,23 @@ from unittest import TestCase
from benchmark.gcd import gcd from benchmark.gcd import gcd
class Test_gcd(TestCase):
# distances_true = {1: [0]}
# distances_false = {1: [1]}
def test_gcd_1(self):
assert gcd(a=1, b=376) == 1
# distances_true = {1: [3], 2: [309], 3: [306], 4: [0], 5: [0, 0, 1]}
# distances_false = {1: [0], 2: [0], 3: [0], 4: [306], 5: [4, 2, 0]}
def test_gcd_2(self):
assert gcd(a=4, b=310) == 2
# distances_true = {1: [930], 2: [8], 3: [922], 4: [923], 5: [0, 0, 0, 1]}
# distances_false = {1: [0], 2: [0], 3: [0], 4: [0], 5: [9, 4, 1, 0]}
def test_gcd_3(self):
assert gcd(a=931, b=9) == 1
# distances_true = {1: [698], 2: [0]}
# distances_false = {1: [0], 2: [1]}
def test_gcd_4(self):
assert gcd(a=699, b=1) == 1

View file

@ -3,5 +3,7 @@ from benchmark.longest_substring import longest_sorted_substr
class Test_longest_sorted_substr(TestCase): class Test_longest_sorted_substr(TestCase):
# distances_true = {1: [45, 0, 14, 0, 15, 0, 0], 2: [0, 1, 1, 0]}
# distances_false = {1: [0, 43, 0, 13, 0, 30, 3], 2: [1, 0, 0, 1]}
def test_longest_sorted_substr_1(self): def test_longest_sorted_substr_1(self):
assert longest_sorted_substr(s='sixBa') == 'ix' assert longest_sorted_substr(s='b5_Q]Nkm') == 'Nkm'

View file

@ -3,14 +3,17 @@ from benchmark.rabin_karp import rabin_karp_search
class Test_rabin_karp_search(TestCase): class Test_rabin_karp_search(TestCase):
# distances_true = {1: [0], 2: [1], 3: [0], 4: [1]}
# distances_false = {1: [1], 2: [0], 3: [1], 4: [0]}
def test_rabin_karp_search_1(self): def test_rabin_karp_search_1(self):
assert rabin_karp_search(pat='3gx!', txt='~*J~%eC') == [0] assert rabin_karp_search(pat='z', txt='z') == [0]
# distances_true = {1: [0], 2: [0], 3: [3], 4: [1]}
# distances_false = {1: [1], 2: [23], 3: [0], 4: [0]}
def test_rabin_karp_search_2(self): def test_rabin_karp_search_2(self):
assert rabin_karp_search(pat='`gO7Vq!kU', txt='=DLaH\\p~[') == [] assert rabin_karp_search(pat='b&k<', txt='K@qO') == []
# distances_true = {1: [0, 0, 61, 51, 81, 82, 87, 98], 3: [1, 2], 4: [0, 0, 0, 0, 0, 0, 0, 1], 5: [1, 62, 52, 82, 83, 88, 99]}
# distances_false = {1: [1, 1, 0, 0, 0, 0, 0, 0], 3: [0, 0], 4: [7, 6, 5, 4, 3, 2, 1, 0], 5: [0, 0, 0, 0, 0, 0, 0]}
def test_rabin_karp_search_3(self): def test_rabin_karp_search_3(self):
assert rabin_karp_search(pat='', txt='%gxypQ7L') == [] assert rabin_karp_search(pat='', txt='ex[>NC6') == []
def test_rabin_karp_search_4(self):
assert rabin_karp_search(pat='@', txt='H@@|DPma"') == [1, 2]

View file

@ -4,14 +4,14 @@ from benchmark.railfence_cipher import raildecrypt
class Test_railencrypt(TestCase): class Test_railencrypt(TestCase):
# distances_true = {1: [0, 0, 0, 0, 0, 1, 1, 1, 1], 2: [4, 3, 2, 1, 0], 3: [3, 2, 1, 0], 4: [0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1]} # distances_true = {1: [0, 0, 0, 0, 1, 1, 1, 0, 0], 2: [3, 2, 1, 0, 2, 1], 3: [2, 1, 0], 4: [0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1]}
# distances_false = {1: [1, 1, 1, 1, 1, 0, 0, 0, 0], 2: [0, 0, 0, 0, 1], 3: [0, 0, 0, 1], 4: [80, 0, 0, 0, 0, 0, 0, 0, 65, 0, 113, 0, 0, 0, 0, 0, 69, 0, 0, 0, 109, 0, 0, 0, 111, 0, 0, 0, 0, 0, 73, 0, 98, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0]} # distances_false = {1: [1, 1, 1, 1, 0, 0, 0, 1, 1], 2: [0, 0, 0, 1, 0, 0], 3: [0, 0, 1], 4: [102, 0, 0, 0, 0, 0, 112, 0, 0, 0, 110, 0, 0, 0, 122, 0, 52, 0, 0, 0, 124, 0, 50, 0, 0, 0, 48, 0, 0, 0, 38, 0, 0, 0, 0, 0]}
def test_railencrypt_1(self): def test_railencrypt_1(self):
assert railencrypt(st='PqmI%boEA', k=5) == 'PAqEmoIb%' assert railencrypt(st='fn|&2zp40', k=4) == 'fpnz4|20&'
class Test_raildecrypt(TestCase): class Test_raildecrypt(TestCase):
# distances_true = {5: [0, 0, 0, 1, 1, 0, 0, 1], 6: [2, 1, 0, 1, 0], 7: [1, 0, 1], 8: [0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1], 9: [0, 0, 0, 0, 0, 0, 0, 0], 10: [8, 0, 0, 1, 1, 0, 0, 1], 12: [0, 1, 0, 1], 11: [1, 0, 1, 0]} # distances_true = {5: [0, 0, 0, 0, 1, 1, 1], 6: [3, 2, 1, 0], 7: [2, 1, 0], 8: [0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1], 9: [0, 0, 0, 0, 0, 0, 0], 10: [7, 0, 0, 0, 1, 1, 1], 12: [0, 2, 1, 0], 11: [2, 1, 0]}
# distances_false = {5: [1, 1, 1, 0, 0, 1, 1, 0], 6: [0, 0, 1, 0, 1], 7: [0, 1, 0], 8: [1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0], 9: [114, 32, 42, 113, 94, 101, 66, 91], 10: [0, 1, 1, 0, 0, 1, 1, 0], 12: [1, 0, 1, 0], 11: [0, 1, 0, 1]} # distances_false = {5: [1, 1, 1, 1, 0, 0, 0], 6: [0, 0, 0, 1], 7: [0, 0, 1], 8: [1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0], 9: [125, 79, 95, 32, 85, 109, 46], 10: [0, 1, 1, 1, 0, 0, 0], 12: [1, 0, 0, 1], 11: [0, 0, 1]}
def test_raildecrypt_1(self): def test_raildecrypt_1(self):
assert raildecrypt(st='r^ qe[*B', k=3) == 'r *q^eB[' assert raildecrypt(st='}.Om_U ', k=4) == '}O_ Um.'

View file

@ -3,17 +3,17 @@ from benchmark.zellers_birthday import zeller
class Test_zeller(TestCase): class Test_zeller(TestCase):
# distances_true = {1: [0], 2: [0], 3: [901], 5: [901], 7: [0], 8: [3, 2, 1, 0]} # distances_true = {1: [1], 2: [6], 3: [0], 4: [0], 5: [1923], 7: [5], 8: [0]}
# distances_false = {1: [1], 2: [913], 3: [0], 5: [0], 7: [1], 8: [0, 0, 0, 1]} # distances_false = {1: [0], 2: [0], 3: [78], 4: [1], 5: [0], 7: [0], 8: [1]}
def test_zeller_1(self): def test_zeller_1(self):
assert zeller(d=32, m=-925, y=-1000) == 'Wednesday' assert zeller(d=31, m=7, y=-22) == 'Sunday'
# distances_true = {1: [0], 2: [0], 3: [0], 4: [0], 5: [1903], 7: [7], 8: [2, 1, 0]} # distances_true = {1: [0], 2: [0], 3: [0], 4: [0], 5: [1923], 7: [0], 8: [3, 2, 1, 0]}
# distances_false = {1: [691], 2: [536], 3: [98], 4: [21], 5: [0], 7: [0], 8: [0, 0, 1]} # distances_false = {1: [1], 2: [1], 3: [78], 4: [1], 5: [0], 7: [1], 8: [0, 0, 0, 1]}
def test_zeller_2(self): def test_zeller_2(self):
assert zeller(d=-722, m=548, y=-2) == 'Tuesday' assert zeller(d=32, m=13, y=-22) == 'Wednesday'
# distances_true = {1: [0], 2: [7], 3: [0], 4: [1], 5: [0], 6: [0], 7: [4], 8: [4, 3, 2, 1, 0]} # distances_true = {1: [1], 2: [0], 3: [0], 4: [8], 5: [0], 6: [0], 7: [0], 8: [1, 0]}
# distances_false = {1: [285], 2: [0], 3: [77], 4: [0], 5: [77], 6: [1], 7: [0], 8: [0, 0, 0, 0, 1]} # distances_false = {1: [0], 2: [1], 3: [70], 4: [0], 5: [70], 6: [8], 7: [1], 8: [0, 1]}
def test_zeller_3(self): def test_zeller_3(self):
assert zeller(d=316, m=6, y=-23) == 'Thursday' assert zeller(d=31, m=13, y=-30) == 'Monday'