Skip to content

Commit f3e619e

Browse files
committed
temp: put back paver checks for testing
1 parent c76feed commit f3e619e

18 files changed

+2193
-1
lines changed

.github/workflows/js-tests-paver.yml

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: Javascript tests PAVER
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- master
8+
9+
jobs:
10+
run_tests:
11+
name: JS
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
matrix:
15+
os: [ubuntu-latest]
16+
node-version: [18, 20]
17+
python-version:
18+
- "3.11"
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
- name: Fetch master to compare coverage
23+
run: git fetch --depth=1 origin master
24+
25+
- name: Setup Node
26+
uses: actions/setup-node@v4
27+
with:
28+
node-version: ${{ matrix.node-version }}
29+
30+
- name: Setup npm
31+
run: npm i -g [email protected]
32+
33+
- name: Install Firefox 123.0
34+
run: |
35+
sudo apt-get purge firefox
36+
wget "https://ftp.mozilla.org/pub/firefox/releases/123.0/linux-x86_64/en-US/firefox-123.0.tar.bz2"
37+
tar -xjf firefox-123.0.tar.bz2
38+
sudo mv firefox /opt/firefox
39+
sudo ln -s /opt/firefox/firefox /usr/bin/firefox
40+
41+
- name: Install Required System Packages
42+
run: sudo apt-get update && sudo apt-get install libxmlsec1-dev ubuntu-restricted-extras xvfb
43+
44+
- name: Setup Python
45+
uses: actions/setup-python@v5
46+
with:
47+
python-version: ${{ matrix.python-version }}
48+
49+
- name: Get pip cache dir
50+
id: pip-cache-dir
51+
run: |
52+
echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
53+
54+
- name: Cache pip dependencies
55+
id: cache-dependencies
56+
uses: actions/cache@v4
57+
with:
58+
path: ${{ steps.pip-cache-dir.outputs.dir }}
59+
key: ${{ runner.os }}-pip-${{ hashFiles('requirements/edx/base.txt') }}
60+
restore-keys: ${{ runner.os }}-pip-
61+
62+
- name: Install Required Python Dependencies
63+
run: |
64+
make base-requirements
65+
66+
- uses: c-hive/gha-npm-cache@v1
67+
- name: Run JS Tests
68+
env:
69+
TEST_SUITE: js-unit
70+
SCRIPT_TO_RUN: ./scripts/generic-ci-tests.sh
71+
run: |
72+
npm install -g jest
73+
xvfb-run --auto-servernum ./scripts/all-tests.sh
74+
75+
- name: Save Job Artifacts
76+
uses: actions/upload-artifact@v4
77+
with:
78+
name: Build-Artifacts
79+
path: |
80+
reports/**/*
81+
test_root/log/*.png
82+
test_root/log/*.log
83+
**/TEST-*.xml
84+
overwrite: true
+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Quality checks PAVER
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- master
8+
- open-release/lilac.master
9+
10+
jobs:
11+
run_tests:
12+
name: Quality Others
13+
runs-on: ${{ matrix.os }}
14+
strategy:
15+
matrix:
16+
os: [ubuntu-22.04]
17+
python-version:
18+
- "3.11"
19+
node-version: [20]
20+
21+
steps:
22+
- uses: actions/checkout@v4
23+
with:
24+
fetch-depth: 2
25+
26+
- name: Fetch base branch for comparison
27+
run: git fetch --depth=1 origin ${{ github.base_ref }}
28+
29+
- name: Install Required System Packages
30+
run: sudo apt-get update && sudo apt-get install libxmlsec1-dev
31+
32+
- name: Setup Python
33+
uses: actions/setup-python@v5
34+
with:
35+
python-version: ${{ matrix.python-version }}
36+
37+
- name: Setup Node
38+
uses: actions/setup-node@v4
39+
with:
40+
node-version: ${{ matrix.node-version }}
41+
42+
- name: Setup npm
43+
run: npm i -g [email protected]
44+
45+
- name: Get pip cache dir
46+
id: pip-cache-dir
47+
run: |
48+
echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
49+
50+
- name: Cache pip dependencies
51+
id: cache-dependencies
52+
uses: actions/cache@v4
53+
with:
54+
path: ${{ steps.pip-cache-dir.outputs.dir }}
55+
key: ${{ runner.os }}-pip-${{ hashFiles('requirements/edx/testing.txt') }}
56+
restore-keys: ${{ runner.os }}-pip-
57+
58+
- name: Install Required Python Dependencies
59+
env:
60+
PIP_SRC: ${{ runner.temp }}
61+
run: |
62+
make test-requirements
63+
64+
- name: Run Quality Tests
65+
env:
66+
TEST_SUITE: quality
67+
SCRIPT_TO_RUN: ./scripts/generic-ci-tests.sh
68+
PIP_SRC: ${{ runner.temp }}
69+
TARGET_BRANCH: ${{ github.base_ref }}
70+
run: |
71+
./scripts/all-tests.sh
72+
73+
- name: Save Job Artifacts
74+
if: always()
75+
uses: actions/upload-artifact@v4
76+
with:
77+
name: Build-Artifacts
78+
path: |
79+
**/reports/**/*
80+
test_root/log/**/*.log
81+
*.log
82+
overwrite: true

pavelib/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
"""
44

55

6-
from . import assets
6+
from . import assets, js_test, prereqs, quality

pavelib/js_test.py

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
"""
2+
Javascript test tasks
3+
"""
4+
5+
6+
import os
7+
import re
8+
import sys
9+
10+
from paver.easy import cmdopts, needs, sh, task
11+
12+
from pavelib.utils.envs import Env
13+
from pavelib.utils.test.suites import JestSnapshotTestSuite, JsTestSuite
14+
from pavelib.utils.timer import timed
15+
16+
try:
17+
from pygments.console import colorize
18+
except ImportError:
19+
colorize = lambda color, text: text
20+
21+
__test__ = False # do not collect
22+
23+
24+
@task
25+
@needs(
26+
'pavelib.prereqs.install_node_prereqs',
27+
'pavelib.utils.test.utils.clean_reports_dir',
28+
)
29+
@cmdopts([
30+
("suite=", "s", "Test suite to run"),
31+
("mode=", "m", "dev or run"),
32+
("coverage", "c", "Run test under coverage"),
33+
("port=", "p", "Port to run test server on (dev mode only)"),
34+
('skip-clean', 'C', 'skip cleaning repository before running tests'),
35+
('skip_clean', None, 'deprecated in favor of skip-clean'),
36+
], share_with=["pavelib.utils.tests.utils.clean_reports_dir"])
37+
@timed
38+
def test_js(options):
39+
"""
40+
Run the JavaScript tests
41+
"""
42+
mode = getattr(options, 'mode', 'run')
43+
port = None
44+
skip_clean = getattr(options, 'skip_clean', False)
45+
46+
if mode == 'run':
47+
suite = getattr(options, 'suite', 'all')
48+
coverage = getattr(options, 'coverage', False)
49+
elif mode == 'dev':
50+
suite = getattr(options, 'suite', None)
51+
coverage = False
52+
port = getattr(options, 'port', None)
53+
else:
54+
sys.stderr.write("Invalid mode. Please choose 'dev' or 'run'.")
55+
return
56+
57+
if (suite != 'all') and (suite not in Env.JS_TEST_ID_KEYS):
58+
sys.stderr.write(
59+
"Unknown test suite. Please choose from ({suites})\n".format(
60+
suites=", ".join(Env.JS_TEST_ID_KEYS)
61+
)
62+
)
63+
return
64+
65+
if suite != 'jest-snapshot':
66+
test_suite = JsTestSuite(suite, mode=mode, with_coverage=coverage, port=port, skip_clean=skip_clean)
67+
test_suite.run()
68+
69+
if (suite == 'jest-snapshot') or (suite == 'all'): # lint-amnesty, pylint: disable=consider-using-in
70+
test_suite = JestSnapshotTestSuite('jest')
71+
test_suite.run()
72+
73+
74+
@task
75+
@cmdopts([
76+
("suite=", "s", "Test suite to run"),
77+
("coverage", "c", "Run test under coverage"),
78+
])
79+
@timed
80+
def test_js_run(options):
81+
"""
82+
Run the JavaScript tests and print results to the console
83+
"""
84+
options.mode = 'run'
85+
test_js(options)
86+
87+
88+
@task
89+
@cmdopts([
90+
("suite=", "s", "Test suite to run"),
91+
("port=", "p", "Port to run test server on"),
92+
])
93+
@timed
94+
def test_js_dev(options):
95+
"""
96+
Run the JavaScript tests in your default browsers
97+
"""
98+
options.mode = 'dev'
99+
test_js(options)
100+
101+
102+
@task
103+
@needs('pavelib.prereqs.install_coverage_prereqs')
104+
@cmdopts([
105+
("compare-branch=", "b", "Branch to compare against, defaults to origin/master"),
106+
], share_with=['coverage'])
107+
@timed
108+
def diff_coverage(options):
109+
"""
110+
Build the diff coverage reports
111+
"""
112+
compare_branch = options.get('compare_branch', 'origin/master')
113+
114+
# Find all coverage XML files (both Python and JavaScript)
115+
xml_reports = []
116+
117+
for filepath in Env.REPORT_DIR.walk():
118+
if bool(re.match(r'^coverage.*\.xml$', filepath.basename())):
119+
xml_reports.append(filepath)
120+
121+
if not xml_reports:
122+
err_msg = colorize(
123+
'red',
124+
"No coverage info found. Run `paver test` before running "
125+
"`paver coverage`.\n"
126+
)
127+
sys.stderr.write(err_msg)
128+
else:
129+
xml_report_str = ' '.join(xml_reports)
130+
diff_html_path = os.path.join(Env.REPORT_DIR, 'diff_coverage_combined.html')
131+
132+
# Generate the diff coverage reports (HTML and console)
133+
# The --diff-range-notation parameter is a workaround for https://github.com/Bachmann1234/diff_cover/issues/153
134+
sh(
135+
"diff-cover {xml_report_str} --diff-range-notation '..' --compare-branch={compare_branch} "
136+
"--html-report {diff_html_path}".format(
137+
xml_report_str=xml_report_str,
138+
compare_branch=compare_branch,
139+
diff_html_path=diff_html_path,
140+
)
141+
)
142+
143+
print("\n")

pavelib/paver_tests/conftest.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""
2+
Pytest fixtures for the pavelib unit tests.
3+
"""
4+
5+
6+
import os
7+
from shutil import rmtree
8+
9+
import pytest
10+
11+
from pavelib.utils.envs import Env
12+
13+
14+
@pytest.fixture(autouse=True, scope='session')
15+
def delete_quality_junit_xml():
16+
"""
17+
Delete the JUnit XML results files for quality check tasks run during the
18+
unit tests.
19+
"""
20+
yield
21+
if os.path.exists(Env.QUALITY_DIR):
22+
rmtree(Env.QUALITY_DIR, ignore_errors=True)

pavelib/paver_tests/test_eslint.py

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"""
2+
Tests for Paver's Stylelint tasks.
3+
"""
4+
5+
6+
import unittest
7+
from unittest.mock import patch
8+
9+
import pytest
10+
from paver.easy import BuildFailure, call_task
11+
12+
import pavelib.quality
13+
14+
15+
class TestPaverESLint(unittest.TestCase):
16+
"""
17+
For testing run_eslint
18+
"""
19+
20+
def setUp(self):
21+
super().setUp()
22+
23+
# Mock the paver @needs decorator
24+
self._mock_paver_needs = patch.object(pavelib.quality.run_eslint, 'needs').start()
25+
self._mock_paver_needs.return_value = 0
26+
27+
# Mock shell commands
28+
patcher = patch('pavelib.quality.sh')
29+
self._mock_paver_sh = patcher.start()
30+
31+
# Cleanup mocks
32+
self.addCleanup(patcher.stop)
33+
self.addCleanup(self._mock_paver_needs.stop)
34+
35+
@patch.object(pavelib.quality, '_write_metric')
36+
@patch.object(pavelib.quality, '_prepare_report_dir')
37+
@patch.object(pavelib.quality, '_get_count_from_last_line')
38+
def test_eslint_violation_number_not_found(self, mock_count, mock_report_dir, mock_write_metric): # pylint: disable=unused-argument
39+
"""
40+
run_eslint encounters an error parsing the eslint output log
41+
"""
42+
mock_count.return_value = None
43+
with pytest.raises(BuildFailure):
44+
call_task('pavelib.quality.run_eslint', args=[''])
45+
46+
@patch.object(pavelib.quality, '_write_metric')
47+
@patch.object(pavelib.quality, '_prepare_report_dir')
48+
@patch.object(pavelib.quality, '_get_count_from_last_line')
49+
def test_eslint_vanilla(self, mock_count, mock_report_dir, mock_write_metric): # pylint: disable=unused-argument
50+
"""
51+
eslint finds violations, but a limit was not set
52+
"""
53+
mock_count.return_value = 1
54+
pavelib.quality.run_eslint("")

0 commit comments

Comments
 (0)