mirror of
https://github.com/unclebob/crapper.git
synced 2026-11-06 18:13:50 +00:00
Add a multi-language CRAP tool that writes .metrics/crap.edn for uml-viewer.
Score Clojure, Java, Go, TypeScript, Rust, and Python with each language's complexity rules and coverage report.
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
from crapper.languages.python import functions_in_source
|
||||
|
||||
|
||||
def test_function_method_and_nested_function():
|
||||
source = """
|
||||
def choose(x, ready):
|
||||
if x > 0 and x < 10:
|
||||
return 1
|
||||
elif x == 0 or ready:
|
||||
return 0
|
||||
for i in xs:
|
||||
if i == 2:
|
||||
return i
|
||||
while ready:
|
||||
break
|
||||
try:
|
||||
return x
|
||||
except ValueError:
|
||||
return 0
|
||||
except KeyError:
|
||||
return -1
|
||||
match x:
|
||||
case 1:
|
||||
return 1
|
||||
case 2 | 3:
|
||||
return 2
|
||||
case _:
|
||||
return 0
|
||||
return x if x > 0 else 0
|
||||
|
||||
class Box:
|
||||
def open(self, flag=False):
|
||||
return 1 if flag else 0
|
||||
|
||||
@staticmethod
|
||||
def shut(self):
|
||||
xs = [n for n in range(3) if n]
|
||||
return xs
|
||||
|
||||
def outer():
|
||||
def inner(n):
|
||||
if n:
|
||||
return 1
|
||||
return 0
|
||||
return inner(1)
|
||||
|
||||
async def load():
|
||||
if True:
|
||||
return 1
|
||||
"""
|
||||
functions = functions_in_source(source, "src/demo/box.py", "/proj")
|
||||
assert [(fn.namespace, fn.name, fn.complexity) for fn in functions] == [
|
||||
("demo.box", "choose", 14),
|
||||
("demo.box.Box", "open", 2),
|
||||
("demo.box.Box", "shut", 2),
|
||||
("demo.box", "outer", 2),
|
||||
("demo.box", "load", 2),
|
||||
]
|
||||
|
||||
|
||||
def test_nested_class_method_is_its_own_entry():
|
||||
source = """
|
||||
class Outer:
|
||||
class Inner:
|
||||
def tick(self, ready, ok):
|
||||
if ready and ok:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def factory():
|
||||
class Hidden:
|
||||
def secret(self):
|
||||
if True:
|
||||
return 1
|
||||
return 0
|
||||
return Hidden()
|
||||
"""
|
||||
functions = functions_in_source(source, "src/demo/sample.py", "/proj")
|
||||
assert [(fn.namespace, fn.name, fn.complexity) for fn in functions] == [
|
||||
("demo.sample.Outer.Inner", "tick", 3),
|
||||
("demo.sample", "factory", 1),
|
||||
("demo.sample.Hidden", "secret", 2),
|
||||
]
|
||||
|
||||
|
||||
def test_namespace_strips_roots_src_and_init():
|
||||
source = "def f():\n return 1\n"
|
||||
assert functions_in_source(source, "/proj/src/demo/app.py", "/proj")[0].namespace == "demo.app"
|
||||
assert functions_in_source(source, "./src/demo/app.py", ".")[0].namespace == "demo.app"
|
||||
assert functions_in_source(source, "pkg/src/demo/__init__.py", None)[0].namespace == "demo"
|
||||
assert functions_in_source(source, "__init__.py", None)[0].namespace == "__init__"
|
||||
|
||||
|
||||
def test_strings_comments_and_package_init_do_not_add_decisions():
|
||||
source = '''
|
||||
def literal():
|
||||
"""if and or for while except"""
|
||||
text = "if x and y"
|
||||
# if x: return 1
|
||||
return text
|
||||
'''
|
||||
functions = functions_in_source(source, "src/demo/__init__.py", "/proj")
|
||||
assert [(fn.namespace, fn.name, fn.complexity) for fn in functions] == [
|
||||
("demo", "literal", 1)
|
||||
]
|
||||
Reference in New Issue
Block a user