aaa
This commit is contained in:
parent
7ca85a871d
commit
6bb60c3323
17 changed files with 167 additions and 129 deletions
|
@ -84,7 +84,7 @@ def random_params(arguments: list[Arg]) -> Params:
|
||||||
pools: dict[tuple, set[tuple]] = {}
|
pools: dict[tuple, set[tuple]] = {}
|
||||||
|
|
||||||
|
|
||||||
def get_pool(arguments: list[Arg]) -> set[Params]:
|
def get_pool(arguments: list[Arg]) -> list[Params]:
|
||||||
arg_types = tuple([arg_type for _, arg_type in arguments])
|
arg_types = tuple([arg_type for _, arg_type in arguments])
|
||||||
arg_names = [arg_name for arg_name, _ in arguments]
|
arg_names = [arg_name for arg_name, _ in arguments]
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ def get_pool(arguments: list[Arg]) -> set[Params]:
|
||||||
|
|
||||||
pools[arg_types] = new_pool
|
pools[arg_types] = new_pool
|
||||||
|
|
||||||
return set([frozendict({arg_names[i]: p for i, p in enumerate(param)}) for param in pools[arg_types]])
|
return [frozendict({arg_names[i]: p for i, p in enumerate(param)}) for param in pools[arg_types]]
|
||||||
|
|
||||||
|
|
||||||
def mutate(test_case: Params, arguments: list[Arg]) -> Params:
|
def mutate(test_case: Params, arguments: list[Arg]) -> Params:
|
||||||
|
@ -132,7 +132,7 @@ def crossover(chosen_test: Params, other_chosen_test: Params, arguments: list[Ar
|
||||||
|
|
||||||
|
|
||||||
def generate_test_case(f_name: str, arguments: list[Arg]) -> Params:
|
def generate_test_case(f_name: str, arguments: list[Arg]) -> Params:
|
||||||
pool: set[Params] = get_pool(arguments)
|
pool: list[Params] = get_pool(arguments)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
test = sample(pool, 1)[0]
|
test = sample(pool, 1)[0]
|
||||||
|
|
104
genetic.py
104
genetic.py
|
@ -1,6 +1,8 @@
|
||||||
|
import argparse
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
import frozendict
|
import frozendict
|
||||||
import tqdm
|
import tqdm
|
||||||
|
@ -8,6 +10,7 @@ from deap import creator, base, tools, algorithms
|
||||||
|
|
||||||
import fuzzer
|
import fuzzer
|
||||||
import instrument
|
import instrument
|
||||||
|
import operators
|
||||||
from fuzzer import generate_test_case, get_test_class
|
from fuzzer import generate_test_case, get_test_class
|
||||||
|
|
||||||
INDMUPROB = 0.05
|
INDMUPROB = 0.05
|
||||||
|
@ -18,11 +21,32 @@ NPOP = 1000
|
||||||
NGEN = 200
|
NGEN = 200
|
||||||
REPS = 10
|
REPS = 10
|
||||||
|
|
||||||
to_test: str = ""
|
|
||||||
|
|
||||||
OUT_DIR = os.path.join(os.path.dirname(__file__), "tests")
|
OUT_DIR = os.path.join(os.path.dirname(__file__), "tests")
|
||||||
|
|
||||||
|
|
||||||
|
class Archive:
|
||||||
|
true_branches: dict[int, any]
|
||||||
|
false_branches: dict[int, any]
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.true_branches = {}
|
||||||
|
self.false_branches = {}
|
||||||
|
|
||||||
|
def branches_covered(self) -> int:
|
||||||
|
return len(self.true_branches.keys()) + len(self.false_branches.keys())
|
||||||
|
|
||||||
|
def branches_str(self) -> str:
|
||||||
|
branch_ids = sorted([f"{branch:2d}T" for branch in self.true_branches.keys()] +
|
||||||
|
[f"{branch:2d}F" for branch in self.false_branches.keys()])
|
||||||
|
return ' '.join([branch.strip() for branch in branch_ids])
|
||||||
|
|
||||||
|
def build_suite(self) -> set[instrument.Params]:
|
||||||
|
return set(list(self.true_branches.values()) + list(self.false_branches.values()))
|
||||||
|
|
||||||
|
|
||||||
def normalize(x):
|
def normalize(x):
|
||||||
return x / (1.0 + x)
|
return x / (1.0 + x)
|
||||||
|
|
||||||
|
@ -32,25 +56,19 @@ def init_deap():
|
||||||
creator.create("Individual", list, fitness=creator.Fitness)
|
creator.create("Individual", list, fitness=creator.Fitness)
|
||||||
|
|
||||||
|
|
||||||
def taken_branches_descriptor() -> str:
|
|
||||||
branch_ids = sorted([f"{branch:2d}T" for branch in instrument.archive_true_branches.keys()] +
|
|
||||||
[f"{branch:2d}F" for branch in instrument.archive_false_branches.keys()])
|
|
||||||
return ' '.join([branch.strip() for branch in branch_ids])
|
|
||||||
|
|
||||||
|
|
||||||
def generate(f_name: str):
|
def generate(f_name: str):
|
||||||
global to_test
|
|
||||||
to_test = f_name
|
|
||||||
|
|
||||||
orig_name = instrument.BranchTransformer.to_original_name(f_name)
|
orig_name = instrument.BranchTransformer.to_original_name(f_name)
|
||||||
|
|
||||||
args = instrument.functions[f_name]
|
args = instrument.functions[f_name]
|
||||||
|
|
||||||
|
range_start, range_end = instrument.n_of_branches[f_name]
|
||||||
|
total_branches = (range_end - range_start) * 2 # *2 because of True and False
|
||||||
|
archive = Archive()
|
||||||
|
|
||||||
toolbox = base.Toolbox()
|
toolbox = base.Toolbox()
|
||||||
toolbox.register("attr_test_case", lambda: list(generate_test_case(f_name, args).items()))
|
toolbox.register("attr_test_case", lambda: list(generate_test_case(f_name, args).items()))
|
||||||
toolbox.register("individual", tools.initIterate, creator.Individual, lambda: toolbox.attr_test_case())
|
toolbox.register("individual", tools.initIterate, creator.Individual, lambda: toolbox.attr_test_case())
|
||||||
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
|
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
|
||||||
toolbox.register("evaluate", compute_fitness)
|
toolbox.register("evaluate", partial(compute_fitness, f_name, archive))
|
||||||
|
|
||||||
def mate(tc1, tc2):
|
def mate(tc1, tc2):
|
||||||
t1, t2 = frozendict.frozendict(tc1), frozendict.frozendict(tc2)
|
t1, t2 = frozendict.frozendict(tc1), frozendict.frozendict(tc2)
|
||||||
|
@ -71,44 +89,33 @@ def generate(f_name: str):
|
||||||
top_result = set()
|
top_result = set()
|
||||||
top_coverage = 0
|
top_coverage = 0
|
||||||
|
|
||||||
range_start, range_end = instrument.n_of_branches[to_test]
|
|
||||||
total_branches = (range_end - range_start) * 2 # *2 because of True and False
|
|
||||||
|
|
||||||
coverage = []
|
|
||||||
for i in range(REPS):
|
for i in range(REPS):
|
||||||
instrument.archive_true_branches = {}
|
archive.reset()
|
||||||
instrument.archive_false_branches = {}
|
|
||||||
population = toolbox.population(n=NPOP)
|
population = toolbox.population(n=NPOP)
|
||||||
|
|
||||||
algorithms.eaSimple(population, toolbox, CXPROB, MUPROB, NGEN, verbose=False)
|
algorithms.eaSimple(population, toolbox, CXPROB, MUPROB, NGEN, verbose=False)
|
||||||
|
|
||||||
true_covered = len(instrument.archive_true_branches.keys())
|
tot_covered = archive.branches_covered()
|
||||||
false_covered = len(instrument.archive_false_branches.keys())
|
|
||||||
tot_covered = true_covered + false_covered
|
|
||||||
|
|
||||||
cov: float = (tot_covered / total_branches) * 100
|
cov: float = (tot_covered / total_branches) * 100
|
||||||
coverage.append(cov)
|
|
||||||
|
|
||||||
branches = taken_branches_descriptor()
|
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}")
|
||||||
|
|
||||||
if cov > top_coverage:
|
if cov > top_coverage:
|
||||||
top_result = set(list(instrument.archive_true_branches.values()) +
|
top_result = archive.build_suite()
|
||||||
list(instrument.archive_false_branches.values()))
|
|
||||||
top_coverage = cov
|
top_coverage = cov
|
||||||
|
|
||||||
print(coverage)
|
|
||||||
|
|
||||||
return top_result
|
return top_result
|
||||||
|
|
||||||
|
|
||||||
def compute_fitness(individual: list) -> tuple[float]:
|
def compute_fitness(f_name: str, archive: Archive, individual: list) -> tuple[float]:
|
||||||
x = frozendict.frozendict(individual)
|
x = frozendict.frozendict(individual)
|
||||||
range_start, range_end = instrument.n_of_branches[to_test]
|
range_start, range_end = instrument.n_of_branches[f_name]
|
||||||
|
|
||||||
# Reset any distance values from previous executions
|
# Reset any distance values from previous executions
|
||||||
instrument.distances_true = {}
|
operators.distances_true = {}
|
||||||
instrument.distances_false = {}
|
operators.distances_false = {}
|
||||||
|
|
||||||
# the archive_true_branches and archive_false_branches are reset after
|
# the archive_true_branches and archive_false_branches are reset after
|
||||||
# each generation. This is intentional as they are used to archive branches that
|
# each generation. This is intentional as they are used to archive branches that
|
||||||
|
@ -117,7 +124,7 @@ def compute_fitness(individual: list) -> tuple[float]:
|
||||||
|
|
||||||
# Run the function under test
|
# Run the function under test
|
||||||
try:
|
try:
|
||||||
out = instrument.invoke(to_test, x)
|
instrument.invoke(f_name, x)
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
# print(to_test, x, "=", "[FAILS] fitness = 100.0")
|
# print(to_test, x, "=", "[FAILS] fitness = 100.0")
|
||||||
return 100.0,
|
return 100.0,
|
||||||
|
@ -126,18 +133,18 @@ def compute_fitness(individual: list) -> tuple[float]:
|
||||||
|
|
||||||
# Sum up branch distances
|
# Sum up branch distances
|
||||||
for branch in range(range_start, range_end):
|
for branch in range(range_start, range_end):
|
||||||
if branch in instrument.distances_true:
|
if branch in operators.distances_true:
|
||||||
if instrument.distances_true[branch] == 0 and branch not in instrument.archive_true_branches:
|
if operators.distances_true[branch] == 0 and branch not in archive.true_branches:
|
||||||
instrument.archive_true_branches[branch] = x
|
archive.true_branches[branch] = x
|
||||||
if branch not in instrument.archive_true_branches:
|
if branch not in archive.true_branches:
|
||||||
fitness += normalize(instrument.distances_true[branch])
|
fitness += normalize(operators.distances_true[branch])
|
||||||
|
|
||||||
for branch in range(range_start, range_end):
|
for branch in range(range_start, range_end):
|
||||||
if branch in instrument.distances_false:
|
if branch in operators.distances_false:
|
||||||
if instrument.distances_false[branch] == 0 and branch not in instrument.archive_false_branches:
|
if operators.distances_false[branch] == 0 and branch not in archive.false_branches:
|
||||||
instrument.archive_false_branches[branch] = x
|
archive.false_branches[branch] = x
|
||||||
if branch not in instrument.archive_false_branches:
|
if branch not in archive.false_branches:
|
||||||
fitness += normalize(instrument.distances_false[branch])
|
fitness += normalize(operators.distances_false[branch])
|
||||||
|
|
||||||
# print(to_test, x, "=", out, "fitness =", fitness)
|
# print(to_test, x, "=", out, "fitness =", fitness)
|
||||||
return fitness,
|
return fitness,
|
||||||
|
@ -146,13 +153,20 @@ def compute_fitness(individual: list) -> tuple[float]:
|
||||||
def build_suite(f_name: str):
|
def build_suite(f_name: str):
|
||||||
instr_name = instrument.BranchTransformer.to_instrumented_name(f_name)
|
instr_name = instrument.BranchTransformer.to_instrumented_name(f_name)
|
||||||
cases = generate(instr_name)
|
cases = generate(instr_name)
|
||||||
with open(os.path.join(OUT_DIR, f_name + ".py"), "w") as f:
|
with open(os.path.join(OUT_DIR, "test_" + f_name + ".py"), "w") as f:
|
||||||
f.write(get_test_class(instr_name, cases))
|
f.write(get_test_class(instr_name, cases))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
random.seed(0) # init random seed
|
random.seed(0) # init random seed
|
||||||
instrument.load_benchmark(save_instrumented=False) # instrument all files in benchmark
|
|
||||||
|
parser = argparse.ArgumentParser(prog='genetic.py',
|
||||||
|
description='Runs genetic algorithm for test case generation. Works on benchmark '
|
||||||
|
'files situated in the \'benchmark\' directory.')
|
||||||
|
parser.add_argument('file', type=str, help="File to test",
|
||||||
|
nargs="*")
|
||||||
|
|
||||||
|
instrument.load_benchmark(save_instrumented=False, files=parser.parse_args().file)
|
||||||
init_deap()
|
init_deap()
|
||||||
|
|
||||||
for instr_f in tqdm.tqdm(sorted(instrument.functions.keys()), desc="Generating tests"):
|
for instr_f in tqdm.tqdm(sorted(instrument.functions.keys()), desc="Generating tests"):
|
||||||
|
|
|
@ -1,28 +1,18 @@
|
||||||
from typing import Optional
|
import ast
|
||||||
import os.path
|
import os.path
|
||||||
|
import sys
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
import astunparse
|
||||||
import tqdm
|
import tqdm
|
||||||
from frozendict import frozendict
|
from frozendict import frozendict
|
||||||
|
from operators import evaluate_condition
|
||||||
|
|
||||||
import ast
|
|
||||||
import astunparse
|
|
||||||
import sys
|
|
||||||
import random
|
|
||||||
from operators import compute_distances
|
|
||||||
|
|
||||||
# hyperparameters
|
|
||||||
ROOT_DIR: str = os.path.dirname(__file__)
|
ROOT_DIR: str = os.path.dirname(__file__)
|
||||||
IN_DIR: str = os.path.join(ROOT_DIR, 'benchmark')
|
IN_DIR: str = os.path.join(ROOT_DIR, 'benchmark')
|
||||||
OUT_DIR: str = os.path.join(ROOT_DIR, 'instrumented')
|
OUT_DIR: str = os.path.join(ROOT_DIR, 'instrumented')
|
||||||
SUFFIX: str = "_instrumented"
|
SUFFIX: str = "_instrumented"
|
||||||
|
|
||||||
distances_true: dict[int, int] = {}
|
|
||||||
distances_false: dict[int, int] = {}
|
|
||||||
|
|
||||||
# Archive of solutions
|
|
||||||
archive_true_branches: dict[int, any] = {}
|
|
||||||
archive_false_branches: dict[int, any] = {}
|
|
||||||
|
|
||||||
|
|
||||||
class BranchTransformer(ast.NodeTransformer):
|
class BranchTransformer(ast.NodeTransformer):
|
||||||
branches_range: dict[str, tuple[int, int]]
|
branches_range: dict[str, tuple[int, int]]
|
||||||
|
@ -78,7 +68,7 @@ class BranchTransformer(ast.NodeTransformer):
|
||||||
return self.generic_visit(ast_node)
|
return self.generic_visit(ast_node)
|
||||||
|
|
||||||
self.branch_num += 1
|
self.branch_num += 1
|
||||||
return ast.Call(func=ast.Name("evaluate_condition", ast.Load()),
|
return ast.Call(func=ast.Name(evaluate_condition.__name__, ast.Load()),
|
||||||
args=[ast.Num(self.branch_num),
|
args=[ast.Num(self.branch_num),
|
||||||
ast.Str(ast_node.ops[0].__class__.__name__),
|
ast.Str(ast_node.ops[0].__class__.__name__),
|
||||||
ast_node.left,
|
ast_node.left,
|
||||||
|
@ -88,41 +78,6 @@ class BranchTransformer(ast.NodeTransformer):
|
||||||
kwargs=None)
|
kwargs=None)
|
||||||
|
|
||||||
|
|
||||||
def update_maps(condition_num, d_true, d_false):
|
|
||||||
global distances_true, distances_false
|
|
||||||
|
|
||||||
if condition_num in distances_true.keys():
|
|
||||||
distances_true[condition_num] = min(distances_true[condition_num], d_true)
|
|
||||||
else:
|
|
||||||
distances_true[condition_num] = d_true
|
|
||||||
|
|
||||||
if condition_num in distances_false.keys():
|
|
||||||
distances_false[condition_num] = min(distances_false[condition_num], d_false)
|
|
||||||
else:
|
|
||||||
distances_false[condition_num] = d_false
|
|
||||||
|
|
||||||
|
|
||||||
def evaluate_condition(num, op, lhs, rhs): # type: ignore
|
|
||||||
if op == "In":
|
|
||||||
if isinstance(lhs, str):
|
|
||||||
lhs = ord(lhs)
|
|
||||||
|
|
||||||
minimum = sys.maxsize
|
|
||||||
for elem in rhs.keys():
|
|
||||||
distance = abs(lhs - ord(elem))
|
|
||||||
if distance < minimum:
|
|
||||||
minimum = distance
|
|
||||||
|
|
||||||
distance_true, distance_false = minimum, 1 if minimum == 0 else 0
|
|
||||||
else:
|
|
||||||
distance_true, distance_false = compute_distances(op, lhs, rhs)
|
|
||||||
|
|
||||||
update_maps(num, distance_true, distance_false)
|
|
||||||
|
|
||||||
# distance == 0 equivalent to actual test by construction
|
|
||||||
return distance_true == 0
|
|
||||||
|
|
||||||
|
|
||||||
ArgType = str
|
ArgType = str
|
||||||
Arg = tuple[str, ArgType]
|
Arg = tuple[str, ArgType]
|
||||||
Params = frozendict[str, any]
|
Params = frozendict[str, any]
|
||||||
|
@ -203,9 +158,14 @@ def find_py_files(search_dir: str):
|
||||||
yield os.path.join(cwd, file)
|
yield os.path.join(cwd, file)
|
||||||
|
|
||||||
|
|
||||||
def load_benchmark(save_instrumented=True):
|
def load_benchmark(save_instrumented=True, files: list[str] = ()):
|
||||||
|
to_load = set([os.path.splitext(os.path.basename(file))[0] + ".py" for file in files])
|
||||||
|
do_all = len(to_load) == 0
|
||||||
|
|
||||||
for file in tqdm.tqdm(find_py_files(IN_DIR), desc="Instrumenting"):
|
for file in tqdm.tqdm(find_py_files(IN_DIR), desc="Instrumenting"):
|
||||||
instrument(file, os.path.join(OUT_DIR, os.path.basename(file)), save_instrumented=save_instrumented)
|
filename = os.path.basename(file)
|
||||||
|
if do_all or filename in to_load:
|
||||||
|
instrument(file, os.path.join(OUT_DIR, filename), save_instrumented=save_instrumented)
|
||||||
|
|
||||||
|
|
||||||
def call_statement(f_name: str, f_args: Params) -> str:
|
def call_statement(f_name: str, f_args: Params) -> str:
|
||||||
|
|
49
operators.py
49
operators.py
|
@ -1,9 +1,13 @@
|
||||||
|
import sys
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import TypeVar, Callable
|
|
||||||
from typing import Generic
|
from typing import Generic
|
||||||
|
from typing import TypeVar, Callable
|
||||||
|
|
||||||
from nltk import edit_distance
|
from nltk import edit_distance
|
||||||
|
|
||||||
|
distances_true: dict[int, int] = {}
|
||||||
|
distances_false: dict[int, int] = {}
|
||||||
|
|
||||||
T = TypeVar('T')
|
T = TypeVar('T')
|
||||||
U = TypeVar('U')
|
U = TypeVar('U')
|
||||||
|
|
||||||
|
@ -100,7 +104,7 @@ def str_check(a: any, b: any) -> bool:
|
||||||
return type(a) == str and type(b) == str
|
return type(a) == str and type(b) == str
|
||||||
|
|
||||||
|
|
||||||
def compute_distances(name: str, lhs: any, rhs: any) -> tuple[int, int]:
|
def compute_distances(name: str, lhs: any, rhs: any) -> tuple[int, int, bool]:
|
||||||
if int_str_check(lhs, rhs):
|
if int_str_check(lhs, rhs):
|
||||||
lhs_int = int_str_convert(lhs)
|
lhs_int = int_str_convert(lhs)
|
||||||
rhs_int = int_str_convert(rhs)
|
rhs_int = int_str_convert(rhs)
|
||||||
|
@ -109,13 +113,50 @@ def compute_distances(name: str, lhs: any, rhs: any) -> tuple[int, int]:
|
||||||
raise ValueError(f"'{name}' is not a valid CmpOp name for 'int_str' operators")
|
raise ValueError(f"'{name}' is not a valid CmpOp name for 'int_str' operators")
|
||||||
|
|
||||||
op = int_str_by_name[name]
|
op = int_str_by_name[name]
|
||||||
return op.true_dist(lhs_int, rhs_int), op.false_dist(lhs_int, rhs_int)
|
return op.true_dist(lhs_int, rhs_int), op.false_dist(lhs_int, rhs_int), op.test(lhs_int, rhs_int)
|
||||||
|
|
||||||
if str_check(lhs, rhs):
|
if str_check(lhs, rhs):
|
||||||
if name not in str_by_name:
|
if name not in str_by_name:
|
||||||
raise ValueError(f"'{name}' is not a valid CmpOp name for 'str' operators")
|
raise ValueError(f"'{name}' is not a valid CmpOp name for 'str' operators")
|
||||||
|
|
||||||
op = str_by_name[name]
|
op = str_by_name[name]
|
||||||
return op.true_dist(lhs, rhs), op.false_dist(lhs, rhs)
|
return op.true_dist(lhs, rhs), op.false_dist(lhs, rhs), op.test(lhs, rhs)
|
||||||
|
|
||||||
raise ValueError(f"'{lhs}' and '{rhs}' are not suitable for both 'int_str' and 'str' operators")
|
raise ValueError(f"'{lhs}' and '{rhs}' are not suitable for both 'int_str' and 'str' operators")
|
||||||
|
|
||||||
|
|
||||||
|
def update_map(the_map: dict[int, int], condition_num: int, distance: int):
|
||||||
|
if condition_num in the_map.keys():
|
||||||
|
the_map[condition_num] = min(the_map[condition_num], distance)
|
||||||
|
else:
|
||||||
|
the_map[condition_num] = distance
|
||||||
|
|
||||||
|
|
||||||
|
def update_maps(condition_num, d_true, d_false):
|
||||||
|
global distances_true, distances_false
|
||||||
|
update_map(distances_true, condition_num, d_true)
|
||||||
|
update_map(distances_false, condition_num, d_false)
|
||||||
|
|
||||||
|
|
||||||
|
def in_op(num, lhs, rhs):
|
||||||
|
if isinstance(lhs, str):
|
||||||
|
lhs = ord(lhs)
|
||||||
|
|
||||||
|
minimum = sys.maxsize
|
||||||
|
for elem in rhs.keys():
|
||||||
|
distance = abs(lhs - ord(elem))
|
||||||
|
if distance < minimum:
|
||||||
|
minimum = distance
|
||||||
|
|
||||||
|
distance_true, distance_false = minimum, 1 if minimum == 0 else 0
|
||||||
|
update_maps(num, distance_true, distance_false)
|
||||||
|
return distance_true == 0 # distance == 0 equivalent to actual test by construction
|
||||||
|
|
||||||
|
|
||||||
|
def evaluate_condition(num, op, lhs, rhs):
|
||||||
|
if op == "In":
|
||||||
|
return in_op(num, lhs, rhs)
|
||||||
|
|
||||||
|
distance_true, distance_false, test = compute_distances(op, lhs, rhs)
|
||||||
|
update_maps(num, distance_true, distance_false)
|
||||||
|
return test
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
/usr/local/bin/python3.10 /Volumes/Data/git/kse/project-02-python-test-generator-maggicl/genetic.py
|
|
||||||
Instrumenting: 10it [00:00, 722.61it/s]
|
|
||||||
Generating tests: 0%| | 0/12 [00:00<?, ?it/s]
|
|
||||||
anagram_check: rep #00: Cov: 87.50% (7/8 branches): 1F 1T 2F 2T 3F 3T 4F
|
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 #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 #02: Cov: 100.00% (8/8 branches): 1F 1T 2F 2T 3F 3T 4F 4T
|
||||||
|
@ -11,8 +8,6 @@ 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 #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 #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
|
anagram_check: rep #09: Cov: 100.00% (8/8 branches): 1F 1T 2F 2T 3F 3T 4F 4T
|
||||||
[87.5, 87.5, 100.0, 87.5, 87.5, 87.5, 100.0, 100.0, 87.5, 100.0]
|
|
||||||
Generating tests: 8%|▊ | 1/12 [01:05<12:02, 65.64s/it]
|
|
||||||
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 #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 #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 #02: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
|
||||||
|
@ -23,8 +18,6 @@ cd_count: rep #06: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
|
||||||
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 #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 #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
|
cd_count: rep #09: Cov: 100.00% (14/14 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T 6F 6T 7F 7T
|
||||||
[100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]
|
|
||||||
Generating tests: 17%|█▋ | 2/12 [02:30<12:50, 77.04s/it]
|
|
||||||
check_armstrong: rep #00: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
|
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 #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 #02: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
|
||||||
|
@ -35,8 +28,6 @@ check_armstrong: rep #06: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T
|
||||||
check_armstrong: rep #07: 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 #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
|
check_armstrong: rep #09: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
|
||||||
[100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]
|
|
||||||
Generating tests: 25%|██▌ | 3/12 [03:36<10:45, 71.73s/it]
|
|
||||||
decrypt: rep #00: Cov: 100.00% (2/2 branches): 2F 2T
|
decrypt: rep #00: Cov: 100.00% (2/2 branches): 2F 2T
|
||||||
decrypt: rep #01: 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 #02: Cov: 100.00% (2/2 branches): 2F 2T
|
||||||
|
@ -47,8 +38,6 @@ decrypt: rep #06: Cov: 100.00% (2/2 branches): 2F 2T
|
||||||
decrypt: rep #07: 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 #08: Cov: 100.00% (2/2 branches): 2F 2T
|
||||||
decrypt: rep #09: Cov: 100.00% (2/2 branches): 2F 2T
|
decrypt: rep #09: Cov: 100.00% (2/2 branches): 2F 2T
|
||||||
[100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]
|
|
||||||
Generating tests: 33%|███▎ | 4/12 [04:49<09:40, 72.50s/it]
|
|
||||||
encrypt: rep #00: Cov: 100.00% (2/2 branches): 1F 1T
|
encrypt: rep #00: Cov: 100.00% (2/2 branches): 1F 1T
|
||||||
encrypt: rep #01: 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 #02: Cov: 100.00% (2/2 branches): 1F 1T
|
||||||
|
@ -59,8 +48,6 @@ encrypt: rep #06: Cov: 100.00% (2/2 branches): 1F 1T
|
||||||
encrypt: rep #07: 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 #08: Cov: 100.00% (2/2 branches): 1F 1T
|
||||||
encrypt: rep #09: Cov: 100.00% (2/2 branches): 1F 1T
|
encrypt: rep #09: Cov: 100.00% (2/2 branches): 1F 1T
|
||||||
[100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]
|
|
||||||
Generating tests: 42%|████▏ | 5/12 [06:04<08:31, 73.13s/it]
|
|
||||||
exponentiation: rep #00: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
|
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 #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 #02: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
|
||||||
|
@ -70,9 +57,6 @@ 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 #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 #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
|
exponentiation: rep #08: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
|
||||||
Generating tests: 50%|█████ | 6/12 [07:50<08:26, 84.43s/it]
|
|
||||||
exponentiation: rep #09: Cov: 62.50% (5/8 branches): 1F 1T 2F 2T 3T
|
|
||||||
[62.5, 62.5, 62.5, 62.5, 62.5, 62.5, 62.5, 62.5, 62.5, 62.5]
|
|
||||||
gcd: rep #00: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
|
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 #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 #02: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
|
||||||
|
@ -83,8 +67,6 @@ 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 #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 #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
|
gcd: rep #09: Cov: 100.00% (10/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F 5T
|
||||||
[100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]
|
|
||||||
Generating tests: 58%|█████▊ | 7/12 [09:09<06:52, 82.57s/it]
|
|
||||||
longest_sorted_substr: rep #00: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
|
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 #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 #02: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
|
||||||
|
@ -94,9 +76,7 @@ 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 #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 #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 #08: Cov: 100.00% (4/4 branches): 1F 1T 2F 2T
|
||||||
Generating tests: 67%|██████▋ | 8/12 [10:19<05:15, 78.78s/it]
|
|
||||||
longest_sorted_substr: rep #09: 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
|
||||||
[100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]
|
|
||||||
rabin_karp_search: rep #00: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
|
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 #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 #02: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
|
||||||
|
@ -107,8 +87,6 @@ rabin_karp_search: rep #06: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T
|
||||||
rabin_karp_search: rep #07: 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 #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
|
rabin_karp_search: rep #09: Cov: 90.00% (9/10 branches): 1F 1T 2F 2T 3F 3T 4F 4T 5F
|
||||||
[90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0, 90.0]
|
|
||||||
Generating tests: 75%|███████▌ | 9/12 [11:32<03:50, 76.96s/it]
|
|
||||||
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 #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 #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 #02: Cov: 93.75% (15/16 branches): 5F 5T 6F 6T 7F 7T 8F 8T 9T 10F 10T 11F 11T 12F 12T
|
||||||
|
@ -119,9 +97,17 @@ raildecrypt: rep #06: Cov: 93.75% (15/16 branches): 5F 5T 6F 6T 7F 7T 8F 8T 9T 1
|
||||||
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 #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 #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
|
raildecrypt: rep #09: Cov: 68.75% (11/16 branches): 5T 6F 6T 8F 8T 9T 10F 10T 11F 11T 12T
|
||||||
[87.5, 93.75, 93.75, 87.5, 87.5, 87.5, 93.75, 93.75, 93.75, 68.75]
|
|
||||||
Generating tests: 83%|████████▎ | 10/12 [17:25<05:24, 162.00s/it]
|
|
||||||
railencrypt: rep #00: Cov: 100.00% (8/8 branches): 1F 1T 2F 2T 3F 3T 4F 4T
|
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 #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 #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
|
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
|
||||||
|
|
14
tests/test_railencrypt.py
Normal file
14
tests/test_railencrypt.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from benchmark.railfence_cipher import railencrypt
|
||||||
|
|
||||||
|
|
||||||
|
class Test_railencrypt(TestCase):
|
||||||
|
def test_railencrypt_1(self):
|
||||||
|
assert railencrypt(st=')x8ro;BVm', k=865) == ')x8ro;BVm'
|
||||||
|
|
||||||
|
def test_railencrypt_2(self):
|
||||||
|
assert railencrypt(st='q338K a{.', k=4) == 'qa3 {3K.8'
|
||||||
|
|
||||||
|
def test_railencrypt_3(self):
|
||||||
|
assert railencrypt(st='X61*8p', k=5) == 'X61*p8'
|
23
tests/test_zeller.py
Normal file
23
tests/test_zeller.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from benchmark.zellers_birthday import zeller
|
||||||
|
|
||||||
|
|
||||||
|
class Test_zeller(TestCase):
|
||||||
|
def test_zeller_1(self):
|
||||||
|
assert zeller(d=-134, m=797, y=67) == 'Sunday'
|
||||||
|
|
||||||
|
def test_zeller_2(self):
|
||||||
|
assert zeller(d=-156, m=10, y=-57) == 'Wednesday'
|
||||||
|
|
||||||
|
def test_zeller_3(self):
|
||||||
|
assert zeller(d=715, m=444, y=74) == 'Thursday'
|
||||||
|
|
||||||
|
def test_zeller_4(self):
|
||||||
|
assert zeller(d=-726, m=864, y=-16) == 'Thursday'
|
||||||
|
|
||||||
|
def test_zeller_5(self):
|
||||||
|
assert zeller(d=31, m=910, y=2) == 'Sunday'
|
||||||
|
|
||||||
|
def test_zeller_6(self):
|
||||||
|
assert zeller(d=369, m=-917, y=-1000) == 'Sunday'
|
Reference in a new issue