• R/O
  • SSH

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Castle: The best Real-Time/Embedded/HighTech language EVER. Attempt 2


Commit MetaInfo

Revision30b384e24ddf6da239bc88563416bb1abb73f2ca (tree)
Zeit2022-05-31 03:44:08
AutorAlbert Mietus < albert AT mietus DOT nl >
CommiterAlbert Mietus < albert AT mietus DOT nl >

Log Message

Added 'make mutmut' Mutation testing -- and fix/whitelisted some trivials

Ändern Zusammenfassung

Diff

diff -r 6ccd9a748252 -r 30b384e24ddf Makefile
--- a/Makefile Mon May 30 20:43:09 2022 +0200
+++ b/Makefile Mon May 30 20:44:08 2022 +0200
@@ -9,10 +9,17 @@
99 coverage run --branch -m pytest ${PYTEST_OPTONS} pytst/
1010 coverage report --skip-covered
1111 coverage html
12+pytest-only:
13+ pytest ${PYTEST_OPTONS} pytst
1214 pytest-s test-s:
1315 pytest ${PYTEST_OPTONS} -s pytst
1416 test-ds test-sd test-d:
1517 pytest ${PYTEST_OPTONS} --log-cli-level=DEBUG -s pytst/
18+mutmut:
19+ -mutmut run --tests-dir pytst --paths-to-mutate castle
20+ mutmut html && mutmut results
21+ open html/index.html
22+
1623
1724 demo: pytest-demo python-demo
1825
@@ -45,7 +52,12 @@
4552 clean_caches:
4653 find . -type d -name __pycache__ -print0 | xargs -0 rm -r
4754 find . -type d -name .pytest_cache -print0 | xargs -0 rm -r
55+ rm -f ./.coverage
56+ rm -f ./.mutmut-cache
4857
58+cleaner: clean
59+ rm -rd ./htmlcov/ #coverage
60+ rm -rf ./html # mutmut
4961
5062 PYREVERSE_DIR=pyreversed
5163 PYREVERSE_FORMAT=svg
diff -r 6ccd9a748252 -r 30b384e24ddf castle/ast/_base.py
--- a/castle/ast/_base.py Mon May 30 20:43:09 2022 +0200
+++ b/castle/ast/_base.py Mon May 30 20:44:08 2022 +0200
@@ -6,12 +6,12 @@
66 """Base class for all Castle ATS nodes"""
77
88 def __init__(self, *, parse_tree=None, **kwargs):
9- assert len(kwargs)==0, "Do not call 'Object' with kwargs (caller is wrong)"
9+ assert len(kwargs)==0, "Do not call 'Object' with kwargs (caller is wrong)" # pragma: no mutate
1010 super().__init__(**kwargs)
1111 self._parse_tree = parse_tree
1212
1313 def __str__(self): # mostly for debugging
14- return '\n__DEBUG__ ' + str(type(self).__name__) + "\n\t" + "\n\t".join(f'{n}\t{str(v)}:{type(v).__name__}' for n,v in self.__dict__.items() if n[0]!='_')
14+ return '\n__DEBUG__ ' + str(type(self).__name__) + "\n\t" + "\n\t".join(f'{n}\t{str(v)}:{type(v).__name__}' for n,v in self.__dict__.items() if n[0]!='_') # pragma: no mutate
1515
1616 def serialize(self, strategy="XML") -> str:
1717 return Serialize(strategy).serialize(self)
@@ -24,15 +24,15 @@
2424 ### Mostly for debugging
2525 @staticmethod
2626 def _typeName(of):
27- return type(of).__name__
27+ return type(of).__name__ # pragma: no mutate
2828
2929 def _valType(self, of:None):
30- if not of: of=self
31- return f'{of}:{self._typeName(of)}'
30+ if not of: of=self # pragma: no mutate
31+ return f'{of}:{self._typeName(of)}' # pragma: no mutate
3232
3333
3434 class IDError(ValueError):
35- "The given ID is not valid as an ID"
35+ "The given ID is not valid as an ID" # pragma: no mutate
3636
3737
3838
diff -r 6ccd9a748252 -r 30b384e24ddf castle/ast/grammar.py
--- a/castle/ast/grammar.py Mon May 30 20:43:09 2022 +0200
+++ b/castle/ast/grammar.py Mon May 30 20:44:08 2022 +0200
@@ -1,4 +1,4 @@
1-import logging; logger = logging.getLogger(__name__)
1+import logging; logger = logging.getLogger(__name__) # pragma: no mutate
22
33 from ._base import AST_BASE, ID, IDError
44
@@ -14,14 +14,14 @@
1414 """With this MixIn PEG-classes get the ``.value`` property"""
1515
1616 def __init__(self, *, value=None, **kwargs):
17- logger.debug(f'{self._typeName(self)}.MixIn_value_attribute:: value:=' +
18- ('[[' +', '.join(f'{v}:{type(v).__name__}' for v in value) + ']]') if isinstance(value, list) else f's>>{value}<<')
17+ logger.debug(f'{self._typeName(self)}.MixIn_value_attribute:: value:=' + # pragma: no mutate
18+ ('[[' +', '.join(f'{v}:{type(v).__name__}' for v in value) + ']]') if isinstance(value, list) else f's>>{value}<<') # pragma: no mutate
1919 super().__init__(**kwargs)
2020 self._value=value
2121
2222 @property
2323 def value(self):
24- logger.debug(f'{self._typeName(self)}:: @value={self._value}')
24+ logger.debug(f'{self._typeName(self)}:: @value={self._value}') # pragma: no mutate
2525 return self._value
2626
2727
@@ -29,13 +29,13 @@
2929 """With this MixIn PEG-classes get the ``.expr`` property"""
3030
3131 def __init__(self, *, expr=None, **kwargs):
32- logger.debug(f'{self._typeName(self)}.MixIn_expr_attribute:: expr:={self._valType(expr)}')
32+ logger.debug(f'{self._typeName(self)}.MixIn_expr_attribute:: expr:={self._valType(expr)}') # pragma: no mutate
3333 super().__init__(**kwargs)
3434 self._expr = expr
3535
3636 @property
3737 def expr(self):
38- logger.debug(f'{self._typeName(self)}:: @expr={self._expr}')
38+ logger.debug(f'{self._typeName(self)}:: @expr={self._expr}') # pragma: no mutate
3939 return self._expr
4040
4141
@@ -43,7 +43,7 @@
4343 """With this MixIn PEG-class get the ``.children`` property; and sequence-alike methods"""
4444 def __init__(self, *, children, **kwargs):
4545 logger.debug(f'{self._typeName(self)}.MixIn_children_tuple:: children[{len(children)}]:=' +
46- ('[[' +', '.join(f'{c}:{type(c).__name__}' for c in children) + ']]') if isinstance(children, list) else f's>>{children}<<')
46+ ('[[' +', '.join(f'{c}:{type(c).__name__}' for c in children) + ']]') if isinstance(children, list) else f's>>{children}<<') # pragma: no mutate
4747 super().__init__(**kwargs)
4848 self._children = tuple(children)
4949
@@ -53,7 +53,7 @@
5353 return self._children[key]
5454 def __iter__(self): return self._children.__iter__()
5555 def __str__(self):
56- return f"<{type(self).__name__}.MixIn_children_tuple:{len(self)}[" + ",".join(str(c) for c in self) + "]>"
56+ return f"<{type(self).__name__}.MixIn_children_tuple:{len(self)}[" + ",".join(str(c) for c in self) + "]>" # pragma: no mutate
5757
5858 ##
5959 ## Note: When using TypeHints with PEG-classes; the clases
@@ -66,7 +66,7 @@
6666 class RegExpTerm(Terminal): pass
6767 class Number(Terminal): # Value is stored as a string
6868 def __str__(self): # mostly for debugging
69- return f'<"{self.value}">'
69+ return f'<"{self.value}">' # pragma: no mutate
7070
7171 class Markers(PEG): pass # abstract
7272 class EOF(Markers): pass # XXX Todo ## singleton?
@@ -90,9 +90,9 @@
9090 def __init__(self, *,
9191 name: ID, expr:Expression=None,
9292 **kwargs):
93- logger.debug(f'{self._typeName(self)}: name={self._valType(name)}, expr={self._valType(expr)}')
93+ logger.debug(f'{self._typeName(self)}: name={self._valType(name)}, expr={self._valType(expr)}') # pragma: no mutate
9494 if expr:
95- logger.debug("\t" + "; ".join(f'{c}:{type(c)}' for c in expr))
95+ logger.debug("\t" + "; ".join(f'{c}:{type(c)}' for c in expr)) # pragma: no mutate
9696 if not isinstance(name, ID): raise TypeError(f'Rule-name {name} is not of type ID')
9797 super().__init__(**kwargs)
9898 self.name = name
@@ -132,14 +132,14 @@
132132 # __init__ (see MixIn) sets self._children; assuming it is a list
133133
134134 def __str__(self): # mostly for debugging
135- return "Seq{{" + " ; ".join(f"{c}" for c in self) + "}}"
135+ return "Seq{{" + " ; ".join(f"{c}" for c in self) + "}}" # pragma: no mutate
136136
137137
138138 class OrderedChoice(MixIn_children_tuple, Expression): # A | B | C | ... the order is relevant
139139 """OC: A _tuple_ of alternative expressions"""
140140
141141 def __str__(self): # mostly for debugging
142- return "OC{{" + " | ".join(f"{c}" for c in self._children) + "}}"
142+ return "OC{{" + " | ".join(f"{c}" for c in self._children) + "}}" # pragma: no mutate
143143
144144 class Optional(Quantity):pass
145145 class ZeroOrMore(Quantity):pass
diff -r 6ccd9a748252 -r 30b384e24ddf castle/readers/parser/__init__.py
--- a/castle/readers/parser/__init__.py Mon May 30 20:43:09 2022 +0200
+++ b/castle/readers/parser/__init__.py Mon May 30 20:44:08 2022 +0200
@@ -37,7 +37,7 @@
3737 **kwargs):
3838 super().__init__(read_dirs=read_dirs, **kwargs)
3939 if language_def is None:
40- raise ValueError("The `language_def` is a mandatory parameter")
40+ raise ValueError("The `language_def` is a mandatory parameter") # pragma: no mutate
4141 # comment_def is allowed to be None
4242 if visitor is None:
4343 raise ValueError("visitor is a mandatory parameter")
diff -r 6ccd9a748252 -r 30b384e24ddf castle/readers/parser/grammar/visitor.py
--- a/castle/readers/parser/grammar/visitor.py Mon May 30 20:43:09 2022 +0200
+++ b/castle/readers/parser/grammar/visitor.py Mon May 30 20:44:08 2022 +0200
@@ -29,7 +29,7 @@
2929
3030 class PegVisitor(arpeggio.PTNodeVisitor):
3131 def _logstr_node_children(self, node, children):
32- return f'>>{node}<< children[{len(children)}] >>' + ", ".join(f'{c}:{type(c).__name__}' for c in children) + '<<'
32+ return f'>>{node}<< children[{len(children)}] >>' + ", ".join(f'{c}:{type(c).__name__}' for c in children) + '<<' # pragma: no mutate
3333
3434 def visit_str_term(self, node, children):
3535 return grammar.StrTerm(value=node[1], parse_tree=node)
@@ -54,27 +54,27 @@
5454 '#': grammar.UnorderedGroup}
5555
5656 if len(children) == 1: # No Optional part
57- logger.debug(f'visit_single_expr==1:: {getattr(children[0], "name", children[0])}:{type(children[0])}')
57+ logger.debug(f'visit_single_expr==1:: {getattr(children[0], "name", children[0])}:{type(children[0])}') # pragma: no mutate
5858 return children[0]
5959
6060 elif len(children) == 2: # Optional part
61- logger.debug(f'visit_single_expr==2::Got: {children[0]}, {children[1]}')
61+ logger.debug(f'visit_single_expr==2::Got: {children[0]}, {children[1]}') # pragma: no mutate
6262 expr = children[0]
6363 token = str(children[1])
6464 quantum_cls = token_2_class.get(token)
6565 if quantum_cls:
6666 ast=quantum_cls(expr=expr, parse_tree=node)
67- logger.debug(f'visit_single_expr==2::Pass: {quantum_cls}(expr={expr})')
67+ logger.debug(f'visit_single_expr==2::Pass: {quantum_cls}(expr={expr})') # pragma: no mutate
6868 return ast
6969 else:
7070 raise QuantityError(f"token '{token}' not recognised")
71- else: # #children not in (1,2)
72- raise NotImplementedError("visit_single_expr, len>2") # -- Is this possible?
71+ else: # #children not in (1,2) -- Is this possible?
72+ raise NotImplementedError("visit_single_expr, len>2") # pragma: no mutate
7373
7474
7575 # expression <- sequence, op_alternative; op_alternative <- ('|' expression)?
7676 def visit_expression(self, node, children) -> Union[grammar.Sequence, grammar.OrderedChoice]:
77- logger.debug('visit_expression::' + self._logstr_node_children(node, children))
77+ logger.debug('visit_expression::' + self._logstr_node_children(node, children)) # pragma: no mutate
7878 if len(children) == 1: #Only sequence
7979 return children[0]
8080 elif len(children) == 2: # So, having 1 or more alternatives in children[1]
@@ -90,14 +90,14 @@
9090
9191 # OneOrMore(single_expr)
9292 def visit_sequence(self, node, children) -> grammar.Sequence:
93- logger.debug(f'visit_sequence::{self._logstr_node_children(node, children)}')
93+ logger.debug(f'visit_sequence::{self._logstr_node_children(node, children)}') # pragma: no mutate
9494 return grammar.Sequence(children=children, parse_tree=node)
9595
9696
9797 def visit_predicate(self, node, children):
9898 token_2_predicate = {'&': grammar.AndPredicate,
9999 '!': grammar.NotPredicate}
100- logger.debug(f'visit_predicate:: >>{node}<< #children={len(children)}')
100+ logger.debug(f'visit_predicate:: >>{node}<< #children={len(children)}') # pragma: no mutate
101101
102102 if len(children) == 2:
103103 token = children[0]
@@ -107,12 +107,12 @@
107107 return ast
108108 else:
109109 raise PredicateError(f"token '{token}' not recognised")
110- else:
111- raise NotImplementedError("visit_predicate, len!=2") # -- Is this possible?
110+ else: # -- Is this possible?
111+ raise NotImplementedError("visit_predicate, len!=2") # pragma: no mutate
112112
113113
114114 def visit_rules(self, node, children): # Mix of `ParseRule`(s)`Setting`(s) ; will be sorted out n `Grammar`
115- logger.debug('visit_rules::' + self._logstr_node_children(node, children))
115+ logger.debug('visit_rules::' + self._logstr_node_children(node, children)) # pragma: no mutate
116116 return grammar.Rules(children=children[:], parse_tree=node)
117117
118118
@@ -129,5 +129,5 @@
129129 return grammar.ID(name=str(node), parse_tree=node)
130130
131131 def visit_setting(self, node, children):
132- logger.debug('visit_setting::' + self._logstr_node_children(node, children))
132+ logger.debug('visit_setting::' + self._logstr_node_children(node, children)) # pragma: no mutate
133133 return grammar.Setting(name=children[0], value=children[1] , parse_tree=node)