1#!/usr/bin/env python3
 2
 3import os
 4import operator
 5
 6funcs = {}
 7for filename in os.listdir("."):
 8    if filename.endswith(".scad"):
 9        filepath = os.path.join(".",filename)
10        with open(filepath, "r") as f:
11            for linenum,line in enumerate(f.readlines()):
12                if line.startswith("function "):
13                    funcname = line[9:].strip().split("(")[0].strip()
14                    if funcname.startswith("_"):
15                        continue
16                    if funcname in funcs:
17                        print("WARNING!!! Function {} re-defined at {}:{}".format(funcname, filename, linenum+1));
18                        print("           Previously defined at {}:{}".format(*funcs[funcname]));
19                    else:
20                        funcs[funcname] = (filename, linenum+1)
21
22covered = {}
23uncovered = funcs.copy()
24for filename in os.listdir("tests"):
25    if filename.startswith("test_") and filename.endswith(".scad"):
26        filepath = os.path.join("tests",filename)
27        with open(filepath, "r") as f:
28            for linenum,line in enumerate(f.readlines()):
29                if line.startswith("module "):
30                    testmodule = line[7:].strip().split("(")[0].strip()
31                    if testmodule.startswith("test_"):
32                        funcname = testmodule.split("_",1)[1]
33                        if funcname in uncovered:
34                            if filename != "test_" + uncovered[funcname][0]:
35                                print("WARNING!!! Function {} defined at {}:{}".format(funcname, *uncovered[funcname]));
36                                print("           but tested at {}:{}".format(filename, linenum+1));
37                            covered[funcname] = (filename,linenum+1)
38                            del uncovered[funcname]
39
40uncovered_by_file = {}
41for funcname in sorted(list(uncovered.keys())):
42    filename = uncovered[funcname][0]
43    if filename not in uncovered_by_file:
44        uncovered_by_file[filename] = []
45    uncovered_by_file[filename].append(funcname)
46
47mostest = []
48for filename in uncovered_by_file.keys():
49    mostest.append( (len(uncovered_by_file[filename]), filename) )
50
51# for funcname in sorted(covered):
52#     print("COVERED: function {}".format(funcname))
53
54print("NOT COVERED:")
55for cnt, filename in sorted(mostest, key=operator.itemgetter(0)):
56    filefuncs = uncovered_by_file[filename]
57    print("  {}: {:d} uncovered functions".format(filename, cnt))
58    for funcname in filefuncs:
59        print("    {}".format(funcname))
60
61totfuncs = len(funcs.keys())
62covfuncs = len(covered)
63
64print(
65    "Total coverage: {} of {} functions ({:.2f}%)".format(
66        covfuncs, totfuncs, 100.0*covfuncs/totfuncs
67    )
68)
69
70# vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap