File indexing completed on 2024-04-21 05:42:43

0001 #!/usr/bin/env python
0002 
0003 # SPDX-FileCopyrightText: 2002-2007 Joachim Eibl, joachim.eibl at gmx.de
0004 # SPDX-License-Identifier: GPL-2.0-or-later
0005 
0006 import argparse
0007 import os
0008 import random
0009 import sys
0010 
0011 dirname = 'testdata/permutations'
0012 
0013 defaultlines = ['aaa\n',
0014                 'bbb\n',
0015                 'ccc\n',
0016                 'ddd\n',
0017                 'eee\n']
0018 
0019 # For the lines of the A file only consider removing them because modifying
0020 # them ("diff") would be equivalent to modifying both B and C, so that will
0021 # be covered anyway.
0022 options = [ ('1','1','1'),
0023             ('1','1','2'),
0024             ('1','1',None),
0025             ('1','2','1'),
0026             ('1','2','2'),
0027             ('1','2','3'),
0028             ('1','2',None),
0029             (None,'1','1'),
0030             (None,'1','2'),
0031             (None,'1',None),
0032             (None,None,'1') ]
0033 
0034 def permutations(nr_of_options, count, currentlist):
0035 
0036     if count == 0:
0037         filename = ''.join([format(i, '1x') for i in currentlist])
0038 
0039         baselines = []
0040         contrib1lines = []
0041         contrib2lines = []
0042         for optionindex, defaultline in zip(currentlist, defaultlines):
0043             option = options[optionindex]
0044 
0045             if option[0]:
0046                 baselines.append(defaultline)
0047 
0048             if option[1] == '1':
0049                 contrib1lines.append(defaultline)
0050             elif option[1] == '2':
0051                 contrib1lines.append('xxx' + defaultline)
0052 
0053             if option[2] == '1':
0054                 contrib2lines.append(defaultline)
0055             elif option[2] == '2':
0056                 contrib2lines.append('xxx' + defaultline)
0057             elif option[2] == '3':
0058                 contrib2lines.append('yyy' + defaultline)
0059 
0060         with open(f'{dirname}/perm_{filename}_base.txt', 'wb') as f:
0061             f.writelines(baselines)
0062 
0063         with open(f'{dirname}/perm_{filename}_contrib1.txt', 'wb') as f:
0064             f.writelines(contrib1lines)
0065 
0066         with open(f'{dirname}/perm_{filename}_contrib2.txt', 'wb') as f:
0067             f.writelines(contrib2lines)
0068 
0069         with open(f'{dirname}/perm_{filename}_expected_result.txt', 'a') as f:
0070             pass
0071 
0072     else:
0073         optionindices = random.sample(range(len(options)), nr_of_options)
0074         for optionindex in optionindices:
0075             permutations(nr_of_options, count - 1, [optionindex] + currentlist)
0076 
0077 
0078 parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
0079                                  description='Generate input files for alignmenttest in ./testdata/permutations/ containing some or all permutations of 3 sets of 5 lines.\n\n' +
0080                                              'Everything is based on a default set of 5 different lines: aaa, bbb, ccc, ddd and eee.\n' +
0081                                              'For the base file each line will be either equal to the default set or removed.\n' +
0082                                              "For contributor 1 each line will either be equal to the default set, different than the default set('xxx' prepended) or removed.\n" +
0083                                              "For contributor 2 each line will either be equal to the default set, equal to contributor 1, different('yyy' prepended) or removed.\n" +
0084                                              f"This results in {len(options) ** len(defaultlines)} possible permutations. The -r option can be used to make a smaller 'random' selection (the same seed is used each time).")
0085 
0086 parser.add_argument('-r', metavar='num', nargs='?', type=int, default=len(options), const=len(options),
0087                     help=f'instead of generating all {len(options)} permutations for each line, generate <num> randomly chosen ones. The number of test cases will become num^5.')
0088 parser.add_argument('-s', metavar='num', nargs='?', type=int, default=0, const=0,
0089                     help='specify the seed to use for the random number generator (default=0). This only makes sense when the -r option is specified.')
0090 args = parser.parse_args()
0091 
0092 if not os.path.exists(dirname):
0093     os.makedirs(dirname)
0094 
0095 print(f'Generating input files in {dirname} ...')
0096 sys.stdout.flush()
0097 
0098 random.seed(args.s)
0099 permutations(args.r, len(defaultlines), [])
0100 
0101 print('Input files generated.')
0102 print('')
0103 print(f'To create a reference set of expected_result.txt files, run alignmenttest and copy/move all {dirname}/*_actual_result.txt files to {dirname}/*_expected_result.txt:')
0104 print('  ./alignmenttest > /dev/null')
0105 print(f'  cd {dirname}')
0106 print('  for file in *_actual_result.txt; do mv ${file} ${file/actual/expected}; done')
0107 print("If you've already modified the algorithm, you can run the alignment test of an older version of kdiff3 and copy those result files over")