Skip to content

Commit 3771e61

Browse files
committed
adding test workflows
improve workflow
1 parent 5a7ddc5 commit 3771e61

File tree

4 files changed

+284
-0
lines changed

4 files changed

+284
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Pymathics-Graph (Consistency Checks)
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ['3.10']
15+
steps:
16+
- uses: actions/checkout@v3
17+
- name: Set up Python ${{ matrix.python-version }}
18+
uses: actions/setup-python@v2
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
python -m pip install pytest
25+
python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full]
26+
git clone https://github.com/Mathics3/mathics-core
27+
(cd mathics-core && make)
28+
(cd mathics-core && python -m pip install -e .[full])
29+
- name: Install Pymathics.graph with minimum dependencies
30+
run: |
31+
make develop
32+
- name: Test Mathics Consistency and Style
33+
run: |
34+
make check-consistency-and-style

.github/workflows/ubuntu.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Pymathics.graph (ubuntu)
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: '**'
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-20.04
12+
strategy:
13+
matrix:
14+
python-version: ['3.9', '3.10']
15+
steps:
16+
- uses: actions/checkout@v3
17+
- name: Set up Python ${{ matrix.python-version }}
18+
uses: actions/setup-python@v2
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
python -m pip install pytest
25+
# Can comment out when next Mathics core and Mathics-scanner are released
26+
python -m pip install -e git+https://github.com/Mathics3/mathics-scanner#egg=Mathics-Scanner[full]
27+
python -m pip install -e git+https://github.com/Mathics3/mathics-core#egg=Mathics3[full]
28+
(cd src/mathics3 && bash ./admin-tools/make-op-tables.sh)
29+
# python -m pip install Mathics3[full]
30+
python -m pip install -e .
31+
- name: install pymathics graph
32+
run: |
33+
make develop
34+
- name: Test Mathics
35+
run: |
36+
make -j3 check

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,8 @@ rmChangeLog:
7474
#: Create a ChangeLog from git via git log and git2cl
7575
ChangeLog: rmChangeLog
7676
git log --pretty --numstat --summary | $(GIT2CL) >$@
77+
78+
79+
#: Run pytest consistency and style checks
80+
check-consistency-and-style:
81+
MATHICS_LINT=t $(PYTHON) -m pytest test/consistency-and-style
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
import glob
2+
import importlib
3+
import os
4+
import os.path as osp
5+
import pkgutil
6+
7+
import pytest
8+
9+
from pymathics.graph import __file__ as module_initfile_path
10+
from mathics.builtin import name_is_builtin_symbol
11+
from mathics.builtin.base import Builtin
12+
from mathics.doc.common_doc import skip_doc
13+
14+
15+
# Get file system path name for mathics.builtin
16+
module_path = osp.dirname(module_initfile_path)
17+
module_builtins_path = module_path
18+
19+
CHECK_GRAMMAR = False
20+
21+
local_vocabulary = (
22+
"Mathics",
23+
"$Aborted",
24+
"Chebyshev",
25+
"Pochhammer",
26+
"Hankel",
27+
"Glaiser",
28+
"kth",
29+
"Struvel",
30+
"Polygamma",
31+
"Stieltjes",
32+
"Gegenbauer",
33+
"Bessel",
34+
"Laguerre",
35+
"Airy",
36+
"polygamma",
37+
"ker",
38+
"kei",
39+
"ber",
40+
"bei",
41+
"n-th",
42+
"i-th",
43+
"q-th",
44+
"th",
45+
"downvalues",
46+
"upvalues",
47+
"ownvalue",
48+
"subvalues",
49+
"machine-precision",
50+
"CompiledFunction",
51+
"CompiledObject",
52+
"ExactNumberQ",
53+
"quantile",
54+
"BeginPackage",
55+
"SetDirectory",
56+
"Begin",
57+
"sympy",
58+
)
59+
60+
language_tool = None
61+
if CHECK_GRAMMAR:
62+
try:
63+
import language_tool_python
64+
65+
language_tool = language_tool_python.LanguageToolPublicAPI("en-US")
66+
# , config={ 'cacheSize': 1000, 'pipelineCaching': True })
67+
except Exception:
68+
pass
69+
70+
module_subdirs = tuple()
71+
72+
__py_files__ = [
73+
osp.basename(f[0:-3])
74+
for f in glob.glob(osp.join(module_path, "[a-z]*.py"))
75+
]
76+
77+
78+
def import_module(module_name: str):
79+
try:
80+
module = importlib.import_module("pymathics.graph." + module_name)
81+
except Exception as e:
82+
print(e)
83+
return None
84+
85+
modules[module_name] = module
86+
87+
88+
# exclude_files = set(("codetables", "base"))
89+
module_names = [f for f in __py_files__]
90+
91+
92+
for subdir in module_subdirs:
93+
import_name = f"pymathics.graph.{subdir}"
94+
builtin_module = importlib.import_module(import_name)
95+
for importer, modname, ispkg in pkgutil.iter_modules(builtin_module.__path__):
96+
module_names.append(f"{subdir}.{modname}")
97+
98+
99+
modules = dict()
100+
for module_name in module_names:
101+
import_module(module_name)
102+
103+
# modules = {"compilation": modules["compilation"],}
104+
105+
106+
def check_grammar(text: str):
107+
matches = language_tool.check(text)
108+
filtered_matches = []
109+
if matches:
110+
for m in matches:
111+
if m.message == "Possible spelling mistake found.":
112+
offset = m.offset
113+
sentence = m.sentence
114+
length = m.errorLength
115+
word = sentence[offset : offset + length]
116+
if word in local_vocabulary:
117+
continue
118+
print(f"<<{word}>> misspelled? not in {local_vocabulary}")
119+
filtered_matches.append(m)
120+
if not filtered_matches:
121+
return True
122+
for msg in filtered_matches:
123+
print("\t", msg)
124+
return False
125+
126+
127+
128+
def check_well_formatted_docstring(docstr: str, instance: Builtin, module_name: str):
129+
assert (
130+
docstr.count("<dl>") >= 1
131+
), f"missing <dl> </dl> tags in {instance.get_name()} from {module_name}"
132+
assert docstr.count("</dl>") == docstr.count(
133+
"<dl>"
134+
), f"unbalanced <dl> </dl> tags in {instance.get_name()} from {module_name}"
135+
assert (
136+
docstr.count("<dt>") > 0
137+
), f"missing <dt> field {instance.get_name()} from {module_name}"
138+
assert (
139+
docstr.count("<dd>") > 0
140+
), f"missing <dd> field {instance.get_name()} from {module_name}"
141+
assert (
142+
docstr.count("</dt>") == 0
143+
), f"unnecesary </dt> {instance.get_name()} from {module_name}"
144+
assert (
145+
docstr.count("</dd>") == 0
146+
), f"unnecesary </dd> field {instance.get_name()} from {module_name}"
147+
148+
assert (
149+
docstr.count("<url>") > 0
150+
), f"missing <url> field {instance.get_name()} from {module_name}"
151+
assert docstr.count("<url>") == docstr.lower().count(
152+
"</url>"
153+
), f"unbalanced <url> </url> tags in {instance.get_name()} from {module_name}"
154+
155+
156+
@pytest.mark.skipif(
157+
not os.environ.get("MATHICS_LINT"),
158+
reason="Checking done only when MATHICS_LINT=t specified",
159+
)
160+
@pytest.mark.parametrize(
161+
("module_name",),
162+
[(module_name,) for module_name in modules],
163+
)
164+
@pytest.mark.skip("not ready")
165+
def test_summary_text_available(module_name):
166+
"""
167+
Checks that each Builtin has its summary_text property.
168+
"""
169+
grammar_OK = True
170+
module = modules[module_name]
171+
if hasattr(module, "no_doc") and module.no_doc is True:
172+
return
173+
vars = dir(module)
174+
for name in vars:
175+
var = name_is_builtin_symbol(module, name)
176+
if var is None:
177+
continue
178+
179+
instance = var(expression=False)
180+
if not isinstance(instance, Builtin):
181+
continue
182+
183+
if skip_doc(instance.__class__):
184+
continue
185+
186+
# For private / internal symbols,
187+
# the documentation is optional.
188+
if "Internal`" in instance.context or "Private`" in instance.context:
189+
continue
190+
191+
# check for a summary text
192+
assert hasattr(instance, "summary_text"), (
193+
f"{var.__name__} in {module_name} " "does not have a summary_text property"
194+
)
195+
# Check for docstrings
196+
docstring = instance.__doc__
197+
assert (
198+
docstring is not None
199+
), f"empty docstring in {instance.get_name()} from {module_name}"
200+
check_well_formatted_docstring(docstring, instance, module_name)
201+
202+
if language_tool and CHECK_GRAMMAR:
203+
full_summary_text = instance.summary_text.strip()
204+
full_summary_text = full_summary_text[0].upper() + full_summary_text[1:]
205+
full_summary_text = full_summary_text + "."
206+
full_summary_text = full_summary_text.replace(" n ", " two ")
207+
if not check_grammar(full_summary_text):
208+
grammar_OK = False
209+
assert grammar_OK

0 commit comments

Comments
 (0)