This commit is contained in:
parent
dd2c98d4e0
commit
98cbe296a5
@ -48,7 +48,7 @@ jobs:
|
|||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
# Run tests with coverage
|
# Run tests with coverage
|
||||||
python -m pytest tests/ -v --cov=pyWebLayout --cov-report=term-missing --cov-report=json --cov-report=html
|
python -m pytest tests/ -v --cov=pyWebLayout --cov-report=term-missing --cov-report=json --cov-report=html --cov-report=xml
|
||||||
|
|
||||||
- name: Check documentation coverage
|
- name: Check documentation coverage
|
||||||
id: docs
|
id: docs
|
||||||
@ -102,6 +102,7 @@ jobs:
|
|||||||
with open('coverage-summary.txt', 'w') as f:
|
with open('coverage-summary.txt', 'w') as f:
|
||||||
f.write(f'{total_coverage}%')
|
f.write(f'{total_coverage}%')
|
||||||
print(f'Test Coverage: {total_coverage}%')
|
print(f'Test Coverage: {total_coverage}%')
|
||||||
|
print(f'Lines Covered: {coverage_data[\'totals\'][\'covered_lines\']}/{coverage_data[\'totals\'][\'num_statements\']}')
|
||||||
else:
|
else:
|
||||||
print('No coverage data found')
|
print('No coverage data found')
|
||||||
"
|
"
|
||||||
@ -137,6 +138,7 @@ jobs:
|
|||||||
coverage-docs.svg
|
coverage-docs.svg
|
||||||
htmlcov/
|
htmlcov/
|
||||||
coverage.json
|
coverage.json
|
||||||
|
coverage.xml
|
||||||
coverage-summary.txt
|
coverage-summary.txt
|
||||||
|
|
||||||
- name: Safety check - prevent infinite loops
|
- name: Safety check - prevent infinite loops
|
||||||
@ -175,4 +177,4 @@ jobs:
|
|||||||
- name: Test package installation
|
- name: Test package installation
|
||||||
run: |
|
run: |
|
||||||
# Test that the package can be imported
|
# Test that the package can be imported
|
||||||
python -c "import pyWebLayout; print('Package imported successfully')"
|
python -c "import pyWebLayout; print('Package imported successfully')"
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<svg width="140" height="20" viewBox="0 0 140 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
<svg width="140" height="20" viewBox="0 0 140 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
<title>interrogate: 93.2%</title>
|
<title>interrogate: 90.0%</title>
|
||||||
<g transform="matrix(1,0,0,1,22,0)">
|
<g transform="matrix(1,0,0,1,22,0)">
|
||||||
<g id="backgrounds" transform="matrix(1.32789,0,0,1,-22.3892,0)">
|
<g id="backgrounds" transform="matrix(1.32789,0,0,1,-22.3892,0)">
|
||||||
<rect x="0" y="0" width="71" height="20" style="fill:rgb(85,85,85);"/>
|
<rect x="0" y="0" width="71" height="20" style="fill:rgb(85,85,85);"/>
|
||||||
@ -12,8 +12,8 @@
|
|||||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
|
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
|
||||||
<text x="590" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="610">interrogate</text>
|
<text x="590" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="610">interrogate</text>
|
||||||
<text x="590" y="140" transform="scale(.1)" textLength="610">interrogate</text>
|
<text x="590" y="140" transform="scale(.1)" textLength="610">interrogate</text>
|
||||||
<text x="1160" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370" data-interrogate="result">93.2%</text>
|
<text x="1160" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370" data-interrogate="result">90.0%</text>
|
||||||
<text x="1160" y="140" transform="scale(.1)" textLength="370" data-interrogate="result">93.2%</text>
|
<text x="1160" y="140" transform="scale(.1)" textLength="370" data-interrogate="result">90.0%</text>
|
||||||
</g>
|
</g>
|
||||||
<g id="logo-shadow" serif:id="logo shadow" transform="matrix(0.854876,0,0,0.854876,-6.73514,1.732)">
|
<g id="logo-shadow" serif:id="logo shadow" transform="matrix(0.854876,0,0,0.854876,-6.73514,1.732)">
|
||||||
<g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
|
<g transform="matrix(0.299012,0,0,0.299012,9.70229,-6.68582)">
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
1
coverage-summary.txt
Normal file
1
coverage-summary.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
33.9%
|
||||||
1
coverage.json
Normal file
1
coverage.json
Normal file
File diff suppressed because one or more lines are too long
112
coverage.xml
112
coverage.xml
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" ?>
|
<?xml version="1.0" ?>
|
||||||
<coverage version="7.8.2" timestamp="1749309218680" lines-valid="3794" lines-covered="1466" line-rate="0.3864" branches-valid="1364" branches-covered="191" branch-rate="0.14" complexity="0">
|
<coverage version="7.8.2" timestamp="1749312034554" lines-valid="3794" lines-covered="1519" line-rate="0.4004" branches-valid="1364" branches-covered="227" branch-rate="0.1664" complexity="0">
|
||||||
<!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.8.2 -->
|
<!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.8.2 -->
|
||||||
<!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
|
<!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
|
||||||
<sources>
|
<sources>
|
||||||
@ -652,7 +652,7 @@
|
|||||||
</class>
|
</class>
|
||||||
</classes>
|
</classes>
|
||||||
</package>
|
</package>
|
||||||
<package name="abstract" line-rate="0.7742" branch-rate="0.3663" complexity="0">
|
<package name="abstract" line-rate="0.8326" branch-rate="0.5756" complexity="0">
|
||||||
<classes>
|
<classes>
|
||||||
<class name="__init__.py" filename="abstract/__init__.py" complexity="0" line-rate="1" branch-rate="1">
|
<class name="__init__.py" filename="abstract/__init__.py" complexity="0" line-rate="1" branch-rate="1">
|
||||||
<methods/>
|
<methods/>
|
||||||
@ -1432,7 +1432,7 @@
|
|||||||
<line number="315" hits="1"/>
|
<line number="315" hits="1"/>
|
||||||
</lines>
|
</lines>
|
||||||
</class>
|
</class>
|
||||||
<class name="inline.py" filename="abstract/inline.py" complexity="0" line-rate="0.6467" branch-rate="0.1818">
|
<class name="inline.py" filename="abstract/inline.py" complexity="0" line-rate="1" branch-rate="1">
|
||||||
<methods/>
|
<methods/>
|
||||||
<lines>
|
<lines>
|
||||||
<line number="1" hits="1"/>
|
<line number="1" hits="1"/>
|
||||||
@ -1450,38 +1450,38 @@
|
|||||||
<line number="30" hits="1"/>
|
<line number="30" hits="1"/>
|
||||||
<line number="32" hits="1"/>
|
<line number="32" hits="1"/>
|
||||||
<line number="33" hits="1"/>
|
<line number="33" hits="1"/>
|
||||||
<line number="56" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="57,63"/>
|
<line number="56" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="57" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="58,60"/>
|
<line number="57" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="58" hits="0"/>
|
<line number="58" hits="1"/>
|
||||||
<line number="60" hits="0"/>
|
<line number="60" hits="1"/>
|
||||||
<line number="63" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="64,67"/>
|
<line number="63" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="64" hits="0"/>
|
<line number="64" hits="1"/>
|
||||||
<line number="67" hits="0"/>
|
<line number="67" hits="1"/>
|
||||||
<line number="68" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="70,71"/>
|
<line number="68" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="70" hits="0"/>
|
<line number="70" hits="1"/>
|
||||||
<line number="71" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="73,81"/>
|
<line number="71" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="73" hits="0"/>
|
<line number="73" hits="1"/>
|
||||||
<line number="75" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="76,81"/>
|
<line number="75" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="76" hits="0"/>
|
<line number="76" hits="1"/>
|
||||||
<line number="77" hits="0"/>
|
<line number="77" hits="1"/>
|
||||||
<line number="78" hits="0"/>
|
<line number="78" hits="1"/>
|
||||||
<line number="81" hits="0"/>
|
<line number="81" hits="1"/>
|
||||||
<line number="84" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="85,88"/>
|
<line number="84" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="85" hits="0"/>
|
<line number="85" hits="1"/>
|
||||||
<line number="88" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="90,113"/>
|
<line number="88" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="90" hits="0"/>
|
<line number="90" hits="1"/>
|
||||||
<line number="91" hits="0"/>
|
<line number="91" hits="1"/>
|
||||||
<line number="92" hits="0"/>
|
<line number="92" hits="1"/>
|
||||||
<line number="94" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="96,111"/>
|
<line number="94" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="96" hits="0"/>
|
<line number="96" hits="1"/>
|
||||||
<line number="97" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="99,104"/>
|
<line number="97" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="99" hits="0"/>
|
<line number="99" hits="1"/>
|
||||||
<line number="104" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="105,108"/>
|
<line number="104" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="105" hits="0"/>
|
<line number="105" hits="1"/>
|
||||||
<line number="108" hits="0"/>
|
<line number="108" hits="1"/>
|
||||||
<line number="111" hits="0"/>
|
<line number="111" hits="1"/>
|
||||||
<line number="113" hits="0"/>
|
<line number="113" hits="1"/>
|
||||||
<line number="115" hits="0"/>
|
<line number="115" hits="1"/>
|
||||||
<line number="117" hits="1"/>
|
<line number="117" hits="1"/>
|
||||||
<line number="118" hits="1"/>
|
<line number="118" hits="1"/>
|
||||||
<line number="120" hits="1"/>
|
<line number="120" hits="1"/>
|
||||||
@ -1533,17 +1533,17 @@
|
|||||||
<line number="248" hits="1"/>
|
<line number="248" hits="1"/>
|
||||||
<line number="250" hits="1"/>
|
<line number="250" hits="1"/>
|
||||||
<line number="251" hits="1"/>
|
<line number="251" hits="1"/>
|
||||||
<line number="268" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="269,275"/>
|
<line number="268" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="269" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="270,272"/>
|
<line number="269" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="270" hits="0"/>
|
<line number="270" hits="1"/>
|
||||||
<line number="272" hits="0"/>
|
<line number="272" hits="1"/>
|
||||||
<line number="275" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="276,279"/>
|
<line number="275" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="276" hits="0"/>
|
<line number="276" hits="1"/>
|
||||||
<line number="279" hits="0"/>
|
<line number="279" hits="1"/>
|
||||||
<line number="282" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="283,285"/>
|
<line number="282" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="283" hits="0"/>
|
<line number="283" hits="1"/>
|
||||||
<line number="285" hits="0"/>
|
<line number="285" hits="1"/>
|
||||||
<line number="287" hits="0"/>
|
<line number="287" hits="1"/>
|
||||||
<line number="289" hits="1"/>
|
<line number="289" hits="1"/>
|
||||||
<line number="290" hits="1"/>
|
<line number="290" hits="1"/>
|
||||||
<line number="292" hits="1"/>
|
<line number="292" hits="1"/>
|
||||||
@ -1573,18 +1573,18 @@
|
|||||||
<line number="352" hits="1"/>
|
<line number="352" hits="1"/>
|
||||||
<line number="354" hits="1"/>
|
<line number="354" hits="1"/>
|
||||||
<line number="355" hits="1"/>
|
<line number="355" hits="1"/>
|
||||||
<line number="357" hits="0"/>
|
<line number="357" hits="1"/>
|
||||||
<line number="359" hits="1"/>
|
<line number="359" hits="1"/>
|
||||||
<line number="360" hits="1"/>
|
<line number="360" hits="1"/>
|
||||||
<line number="371" hits="0"/>
|
<line number="371" hits="1"/>
|
||||||
<line number="374" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="375,376"/>
|
<line number="374" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="375" hits="0"/>
|
<line number="375" hits="1"/>
|
||||||
<line number="376" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="377,378"/>
|
<line number="376" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="377" hits="0"/>
|
<line number="377" hits="1"/>
|
||||||
<line number="378" hits="0" branch="true" condition-coverage="0% (0/2)" missing-branches="380,383"/>
|
<line number="378" hits="1" branch="true" condition-coverage="100% (2/2)"/>
|
||||||
<line number="380" hits="0"/>
|
<line number="380" hits="1"/>
|
||||||
<line number="383" hits="0"/>
|
<line number="383" hits="1"/>
|
||||||
<line number="385" hits="0"/>
|
<line number="385" hits="1"/>
|
||||||
</lines>
|
</lines>
|
||||||
</class>
|
</class>
|
||||||
</classes>
|
</classes>
|
||||||
|
|||||||
61
fix_coverage_paths.py
Normal file
61
fix_coverage_paths.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Fix coverage paths for Coverage Gutters extension.
|
||||||
|
This script modifies the coverage.xml file to use relative paths instead of absolute paths.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def fix_coverage_paths():
|
||||||
|
"""Fix the paths in coverage.xml to be relative to the workspace root."""
|
||||||
|
|
||||||
|
# Read the coverage.xml file
|
||||||
|
tree = ET.parse('coverage.xml')
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
# Get the current working directory
|
||||||
|
current_dir = os.getcwd()
|
||||||
|
print(f"Current directory: {current_dir}")
|
||||||
|
|
||||||
|
# Find and update the source element
|
||||||
|
sources = root.find('sources')
|
||||||
|
if sources is not None:
|
||||||
|
for source in sources.findall('source'):
|
||||||
|
old_path = source.text
|
||||||
|
print(f"Old source path: {old_path}")
|
||||||
|
|
||||||
|
# Convert absolute path to relative path
|
||||||
|
if old_path.startswith(current_dir):
|
||||||
|
# Remove the current directory part and the extra 'pyWebLayout' part
|
||||||
|
relative_path = old_path.replace(current_dir + '/pyWebLayout', './pyWebLayout')
|
||||||
|
# Or just use current directory
|
||||||
|
relative_path = '.'
|
||||||
|
source.text = relative_path
|
||||||
|
print(f"New source path: {relative_path}")
|
||||||
|
|
||||||
|
# Update all filename attributes in class elements to be relative
|
||||||
|
for package in root.findall('.//package'):
|
||||||
|
for cls in package.findall('classes/class'):
|
||||||
|
filename = cls.get('filename')
|
||||||
|
if filename:
|
||||||
|
# Ensure filename is relative to project root
|
||||||
|
if not filename.startswith('./') and not filename.startswith('pyWebLayout/'):
|
||||||
|
# Add pyWebLayout/ prefix if it's just a bare filename
|
||||||
|
if '/' not in filename:
|
||||||
|
# This is a top-level file
|
||||||
|
new_filename = f"pyWebLayout/{filename}"
|
||||||
|
else:
|
||||||
|
# This already has a path, just prefix with pyWebLayout/
|
||||||
|
new_filename = f"pyWebLayout/{filename}"
|
||||||
|
cls.set('filename', new_filename)
|
||||||
|
print(f"Updated filename: {filename} -> {new_filename}")
|
||||||
|
|
||||||
|
# Save the modified XML
|
||||||
|
tree.write('coverage.xml', encoding='utf-8', xml_declaration=True)
|
||||||
|
print("Coverage paths fixed successfully!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
fix_coverage_paths()
|
||||||
@ -2,6 +2,7 @@
|
|||||||
"""
|
"""
|
||||||
Simple coverage runner for Coverage Gutters extension.
|
Simple coverage runner for Coverage Gutters extension.
|
||||||
Generates coverage.xml file needed by the VSCode Coverage Gutters extension.
|
Generates coverage.xml file needed by the VSCode Coverage Gutters extension.
|
||||||
|
Uses the same approach as CI for consistency.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
@ -12,32 +13,46 @@ import os
|
|||||||
def main():
|
def main():
|
||||||
"""Run coverage for Coverage Gutters."""
|
"""Run coverage for Coverage Gutters."""
|
||||||
print("Generating coverage for Coverage Gutters...")
|
print("Generating coverage for Coverage Gutters...")
|
||||||
|
print("Using the same pytest approach as CI...")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Run tests with coverage and generate XML report
|
# Run tests with coverage and generate all report formats (same as CI)
|
||||||
cmd = [
|
cmd = [
|
||||||
sys.executable, "-m", "pytest",
|
sys.executable, "-m", "pytest",
|
||||||
"tests/",
|
"tests/",
|
||||||
|
"-v",
|
||||||
"--cov=pyWebLayout",
|
"--cov=pyWebLayout",
|
||||||
"--cov-report=xml",
|
"--cov-report=term-missing",
|
||||||
"--cov-report=term"
|
"--cov-report=json",
|
||||||
|
"--cov-report=html",
|
||||||
|
"--cov-report=xml"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
print(f"Running: {' '.join(cmd)}")
|
||||||
result = subprocess.run(cmd, check=True)
|
result = subprocess.run(cmd, check=True)
|
||||||
|
|
||||||
# Check if coverage.xml was created
|
# Check if coverage.xml was created
|
||||||
if os.path.exists("coverage.xml"):
|
if os.path.exists("coverage.xml"):
|
||||||
print("✓ coverage.xml generated successfully!")
|
print("✓ coverage.xml generated successfully!")
|
||||||
print("Coverage Gutters should now be able to display coverage data.")
|
print("✓ coverage.json generated for CI compatibility")
|
||||||
|
print("✓ HTML coverage report generated in htmlcov/")
|
||||||
|
print("\nCoverage Gutters should now be able to display coverage data.")
|
||||||
print("\nTo use Coverage Gutters in VSCode:")
|
print("\nTo use Coverage Gutters in VSCode:")
|
||||||
print("1. Open Command Palette (Ctrl+Shift+P)")
|
print("1. Open Command Palette (Ctrl+Shift+P)")
|
||||||
print("2. Run 'Coverage Gutters: Display Coverage'")
|
print("2. Run 'Coverage Gutters: Remove Coverage' (to clear cache)")
|
||||||
print("3. Or use the Coverage Gutters buttons in the status bar")
|
print("3. Run 'Coverage Gutters: Display Coverage'")
|
||||||
|
print("4. Or use the Coverage Gutters buttons in the status bar")
|
||||||
|
|
||||||
|
# Show file info
|
||||||
|
size = os.path.getsize("coverage.xml")
|
||||||
|
print(f"\nGenerated coverage.xml: {size} bytes")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("✗ coverage.xml was not generated")
|
print("✗ coverage.xml was not generated")
|
||||||
|
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
print(f"Error running tests: {e}")
|
print(f"Error running tests: {e}")
|
||||||
|
print("This may indicate test failures or missing dependencies.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print("pytest not found. Please install it with: pip install pytest pytest-cov")
|
print("pytest not found. Please install it with: pip install pytest pytest-cov")
|
||||||
|
|||||||
@ -58,7 +58,7 @@ def main():
|
|||||||
|
|
||||||
# Generate test coverage badge
|
# Generate test coverage badge
|
||||||
print("\n3. Generating test coverage badge...")
|
print("\n3. Generating test coverage badge...")
|
||||||
run_command("coverage-badge -o coverage.svg", "Generating test coverage badge")
|
run_command("coverage-badge -o coverage.svg -f", "Generating test coverage badge")
|
||||||
|
|
||||||
# Check documentation coverage
|
# Check documentation coverage
|
||||||
print("\n4. Checking documentation coverage...")
|
print("\n4. Checking documentation coverage...")
|
||||||
@ -67,25 +67,37 @@ def main():
|
|||||||
|
|
||||||
# Generate coverage summary
|
# Generate coverage summary
|
||||||
print("\n5. Generating coverage summary...")
|
print("\n5. Generating coverage summary...")
|
||||||
summary_script = """
|
|
||||||
import json
|
# Write a temporary script to avoid shell quoting issues
|
||||||
|
summary_script_content = '''import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
if os.path.exists('coverage.json'):
|
if os.path.exists("coverage.json"):
|
||||||
with open('coverage.json', 'r') as f:
|
with open("coverage.json", "r") as f:
|
||||||
coverage_data = json.load(f)
|
coverage_data = json.load(f)
|
||||||
|
|
||||||
total_coverage = round(coverage_data['totals']['percent_covered'], 1)
|
total_coverage = round(coverage_data["totals"]["percent_covered"], 1)
|
||||||
|
covered_lines = coverage_data["totals"]["covered_lines"]
|
||||||
|
total_lines = coverage_data["totals"]["num_statements"]
|
||||||
|
|
||||||
with open('coverage-summary.txt', 'w') as f:
|
with open("coverage-summary.txt", "w") as f:
|
||||||
f.write(f'{total_coverage}%')
|
f.write(f"{total_coverage}%")
|
||||||
|
|
||||||
print(f'Test Coverage: {total_coverage}%')
|
print(f"Test Coverage: {total_coverage}%")
|
||||||
print(f'Lines Covered: {coverage_data["totals"]["covered_lines"]}/{coverage_data["totals"]["num_statements"]}')
|
print(f"Lines Covered: {covered_lines}/{total_lines}")
|
||||||
else:
|
else:
|
||||||
print('No coverage data found')
|
print("No coverage data found")
|
||||||
"""
|
'''
|
||||||
run_command(f'python -c "{summary_script}"', "Generating coverage summary")
|
|
||||||
|
# Write and execute temporary script
|
||||||
|
with open('temp_coverage_summary.py', 'w') as f:
|
||||||
|
f.write(summary_script_content)
|
||||||
|
|
||||||
|
success = run_command("python temp_coverage_summary.py", "Generating coverage summary")
|
||||||
|
|
||||||
|
# Clean up temporary script
|
||||||
|
if os.path.exists('temp_coverage_summary.py'):
|
||||||
|
os.remove('temp_coverage_summary.py')
|
||||||
|
|
||||||
# List generated files
|
# List generated files
|
||||||
print("\n6. Generated files:")
|
print("\n6. Generated files:")
|
||||||
|
|||||||
103
update_coverage_gutters.py
Normal file
103
update_coverage_gutters.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Update coverage gutters configuration and fix coverage paths.
|
||||||
|
This script ensures Coverage Gutters can properly display coverage information.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main function to fix coverage gutters configuration."""
|
||||||
|
|
||||||
|
print("=== Coverage Gutters Fix ===")
|
||||||
|
print(f"Current working directory: {os.getcwd()}")
|
||||||
|
|
||||||
|
# 1. Check if coverage.xml exists
|
||||||
|
if os.path.exists('coverage.xml'):
|
||||||
|
print("✓ coverage.xml exists")
|
||||||
|
|
||||||
|
# Check file size and basic content
|
||||||
|
size = os.path.getsize('coverage.xml')
|
||||||
|
print(f"✓ coverage.xml size: {size} bytes")
|
||||||
|
|
||||||
|
# Read first few lines to verify it's valid XML
|
||||||
|
try:
|
||||||
|
with open('coverage.xml', 'r') as f:
|
||||||
|
first_line = f.readline().strip()
|
||||||
|
if first_line.startswith('<?xml'):
|
||||||
|
print("✓ coverage.xml appears to be valid XML")
|
||||||
|
else:
|
||||||
|
print("✗ coverage.xml does not start with XML declaration")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ Error reading coverage.xml: {e}")
|
||||||
|
else:
|
||||||
|
print("✗ coverage.xml does not exist")
|
||||||
|
print("Running coverage to generate coverage.xml...")
|
||||||
|
os.system("python -m coverage run --source=pyWebLayout -m unittest tests.test_abstract_inline")
|
||||||
|
os.system("python -m coverage xml")
|
||||||
|
|
||||||
|
# 2. Check VSCode settings
|
||||||
|
vscode_settings_path = '.vscode/settings.json'
|
||||||
|
if os.path.exists(vscode_settings_path):
|
||||||
|
print("✓ VSCode settings.json exists")
|
||||||
|
|
||||||
|
with open(vscode_settings_path, 'r') as f:
|
||||||
|
try:
|
||||||
|
settings = json.load(f)
|
||||||
|
gutters_config = {k: v for k, v in settings.items() if 'coverage-gutters' in k}
|
||||||
|
if gutters_config:
|
||||||
|
print("✓ Coverage Gutters settings found:")
|
||||||
|
for key, value in gutters_config.items():
|
||||||
|
print(f" {key}: {value}")
|
||||||
|
else:
|
||||||
|
print("✗ No Coverage Gutters settings found")
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
print(f"✗ Error parsing VSCode settings: {e}")
|
||||||
|
else:
|
||||||
|
print("✗ VSCode settings.json not found")
|
||||||
|
|
||||||
|
# 3. Check if inline.py file exists
|
||||||
|
inline_file = 'pyWebLayout/abstract/inline.py'
|
||||||
|
if os.path.exists(inline_file):
|
||||||
|
print(f"✓ {inline_file} exists")
|
||||||
|
|
||||||
|
# Check file size
|
||||||
|
size = os.path.getsize(inline_file)
|
||||||
|
print(f"✓ {inline_file} size: {size} bytes")
|
||||||
|
else:
|
||||||
|
print(f"✗ {inline_file} does not exist")
|
||||||
|
|
||||||
|
# 4. Run a fresh coverage collection specifically for the inline module
|
||||||
|
print("\n=== Running Fresh Coverage ===")
|
||||||
|
try:
|
||||||
|
print("Running tests with coverage...")
|
||||||
|
os.system("python -m coverage erase") # Clear old coverage data
|
||||||
|
os.system("python -m coverage run --source=pyWebLayout -m unittest tests.test_abstract_inline -v")
|
||||||
|
os.system("python -m coverage xml -o coverage.xml")
|
||||||
|
os.system("python -m coverage report --include='pyWebLayout/abstract/inline.py'")
|
||||||
|
print("✓ Fresh coverage data generated")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ Error generating coverage: {e}")
|
||||||
|
|
||||||
|
# 5. Instructions for manual verification
|
||||||
|
print("\n=== Manual Verification Steps ===")
|
||||||
|
print("1. In VSCode, open the Command Palette (Ctrl+Shift+P)")
|
||||||
|
print("2. Run 'Coverage Gutters: Display Coverage'")
|
||||||
|
print("3. If coverage doesn't appear, try:")
|
||||||
|
print(" - 'Coverage Gutters: Remove Coverage'")
|
||||||
|
print(" - 'Coverage Gutters: Display Coverage' again")
|
||||||
|
print("4. Check that coverage.xml contains data for pyWebLayout/abstract/inline.py")
|
||||||
|
print("5. The file should show 100% coverage (all lines covered)")
|
||||||
|
|
||||||
|
print("\n=== Troubleshooting ===")
|
||||||
|
print("If coverage still doesn't show:")
|
||||||
|
print("1. Restart VSCode")
|
||||||
|
print("2. Check Coverage Gutters extension is enabled")
|
||||||
|
print("3. Try running: python run_coverage_gutters.py")
|
||||||
|
print("4. Check VSCode Output panel for Coverage Gutters logs")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
x
Reference in New Issue
Block a user