feat: add initial WOMM Certification Toolkit implementation

Introduces the Works On My Machine certification framework, including:
- CLI tool for project certification and badge/certificate generation
- Certification checks per WOMM-STD-001:2026 standard
- Supporting documents, assets, and tests
- Python package setup with pyproject.toml
This commit is contained in:
Gregory Gauthier 2026-04-02 16:30:28 +01:00
commit 1002b16b81
19 changed files with 1834 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.idea/
poetry.lock

64
README.md Normal file
View File

@ -0,0 +1,64 @@
# WOMM Certification Toolkit
**Works On My Machine -- The Official Certification Standard**
A formal certification framework for the age-old claim "it works on my machine," complete with a bureaucratic standards document, an official seal of approval, and a CLI tool to certify your projects.
## Installation
```bash
pip install -e .
```
For PNG badge export support:
```bash
pip install -e '.[png]'
```
## Usage
### Certify a project
```bash
womm certify # certify current directory
womm certify /path/to/project
womm certify --level gold # target a specific level
```
### Generate a badge
```bash
womm badge # default: gold, womm-seal.svg
womm badge --level platinum -o seal.svg
```
### Generate a certificate
```bash
womm certificate # print to stdout
womm certificate -o cert.txt # save to file
```
### Read the standard
```bash
womm standard
```
## Certification Levels
| Level | Requirements |
|----------|-------------|
| Bronze | Project exists, has source files, no syntax errors |
| Silver | Bronze + tests exist and pass |
| Gold | Silver + README exists, no TODO/FIXME/HACK comments |
| Platinum | Gold + CI config present, git tree is clean |
## The Standard
See [WOMM-STD-001:2026](WOMM-STANDARD-001.md) for the full certification standard.
## License
MIT

99
WOMM-CERTIFICATE.txt Normal file
View File

@ -0,0 +1,99 @@
================================================================
WOMM CERTIFICATE OF COMPLIANCE
WOMM-STD-001:2026
================================================================
Certificate Number: WOMM-20260402162108-3551
Date of Issuance: 2026-04-02 16:21:08
Standard: WOMM-STD-001:2026, First Edition
----------------------------------------------------------------
PROJECT INFORMATION
----------------------------------------------------------------
Project Name: womm-certification
Project Path: /Users/gregory.gauthier/Projects/local/womm-certification
Certification Level: BRONZE (It Compiles)
----------------------------------------------------------------
CERTIFICATION AUTHORITY
----------------------------------------------------------------
Certifying Machine: PD2328.local
Certifying User: gregory.gauthier
Operating System: Darwin 24.6.0
Python Version: 3.9.6
This certification was performed on the above machine and is
valid exclusively for this machine in its current configuration,
including all running processes, environment variables, and the
certifier's current emotional state.
----------------------------------------------------------------
AUDIT TRAIL
----------------------------------------------------------------
| Check | Result | Detail |
|------------------------------------------|--------|--------|
| Project directory exists | PASS | Project directory located. We're off to a strong start. |
| Contains source code | PASS | Source files detected. This is, in fact, a software project. |
| Python syntax check | PASS | All Python files parse cleanly. The AST smiles upon you. |
| Test suite exists | PASS | Test suite located. Someone here believes in accountability. |
| Tests pass | FAIL | Could not find a test runner. Neither pytest nor unittest obliged. |
| README exists | PASS | README found. Documentation: the thought that counts. |
| No TODO/FIXME/HACK comments | FAIL | Found markers in: test_certify.py:102, certify.py:215, certify.py:233. The guilt is documented. |
| CI configuration exists | FAIL | No CI configuration found. You are the CI. |
| Git working tree is clean | FAIL | Uncommitted changes detected. Living dangerously. |
----------------------------------------------------------------
DECLARATION
----------------------------------------------------------------
I, Greg Gauthier, do hereby certify that the software
project "womm-certification" has been evaluated in accordance
with WOMM-STD-001:2026 and has achieved:
*** WOMM BRONZE CERTIFICATION ***
This certification is granted under the following conditions:
1. The software was observed to work on my machine.
2. No guarantee is made regarding any other machine.
3. This certificate is void if anyone asks "are you sure?"
4. Validity expires upon the next git pull, dependency update,
or passage of more than 24 hours.
----------------------------------------------------------------
SIGNATURES
----------------------------------------------------------------
Certified by:
___________________________
Greg Gauthier
My Machine
2026-04-02
Witnessed by:
___________________________
/dev/null
(The Void)
Approved by the WOMM Standards Committee:
___________________________
The Committee
(Quorum: 1)
================================================================
This document was generated in compliance with WOMM-STD-001:2026
"Works On My Machine" Certification Standard
First Edition, 2026-04-02
Copyright 2026 The WOMM Standards Committee.
All rights reserved, except the right to guarantee
it works on your machine.
================================================================

482
WOMM-STANDARD-001.md Normal file
View File

@ -0,0 +1,482 @@
# WOMM-STD-001:2026
## Works On My Machine — Certification Standard
**First Edition — 2026-04-02**
Published by the **International Bureau of Local Development Assurance (IBLDA)**
on behalf of the **WOMM Standards Committee (WSC)**
---
> *"It works on my machine."*
> — Every developer, at some point
---
## Document Classification
| Field | Value |
|----------------------|--------------------------------------------|
| Standard Number | WOMM-STD-001:2026 |
| Edition | First |
| Status | **ACTIVE** |
| Classification | Public — Developer Eyes Only |
| Supersedes | Verbal assurances, Slack messages, shrugs |
| Committee | WOMM Standards Committee (WSC/TC-1) |
| Secretariat | IBLDA, Geneva (or wherever the laptop is) |
---
## Foreword
The WOMM Standards Committee (WSC) was convened in response to an
industry-wide crisis of confidence in the phrase "it works on my
machine." For decades, this declaration has served as the final word
in software dispute resolution, yet it has lacked the formal rigour
demanded by modern engineering practice.
This standard provides a comprehensive framework for evaluating,
certifying, and communicating the operational status of software
within the confines of a single developer's workstation. It is the
product of extensive deliberation by experts from such distinguished
fields as "closing the laptop and hoping for the best" and "I swear
I didn't change anything."
The WSC acknowledges that this standard cannot guarantee software
will work on any machine other than the one on which certification
was performed. This is, in fact, the entire point.
Participation in this certification programme is voluntary. However,
developers who do not participate will be asked "but did you even
try?" at their next standup.
---
## 1. Scope
### 1.1 Purpose
This standard establishes the requirements for certifying that a
software project **works on the certifier's machine** at the time
of certification. It provides:
a) A common vocabulary for describing the state of "working"
b) A tiered certification framework with escalating levels of
assurance
c) Procedures for auditing and verifying compliance
d) A formal mechanism for responding to the question "well, does
it work?"
### 1.2 Applicability
This standard applies to any software project, repository, script,
or "quick hack I threw together" that resides on a local filesystem
and is subject to the claim "it works on my machine."
### 1.3 Limitations
This standard explicitly does **not** certify that the software:
- Works on anyone else's machine
- Will continue to work after the next `git pull`
- Works when the Wi-Fi is off (unless the project does not require
Wi-Fi, in which case, congratulations)
- Works in production
- Works
The certification is valid only for the exact hardware, software,
environment variables, running background processes, phase of the
moon, and emotional state of the developer present at the time of
certification.
---
## 2. Normative References
The following documents are indispensable for the application of
this standard. For dated references, only the edition cited applies.
For undated references, good luck.
| Reference | Title |
|----------------------|----------------------------------------------------|
| WOMM-STD-000:2025 | Definition of "It" in Software Contexts |
| WOMM-STD-002:2026 | Requirements for the Phrase "I Didn't Touch That" |
| WOMM-STD-003:2026 | Guidelines for Reproducible Shrugging |
| IEEE 404 | Standard Not Found |
| RFC 2324 | Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)|
| ISO 9001 | Quality management systems (cited for comedic contrast) |
| xkcd 1172 | Workflow (normative) |
---
## 3. Terms and Definitions
For the purposes of this standard, the following terms and
definitions apply.
### 3.1 works
The software executes without producing an error message that the
developer cannot explain. Note: errors that the developer *can*
explain (e.g., "oh that's fine, it always does that") do not
constitute failure.
### 3.2 my machine
The specific computer, virtual machine, container, or cardboard
box with blinking lights on which the developer performs their
work. "My machine" is implicitly scoped to the exact configuration
present at certification time, including but not limited to:
- Operating system and version
- Installed packages and their versions
- Environment variables (exported and forgotten)
- Browser tabs currently open
- Number of Docker containers running
- Whether Spotify is playing lo-fi beats
### 3.3 it
The software under certification. The antecedent of "it" must be
identifiable from context, project directory, or vigorous pointing
at a screen. See WOMM-STD-000.
### 3.4 compiles
The software can be transformed from source code into an executable
or interpretable form without the build tool exiting with a non-zero
status code. Warnings are not errors. Warnings have never been
errors. We do not speak of `-Werror`.
### 3.5 tests pass
All automated tests in the project's test suite complete with a
passing status. Tests that are skipped, marked as expected failures,
or commented out with `# TODO: fix this later` are considered to
have passed in the spiritual sense.
### 3.6 but did you pull main?
A ritual question posed during certification disputes. The correct
response is always "yes" regardless of whether one has, in fact,
pulled main.
### 3.7 the vibes
An intangible but critical quality metric. Software that works but
feels wrong has poor vibes and may be subject to additional scrutiny
under Section 6.
### 3.8 nondeterministic
A word used to describe test failures that only happen in CI. See
also: "cosmic rays", "timing issue", "works on my machine."
---
## 4. Certification Levels
### 4.1 General
WOMM certification is awarded at one of four levels, each
representing an increasing degree of assurance that the software
works on the certifier's machine.
### 4.2 Level Definitions
#### 4.2.1 WOMM Bronze — "It Compiles"
Requirements:
a) The project directory exists and contains at least one source
file recognisable as code
b) The source code can be parsed without syntax errors
c) The developer can point to the project and say "that's the
one" with reasonable confidence
Bronze certification represents the minimum viable claim that
software exists and is not, in fact, just a README.
#### 4.2.2 WOMM Silver — "Tests Pass"
Requirements:
a) All requirements of WOMM Bronze
b) A test suite exists within the project
c) The test suite executes and all tests pass (see definition 3.5)
d) The developer did not achieve this by deleting the failing tests
Silver certification indicates that the software does what someone,
at some point, thought it should do.
#### 4.2.3 WOMM Gold — "Production Ready*"
\*on my machine
Requirements:
a) All requirements of WOMM Silver
b) A README file exists and contains at least one true statement
about the project
c) No `TODO`, `FIXME`, or `HACK` comments remain in the codebase
(or they have been reclassified as "known architectural decisions")
d) The developer has mass-suppressed that vague feeling that
something isn't quite right
Gold certification indicates that the software meets a standard of
quality that the developer would be comfortable showing to a
colleague, provided the colleague does not look too closely.
#### 4.2.4 WOMM Platinum — "Works Everywhere*"
\*that I have tested, which is here
Requirements:
a) All requirements of WOMM Gold
b) A continuous integration configuration file is present in the
repository (e.g., `.github/workflows/`, `Jenkinsfile`,
`.gitlab-ci.yml`, `bitbucket-pipelines.yml`)
c) The git working tree is clean (no uncommitted changes)
d) The developer has mass-suppressed the even stronger vague feeling
that something isn't quite right
Platinum certification represents the highest level of assurance
available under this standard. It indicates that the developer has
not only verified local functionality but has at least *gestured*
toward the concept of reproducibility.
---
## 5. Certification Procedure
### 5.1 Pre-Certification
Before initiating the certification process, the certifier SHALL:
a) Close all unrelated terminal windows to reduce anxiety
b) Ensure the machine is in a "known good state" (defined as: the
state it's in right now)
c) Optionally mutter "okay, let's see" under their breath
### 5.2 Certification Execution
Certification SHALL be performed by executing the WOMM CLI tool
(`womm certify`) in the root directory of the project under test.
The tool will automatically evaluate all applicable requirements
and assign the highest achievable certification level.
Manual certification (i.e., just saying "it works on my machine"
without running the tool) is deprecated as of this edition but
remains in widespread use.
### 5.3 Post-Certification
Upon successful certification, the certifier SHALL:
a) Generate a certificate of compliance using `womm certificate`
b) Optionally affix the WOMM seal to the project's README
c) Lean back in their chair with quiet satisfaction
d) Not touch anything else
### 5.4 Recertification
Certification is valid until:
- Any file in the project is modified
- Any dependency is updated
- The developer runs `git pull`
- The machine is restarted
- More than 24 hours have elapsed
- Someone asks "are you sure?"
Recertification follows the same procedure as initial certification.
---
## 6. Audit Procedures
### 6.1 General
An audit may be requested by any stakeholder who has reason to
believe that the claim "it works on my machine" is unsubstantiated.
Common triggers include:
- The software does not work on the auditor's machine
- The CI pipeline is red
- A customer has reported an issue
- It's Monday
### 6.2 Audit Process
The audit SHALL proceed as follows:
a) The auditor requests the certifier demonstrate the software
working on their machine
b) The certifier navigates to the project directory, ideally while
saying "it was working five minutes ago"
c) The `womm certify` command is executed
d) Results are compared against the claimed certification level
e) If certification fails, proceed to Section 7
### 6.3 Environmental Considerations
The auditor must acknowledge that the software's behaviour may be
influenced by factors beyond the developer's control, including but
not limited to:
- The auditor's presence (observer effect)
- Solar flares
- npm
- The fact that Mercury is in retrograde
---
## 7. Non-Conformance and Appeals
### 7.1 Non-Conformance
A non-conformance occurs when the software fails to meet the
requirements of its claimed certification level during an audit.
### 7.2 Immediate Remediation Steps
Upon discovery of non-conformance, the following steps SHALL be
attempted in order:
1. Run the command again
2. Run the command again, but slower
3. Clear all caches (local, browser, DNS, emotional)
4. Run `git status` and stare at the output pensively
5. Check if the correct branch is checked out
6. Ask "did someone push something?"
7. Restart the machine
8. Restart the machine again, but with feeling
### 7.3 Appeals
If remediation is unsuccessful, the certifier may appeal by filing
a Formal Declaration of Bewilderment (Form WOMM-7B), which must
include:
- Timestamp of last known working state
- A sworn statement that "I literally didn't change anything"
- Screenshot evidence (optional but strongly recommended)
- Stack Overflow link that seems relevant but isn't
---
## 8. Marking and Labelling
### 8.1 WOMM Seal
Projects that have achieved WOMM certification MAY display the
official WOMM Seal of Approval in their documentation, README, or
office wall.
The seal SHALL include:
- The text "WOMM CERTIFIED"
- The certification level (Bronze, Silver, Gold, or Platinum)
- The date of certification
- The text "Works On My Machine" or an approved abbreviation
### 8.2 Usage Restrictions
The WOMM Seal SHALL NOT be used to imply that the software works
on any machine other than the certifier's. Misuse of the seal
constitutes a violation of WOMM-STD-001 and may result in the
offender being asked to "fix it in production, then."
---
## Appendix A (Informative): Common Excuses and Their Classification
| Excuse | Classification | Accepted? |
|--------|---------------|-----------|
| "It works on my machine" | Standard claim | Yes (with certification) |
| "I didn't change anything" | Denial | Under investigation |
| "It must be a caching issue" | Deflection | Provisionally accepted |
| "That test is flaky" | Technical excuse | Accepted if test is, in fact, flaky |
| "Works in debug mode" | Partial conformance | Bronze only |
| "The API must be down" | External attribution | Requires evidence |
| "Have you tried clearing your node_modules?" | Counter-audit | Procedurally valid |
| "It's a known issue" | Acknowledgement | Accepted if issue is, in fact, known |
| "That's not a bug, it's a feature" | Reclassification | Requires product owner sign-off |
| "I'll fix it tomorrow" | Deferral | Not accepted for certification |
| "It worked yesterday" | Temporal defence | Expired |
| "It works if you do it in the right order" | User-error claim | Gold and above only |
---
## Appendix B (Normative): Official WOMM Seal Usage Guidelines
### B.1 Minimum Seal Size
The WOMM Seal SHALL be displayed at a minimum size of 64x64 pixels
in digital media, or 20mm diameter in print. Smaller sizes risk the
seal being mistaken for a loading spinner.
### B.2 Colour Requirements
The seal SHALL be displayed in the official WOMM colour palette:
| Level | Primary Colour | Hex |
|----------|---------------|---------|
| Bronze | Copper | #B87333 |
| Silver | Silver | #C0C0C0 |
| Gold | Gold | #FFD700 |
| Platinum | Platinum | #E5E4E2 |
### B.3 Prohibited Modifications
The following modifications to the seal are prohibited:
- Adding the word "probably" before "certified"
- Replacing the checkmark with a question mark
- Displaying the seal upside-down (this indicates WOMM Decertification)
- Using the seal as a loading animation
- Tattooing the seal on any body part (this is not prohibited per se,
but the Committee questions your judgement)
---
## Appendix C (Informative): Revision History
| Version | Date | Description |
|---------|------------|-------------------------------------------------|
| 0.1 | 2025-01-15 | Initial draft, written on a napkin |
| 0.2 | 2025-06-01 | Added certification levels after heated debate |
| 0.9 | 2025-11-30 | Committee reached quorum (2 people) |
| 1.0 | 2026-04-02 | First edition published. It works on my machine. |
---
*Copyright 2026 The WOMM Standards Committee. All rights reserved,
except the right to guarantee it works on your machine.*
*END OF WOMM-STD-001:2026*

78
assets/womm-seal.svg Normal file
View File

@ -0,0 +1,78 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" width="400" height="400">
<defs>
<style>
@import url('https://fonts.googleapis.com/css2?family=EB+Garamond:wght@700&amp;display=swap');
.seal-text { font-family: 'EB Garamond', 'Georgia', serif; font-weight: 700; }
</style>
</defs>
<!-- Outer ring -->
<circle cx="200" cy="200" r="190" fill="none" stroke="#1a1a2e" stroke-width="6"/>
<circle cx="200" cy="200" r="180" fill="none" stroke="#1a1a2e" stroke-width="2"/>
<!-- Decorative dots on outer ring -->
<g fill="#1a1a2e">
<circle cx="200" cy="14" r="4"/>
<circle cx="200" cy="386" r="4"/>
<circle cx="14" cy="200" r="4"/>
<circle cx="386" cy="200" r="4"/>
<!-- Diagonal dots -->
<circle cx="68" cy="68" r="3"/>
<circle cx="332" cy="68" r="3"/>
<circle cx="68" cy="332" r="3"/>
<circle cx="332" cy="332" r="3"/>
</g>
<!-- Inner ring -->
<circle cx="200" cy="200" r="150" fill="none" stroke="#1a1a2e" stroke-width="2"/>
<circle cx="200" cy="200" r="140" fill="none" stroke="#1a1a2e" stroke-width="1"/>
<!-- Star decorations between rings -->
<g fill="#1a1a2e" class="seal-text" text-anchor="middle" font-size="16">
<text x="200" y="42">&#9733;</text>
<text x="200" y="370">&#9733;</text>
<text x="38" y="206">&#9733;</text>
<text x="362" y="206">&#9733;</text>
</g>
<!-- Circular text - top arc: "WORKS ON MY MACHINE" -->
<path id="topArc" d="M 80,200 a 120,120 0 0,1 240,0" fill="none"/>
<text class="seal-text" font-size="18" fill="#1a1a2e" letter-spacing="3">
<textPath href="#topArc" startOffset="50%" text-anchor="middle">WORKS ON MY MACHINE</textPath>
</text>
<!-- Circular text - bottom arc: "CERTIFIED" -->
<path id="bottomArc" d="M 320,200 a 120,120 0 0,1 -240,0" fill="none"/>
<text class="seal-text" font-size="18" fill="#1a1a2e" letter-spacing="5">
<textPath href="#bottomArc" startOffset="50%" text-anchor="middle">CERTIFIED</textPath>
</text>
<!-- Central content area -->
<!-- Laptop icon -->
<g transform="translate(200,170)" fill="none" stroke="#1a1a2e" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
<!-- Screen -->
<rect x="-35" y="-30" width="70" height="48" rx="4"/>
<!-- Checkmark on screen -->
<polyline points="-12,0 -2,10 16,-10" stroke-width="4" stroke="#2d6a4f"/>
<!-- Base -->
<path d="M-45,18 L-50,28 L50,28 L45,18"/>
</g>
<!-- WOMM text -->
<text x="200" y="230" class="seal-text" font-size="42" fill="#1a1a2e" text-anchor="middle" letter-spacing="6">WOMM</text>
<!-- Divider lines -->
<line x1="130" y1="242" x2="270" y2="242" stroke="#1a1a2e" stroke-width="1.5"/>
<!-- Seal of Approval text -->
<text x="200" y="262" class="seal-text" font-size="13" fill="#1a1a2e" text-anchor="middle" letter-spacing="2">SEAL OF APPROVAL</text>
<!-- Year -->
<text x="200" y="285" class="seal-text" font-size="14" fill="#1a1a2e" text-anchor="middle" letter-spacing="1">EST. 2026</text>
<!-- Small decorative elements -->
<g fill="#1a1a2e">
<circle cx="155" cy="285" r="2"/>
<circle cx="245" cy="285" r="2"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

28
pyproject.toml Normal file
View File

@ -0,0 +1,28 @@
[build-system]
requires = ["setuptools>=68.0", "setuptools-scm>=8.0"]
build-backend = "setuptools.build_meta"
[project]
name = "womm-certification"
version = "1.0.0"
description = "Works On My Machine — The Official Certification Toolkit"
readme = "README.md"
requires-python = ">=3.9"
license = "MIT"
authors = [
{ name = "The WOMM Standards Committee" },
]
dependencies = [
"click>=8.0",
"rich>=13.0",
]
[project.optional-dependencies]
png = ["cairosvg>=2.7"]
dev = ["pytest>=8.0"]
[project.scripts]
womm = "womm.cli:main"
[tool.setuptools.packages.find]
where = ["src"]

3
src/womm/__init__.py Normal file
View File

@ -0,0 +1,3 @@
"""WOMM — Works On My Machine Certification Toolkit."""
__version__ = "1.0.0"

159
src/womm/badge.py Normal file
View File

@ -0,0 +1,159 @@
"""Generate WOMM Seal of Approval badges as SVG."""
from __future__ import annotations
from datetime import date
from pathlib import Path
from womm.certify import Level
_SVG_TEMPLATE = """\
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" width="{size}" height="{size}">
<defs>
<style>
.seal-text {{ font-family: 'Georgia', 'EB Garamond', serif; font-weight: 700; }}
</style>
</defs>
<!-- Outer ring -->
<circle cx="200" cy="200" r="190" fill="none" stroke="{colour}" stroke-width="6"/>
<circle cx="200" cy="200" r="180" fill="none" stroke="{colour}" stroke-width="2"/>
<!-- Decorative dots -->
<g fill="{colour}">
<circle cx="200" cy="14" r="4"/>
<circle cx="200" cy="386" r="4"/>
<circle cx="14" cy="200" r="4"/>
<circle cx="386" cy="200" r="4"/>
<circle cx="68" cy="68" r="3"/>
<circle cx="332" cy="68" r="3"/>
<circle cx="68" cy="332" r="3"/>
<circle cx="332" cy="332" r="3"/>
</g>
<!-- Inner ring -->
<circle cx="200" cy="200" r="150" fill="none" stroke="{colour}" stroke-width="2"/>
<circle cx="200" cy="200" r="140" fill="none" stroke="{colour}" stroke-width="1"/>
<!-- Stars between rings -->
<g fill="{colour}" class="seal-text" text-anchor="middle" font-size="16">
<text x="200" y="42">&#9733;</text>
<text x="200" y="370">&#9733;</text>
<text x="38" y="206">&#9733;</text>
<text x="362" y="206">&#9733;</text>
</g>
<!-- Circular text - top: "WORKS ON MY MACHINE" -->
<path id="topArc" d="M 80,200 a 120,120 0 0,1 240,0" fill="none"/>
<text class="seal-text" font-size="18" fill="{colour}" letter-spacing="3">
<textPath href="#topArc" startOffset="50%" text-anchor="middle">WORKS ON MY MACHINE</textPath>
</text>
<!-- Circular text - bottom: "CERTIFIED" -->
<path id="bottomArc" d="M 320,200 a 120,120 0 0,1 -240,0" fill="none"/>
<text class="seal-text" font-size="18" fill="{colour}" letter-spacing="5">
<textPath href="#bottomArc" startOffset="50%" text-anchor="middle">CERTIFIED</textPath>
</text>
<!-- Laptop + checkmark icon -->
<g transform="translate(200,165)" fill="none" stroke="{colour}" stroke-width="3"
stroke-linecap="round" stroke-linejoin="round">
<rect x="-35" y="-30" width="70" height="48" rx="4"/>
<polyline points="-12,0 -2,10 16,-10" stroke-width="4" stroke="{check_colour}"/>
<path d="M-45,18 L-50,28 L50,28 L45,18"/>
</g>
<!-- WOMM -->
<text x="200" y="228" class="seal-text" font-size="42" fill="{colour}"
text-anchor="middle" letter-spacing="6">WOMM</text>
<!-- Divider -->
<line x1="120" y1="240" x2="280" y2="240" stroke="{colour}" stroke-width="1.5"/>
<!-- Level label -->
<text x="200" y="260" class="seal-text" font-size="16" fill="{colour}"
text-anchor="middle" letter-spacing="3">{level_label}</text>
<!-- Date -->
<text x="200" y="285" class="seal-text" font-size="13" fill="{colour}"
text-anchor="middle" letter-spacing="1">{date_str}</text>
<!-- Dot decorations -->
<g fill="{colour}">
<circle cx="148" cy="282" r="2"/>
<circle cx="252" cy="282" r="2"/>
</g>
</svg>
"""
_CHECK_COLOURS = {
Level.NONE: "#888888",
Level.BRONZE: "#8B5E3C",
Level.SILVER: "#2d6a4f",
Level.GOLD: "#2d6a4f",
Level.PLATINUM: "#2d6a4f",
}
def generate_badge_svg(
level: Level = Level.GOLD,
certification_date: date | None = None,
size: int = 400,
) -> str:
"""Generate an SVG string for a WOMM Seal of Approval.
Args:
level: Certification level to display.
certification_date: Date to show on the seal. Defaults to today.
size: Width and height in pixels.
Returns:
SVG markup as a string.
"""
cert_date = certification_date or date.today()
return _SVG_TEMPLATE.format(
size=size,
colour=level.colour_hex,
check_colour=_CHECK_COLOURS.get(level, "#2d6a4f"),
level_label=level.label.upper(),
date_str=cert_date.strftime("%Y-%m-%d"),
)
def save_badge(
output_path: str | Path,
level: Level = Level.GOLD,
certification_date: date | None = None,
size: int = 400,
) -> Path:
"""Generate and save a WOMM badge.
Args:
output_path: Where to write the file. If it ends in .png and
cairosvg is available, a PNG will be generated.
level: Certification level.
certification_date: Date for the seal.
size: Badge dimensions.
Returns:
The resolved output path.
"""
out = Path(output_path).resolve()
svg_content = generate_badge_svg(level, certification_date, size)
if out.suffix.lower() == ".png":
try:
import cairosvg # type: ignore[import-untyped]
cairosvg.svg2png(bytestring=svg_content.encode(), write_to=str(out))
except ImportError:
# Fall back to saving SVG with a note
svg_path = out.with_suffix(".svg")
svg_path.write_text(svg_content, encoding="utf-8")
raise SystemExit(
f"cairosvg not installed — saved SVG to {svg_path} instead.\n"
"Install with: pip install 'womm-certification[png]'"
)
else:
out.write_text(svg_content, encoding="utf-8")
return out

335
src/womm/certify.py Normal file
View File

@ -0,0 +1,335 @@
"""WOMM certification checks per WOMM-STD-001:2026."""
from __future__ import annotations
import ast
import os
import subprocess
from dataclasses import dataclass, field
from enum import IntEnum
from pathlib import Path
class Level(IntEnum):
"""WOMM certification levels (Section 4.2)."""
NONE = 0
BRONZE = 1
SILVER = 2
GOLD = 3
PLATINUM = 4
@property
def label(self) -> str:
return self.name.capitalize() if self != Level.NONE else "Uncertified"
@property
def colour_hex(self) -> str:
return {
Level.NONE: "#888888",
Level.BRONZE: "#B87333",
Level.SILVER: "#C0C0C0",
Level.GOLD: "#FFD700",
Level.PLATINUM: "#E5E4E2",
}[self]
@dataclass
class CheckResult:
"""Outcome of a single certification check."""
name: str
passed: bool
message: str
level: Level
@dataclass
class CertificationReport:
"""Full certification report for a project."""
project_path: Path
project_name: str
results: list[CheckResult] = field(default_factory=list)
@property
def level(self) -> Level:
"""Highest level for which all checks passed."""
achieved = Level.PLATINUM
for result in self.results:
if not result.passed and result.level <= achieved:
achieved = Level(result.level - 1)
return max(achieved, Level.NONE)
# ---------------------------------------------------------------------------
# Individual checks
# ---------------------------------------------------------------------------
def _check_project_exists(path: Path) -> CheckResult:
exists = path.is_dir()
return CheckResult(
name="Project directory exists",
passed=exists,
message=(
"Project directory located. We're off to a strong start."
if exists
else "Project directory not found. This is... concerning."
),
level=Level.BRONZE,
)
def _check_has_source_files(path: Path) -> CheckResult:
extensions = {".py", ".js", ".ts", ".c", ".cpp", ".go", ".rs", ".java", ".rb", ".sh"}
found = any(
f.suffix in extensions
for f in path.rglob("*")
if f.is_file() and ".git" not in f.parts
)
return CheckResult(
name="Contains source code",
passed=found,
message=(
"Source files detected. This is, in fact, a software project."
if found
else "No recognisable source files found. Are you sure this isn't just a README?"
),
level=Level.BRONZE,
)
def _check_python_syntax(path: Path) -> CheckResult:
py_files = [
f for f in path.rglob("*.py")
if f.is_file() and ".git" not in f.parts
]
if not py_files:
return CheckResult(
name="Python syntax check",
passed=True,
message="No Python files to check. Blissful ignorance achieved.",
level=Level.BRONZE,
)
errors: list[str] = []
for py_file in py_files:
try:
ast.parse(py_file.read_text(encoding="utf-8"), filename=str(py_file))
except SyntaxError as exc:
errors.append(f"{py_file.name}:{exc.lineno}: {exc.msg}")
return CheckResult(
name="Python syntax check",
passed=len(errors) == 0,
message=(
"All Python files parse cleanly. The AST smiles upon you."
if not errors
else f"Syntax errors found ({len(errors)}): {'; '.join(errors[:3])}"
),
level=Level.BRONZE,
)
def _check_tests_exist(path: Path) -> CheckResult:
test_indicators = [
path / "tests",
path / "test",
*path.rglob("test_*.py"),
*path.rglob("*_test.py"),
*path.rglob("tests.py"),
]
found = any(p.exists() for p in test_indicators)
return CheckResult(
name="Test suite exists",
passed=found,
message=(
"Test suite located. Someone here believes in accountability."
if found
else "No test suite found. Bold strategy."
),
level=Level.SILVER,
)
def _check_tests_pass(path: Path) -> CheckResult:
# Try pytest, then unittest
for cmd in (["python", "-m", "pytest", "-x", "-q"], ["python", "-m", "unittest", "discover", "-s", "."]):
try:
result = subprocess.run(
cmd,
cwd=path,
capture_output=True,
text=True,
timeout=120,
)
if result.returncode == 0:
return CheckResult(
name="Tests pass",
passed=True,
message="All tests pass. On this machine, at least.",
level=Level.SILVER,
)
elif result.returncode == 5 and "pytest" in cmd[2]:
# pytest exit code 5 = no tests collected
continue
else:
snippet = (result.stdout + result.stderr).strip().split("\n")[-1]
return CheckResult(
name="Tests pass",
passed=False,
message=f"Tests failed. {snippet}",
level=Level.SILVER,
)
except FileNotFoundError:
continue
except subprocess.TimeoutExpired:
return CheckResult(
name="Tests pass",
passed=False,
message="Tests timed out after 120s. The machine grew weary.",
level=Level.SILVER,
)
return CheckResult(
name="Tests pass",
passed=False,
message="Could not find a test runner. Neither pytest nor unittest obliged.",
level=Level.SILVER,
)
def _check_readme_exists(path: Path) -> CheckResult:
readmes = [path / name for name in ("README.md", "README.rst", "README.txt", "README")]
found = any(r.is_file() for r in readmes)
return CheckResult(
name="README exists",
passed=found,
message=(
"README found. Documentation: the thought that counts."
if found
else "No README. Future you will regret this."
),
level=Level.GOLD,
)
def _check_no_todo_comments(path: Path) -> CheckResult:
markers = ("TODO", "FIXME", "HACK", "XXX")
offenders: list[str] = []
for f in path.rglob("*"):
if not f.is_file() or ".git" in f.parts or f.suffix not in (
".py", ".js", ".ts", ".c", ".cpp", ".go", ".rs", ".java", ".rb",
):
continue
try:
for i, line in enumerate(f.read_text(encoding="utf-8", errors="ignore").splitlines(), 1):
if any(m in line for m in markers):
offenders.append(f"{f.name}:{i}")
if len(offenders) >= 5:
break
except (OSError, UnicodeDecodeError):
continue
if len(offenders) >= 5:
break
return CheckResult(
name="No TODO/FIXME/HACK comments",
passed=len(offenders) == 0,
message=(
"No shameful markers found. Either you're thorough, or you're sneaky."
if not offenders
else f"Found markers in: {', '.join(offenders)}. The guilt is documented."
),
level=Level.GOLD,
)
def _check_ci_config_exists(path: Path) -> CheckResult:
ci_paths = [
path / ".github" / "workflows",
path / ".gitlab-ci.yml",
path / "Jenkinsfile",
path / ".circleci",
path / "bitbucket-pipelines.yml",
path / ".travis.yml",
path / "azure-pipelines.yml",
]
found = any(p.exists() for p in ci_paths)
return CheckResult(
name="CI configuration exists",
passed=found,
message=(
"CI config detected. You've at least gestured toward reproducibility."
if found
else "No CI configuration found. You are the CI."
),
level=Level.PLATINUM,
)
def _check_git_clean(path: Path) -> CheckResult:
try:
result = subprocess.run(
["git", "status", "--porcelain"],
cwd=path,
capture_output=True,
text=True,
timeout=10,
)
clean = result.returncode == 0 and result.stdout.strip() == ""
return CheckResult(
name="Git working tree is clean",
passed=clean,
message=(
"Working tree is clean. Pristine. Untouched. (For now.)"
if clean
else "Uncommitted changes detected. Living dangerously."
),
level=Level.PLATINUM,
)
except (FileNotFoundError, subprocess.TimeoutExpired):
return CheckResult(
name="Git working tree is clean",
passed=False,
message="Git not available or not a git repository. The void stares back.",
level=Level.PLATINUM,
)
# ---------------------------------------------------------------------------
# Main certification entry point
# ---------------------------------------------------------------------------
ALL_CHECKS = [
_check_project_exists,
_check_has_source_files,
_check_python_syntax,
_check_tests_exist,
_check_tests_pass,
_check_readme_exists,
_check_no_todo_comments,
_check_ci_config_exists,
_check_git_clean,
]
def certify(path: str | Path | None = None, target_level: Level | None = None) -> CertificationReport:
"""Run WOMM certification checks against a project directory.
Args:
path: Project root directory. Defaults to cwd.
target_level: If set, only run checks up to this level.
Returns:
A CertificationReport with all check results.
"""
project_path = Path(path or os.getcwd()).resolve()
report = CertificationReport(
project_path=project_path,
project_name=project_path.name,
)
for check_fn in ALL_CHECKS:
result = check_fn(project_path)
report.results.append(result)
if target_level is not None and result.level > target_level:
break
return report

172
src/womm/cli.py Normal file
View File

@ -0,0 +1,172 @@
"""WOMM CLI — Works On My Machine Certification Toolkit."""
from __future__ import annotations
from pathlib import Path
import click
from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.text import Text
from womm.certify import Level, certify
from womm.badge import save_badge
from womm.document import generate_certificate, save_certificate
console = Console()
LEVEL_STYLES = {
Level.NONE: "dim",
Level.BRONZE: "rgb(184,115,51)",
Level.SILVER: "grey78",
Level.GOLD: "yellow",
Level.PLATINUM: "white",
}
LEVEL_EMOJI = {
Level.NONE: " ",
Level.BRONZE: " ",
Level.SILVER: " ",
Level.GOLD: " ",
Level.PLATINUM: " ",
}
def _level_choice(value: str) -> Level | None:
if value is None:
return None
try:
return Level[value.upper()]
except KeyError:
raise click.BadParameter(f"Unknown level: {value}. Choose from: bronze, silver, gold, platinum")
@click.group()
@click.version_option(package_name="womm-certification")
def main() -> None:
"""WOMM -- Works On My Machine Certification Toolkit.
The official tool for certifying that software works on your machine,
in accordance with WOMM-STD-001:2026.
"""
@main.command()
@click.argument("path", default=".", type=click.Path(exists=True))
@click.option("--level", "target_level", default=None, help="Target certification level (bronze/silver/gold/platinum).")
def certify_cmd(path: str, target_level: str | None) -> None:
"""Run WOMM certification checks against a project."""
level = _level_choice(target_level) if target_level else None
report = certify(path, target_level=level)
# Header
console.print()
console.print(
Panel(
"[bold]WOMM-STD-001:2026[/bold]\nWorks On My Machine — Certification Report",
border_style="blue",
expand=False,
)
)
console.print(f" Project: [bold]{report.project_name}[/bold]")
console.print(f" Path: {report.project_path}")
console.print()
# Results table
table = Table(show_header=True, header_style="bold", expand=True)
table.add_column("Level", width=10)
table.add_column("Check", width=35)
table.add_column("Result", width=6)
table.add_column("Detail")
for result in report.results:
style = LEVEL_STYLES.get(result.level, "")
status = Text("PASS", style="bold green") if result.passed else Text("FAIL", style="bold red")
table.add_row(
result.level.label,
result.name,
status,
result.message,
style=style if not result.passed else "",
)
console.print(table)
console.print()
# Final verdict
achieved = report.level
style = LEVEL_STYLES.get(achieved, "bold")
emoji = LEVEL_EMOJI.get(achieved, "")
if achieved == Level.NONE:
console.print(
Panel(
"[bold red]CERTIFICATION FAILED[/bold red]\n\n"
"The software does not meet the minimum requirements of\n"
"WOMM-STD-001:2026. Please address the above findings\n"
"and try again. Or don't. We're not your boss.",
border_style="red",
expand=False,
)
)
else:
console.print(
Panel(
f"[bold {style}]{emoji}WOMM {achieved.label.upper()} CERTIFIED{emoji}[/bold {style}]\n\n"
f"This project has been certified to WOMM {achieved.label} level\n"
"in accordance with WOMM-STD-001:2026.\n\n"
"[dim]This certification is valid on this machine only.\n"
"Void if anyone asks 'are you sure?'[/dim]",
border_style=style,
expand=False,
)
)
console.print()
@main.command()
@click.option("--level", default="gold", help="Certification level (bronze/silver/gold/platinum).")
@click.option("--output", "-o", default="womm-seal.svg", help="Output file path (.svg or .png).")
@click.option("--size", default=400, type=int, help="Badge size in pixels.")
def badge(level: str, output: str, size: int) -> None:
"""Generate a WOMM Seal of Approval badge."""
cert_level = _level_choice(level)
if cert_level is None or cert_level == Level.NONE:
raise click.BadParameter("Level must be bronze, silver, gold, or platinum.")
try:
out_path = save_badge(output, level=cert_level, size=size)
console.print(f"[green]Badge saved to:[/green] {out_path}")
except SystemExit as exc:
console.print(f"[yellow]{exc}[/yellow]")
@main.command()
@click.argument("path", default=".", type=click.Path(exists=True))
@click.option("--output", "-o", default=None, help="Save certificate to file (default: print to stdout).")
def certificate(path: str, output: str | None) -> None:
"""Generate a formal WOMM certificate of compliance."""
report = certify(path)
if output:
out_path = save_certificate(report, output)
console.print(f"[green]Certificate saved to:[/green] {out_path}")
else:
console.print(generate_certificate(report))
@main.command()
def standard() -> None:
"""Print the full WOMM-STD-001:2026 standard."""
standard_path = Path(__file__).resolve().parent.parent.parent / "WOMM-STANDARD-001.md"
if standard_path.is_file():
console.print(standard_path.read_text(encoding="utf-8"))
else:
console.print("[yellow]Standard document not found.[/yellow]")
console.print("Expected at: " + str(standard_path))
# Register 'certify' as the command name (avoiding clash with the function import)
main.add_command(certify_cmd, name="certify")

154
src/womm/document.py Normal file
View File

@ -0,0 +1,154 @@
"""Generate formal WOMM certification documents."""
from __future__ import annotations
import getpass
import platform
import textwrap
from datetime import datetime
from pathlib import Path
from womm.certify import CertificationReport, Level
def generate_certificate(report: CertificationReport) -> str:
"""Generate a formal markdown certificate from a certification report.
Args:
report: A completed CertificationReport.
Returns:
Markdown-formatted certificate document.
"""
now = datetime.now()
hostname = platform.node() or "UNKNOWN-HOST"
username = getpass.getuser()
level = report.level
# Build check results table
check_rows = []
for r in report.results:
status = "PASS" if r.passed else "FAIL"
check_rows.append(f"| {r.name:<40} | {status:<6} | {r.message} |")
checks_table = "\n".join(check_rows)
certificate = textwrap.dedent(f"""\
================================================================
WOMM CERTIFICATE OF COMPLIANCE
WOMM-STD-001:2026
================================================================
Certificate Number: WOMM-{now.strftime('%Y%m%d%H%M%S')}-{abs(hash(report.project_name)) % 10000:04d}
Date of Issuance: {now.strftime('%Y-%m-%d %H:%M:%S')}
Standard: WOMM-STD-001:2026, First Edition
----------------------------------------------------------------
PROJECT INFORMATION
----------------------------------------------------------------
Project Name: {report.project_name}
Project Path: {report.project_path}
Certification Level: {level.label.upper()} ({_level_tagline(level)})
----------------------------------------------------------------
CERTIFICATION AUTHORITY
----------------------------------------------------------------
Certifying Machine: {hostname}
Certifying User: {username}
Operating System: {platform.system()} {platform.release()}
Python Version: {platform.python_version()}
This certification was performed on the above machine and is
valid exclusively for this machine in its current configuration,
including all running processes, environment variables, and the
certifier's current emotional state.
----------------------------------------------------------------
AUDIT TRAIL
----------------------------------------------------------------
| {"Check":<40} | {"Result":<6} | Detail |
|{"-" * 42}|{"-" * 8}|--------|
{checks_table}
----------------------------------------------------------------
DECLARATION
----------------------------------------------------------------
I, {username}@{hostname}, do hereby certify that the software
project "{report.project_name}" has been evaluated in accordance
with WOMM-STD-001:2026 and has achieved:
*** WOMM {level.label.upper()} CERTIFICATION ***
This certification is granted under the following conditions:
1. The software was observed to work on my machine.
2. No guarantee is made regarding any other machine.
3. This certificate is void if anyone asks "are you sure?"
4. Validity expires upon the next git pull, dependency update,
or passage of more than 24 hours.
----------------------------------------------------------------
SIGNATURES
----------------------------------------------------------------
Certified by:
___________________________
{username}
{hostname}
{now.strftime('%Y-%m-%d')}
Witnessed by:
___________________________
/dev/null
(The Void)
Approved by the WOMM Standards Committee:
___________________________
The Committee
(Quorum: 1)
================================================================
This document was generated in compliance with WOMM-STD-001:2026
"Works On My Machine" Certification Standard
First Edition, 2026-04-02
Copyright 2026 The WOMM Standards Committee.
All rights reserved, except the right to guarantee
it works on your machine.
================================================================
""")
return certificate
def _level_tagline(level: Level) -> str:
return {
Level.NONE: "Not Certified",
Level.BRONZE: "It Compiles",
Level.SILVER: "Tests Pass",
Level.GOLD: "Production Ready*",
Level.PLATINUM: "Works Everywhere*",
}.get(level, "Unknown")
def save_certificate(report: CertificationReport, output_path: str | Path) -> Path:
"""Generate and save a certificate to a file.
Args:
report: A completed CertificationReport.
output_path: File path to write the certificate.
Returns:
The resolved output path.
"""
out = Path(output_path).resolve()
out.write_text(generate_certificate(report), encoding="utf-8")
return out

View File

@ -0,0 +1,79 @@
Metadata-Version: 2.4
Name: womm-certification
Version: 1.0.0
Summary: Works On My Machine — The Official Certification Toolkit
Author: The WOMM Standards Committee
License-Expression: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: click>=8.0
Requires-Dist: rich>=13.0
Provides-Extra: png
Requires-Dist: cairosvg>=2.7; extra == "png"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
# WOMM Certification Toolkit
**Works On My Machine -- The Official Certification Standard**
A formal certification framework for the age-old claim "it works on my machine," complete with a bureaucratic standards document, an official seal of approval, and a CLI tool to certify your projects.
## Installation
```bash
pip install -e .
```
For PNG badge export support:
```bash
pip install -e '.[png]'
```
## Usage
### Certify a project
```bash
womm certify # certify current directory
womm certify /path/to/project
womm certify --level gold # target a specific level
```
### Generate a badge
```bash
womm badge # default: gold, womm-seal.svg
womm badge --level platinum -o seal.svg
```
### Generate a certificate
```bash
womm certificate # print to stdout
womm certificate -o cert.txt # save to file
```
### Read the standard
```bash
womm standard
```
## Certification Levels
| Level | Requirements |
|----------|-------------|
| Bronze | Project exists, has source files, no syntax errors |
| Silver | Bronze + tests exist and pass |
| Gold | Silver + README exists, no TODO/FIXME/HACK comments |
| Platinum | Gold + CI config present, git tree is clean |
## The Standard
See [WOMM-STD-001:2026](WOMM-STANDARD-001.md) for the full certification standard.
## License
MIT

View File

@ -0,0 +1,14 @@
README.md
pyproject.toml
src/womm/__init__.py
src/womm/badge.py
src/womm/certify.py
src/womm/cli.py
src/womm/document.py
src/womm_certification.egg-info/PKG-INFO
src/womm_certification.egg-info/SOURCES.txt
src/womm_certification.egg-info/dependency_links.txt
src/womm_certification.egg-info/entry_points.txt
src/womm_certification.egg-info/requires.txt
src/womm_certification.egg-info/top_level.txt
tests/test_certify.py

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,2 @@
[console_scripts]
womm = womm.cli:main

View File

@ -0,0 +1,8 @@
click>=8.0
rich>=13.0
[dev]
pytest>=8.0
[png]
cairosvg>=2.7

View File

@ -0,0 +1 @@
womm

0
tests/__init__.py Normal file
View File

153
tests/test_certify.py Normal file
View File

@ -0,0 +1,153 @@
"""Tests for WOMM certification checks."""
from __future__ import annotations
from pathlib import Path
import pytest
from womm.certify import (
CertificationReport,
Level,
certify,
_check_has_source_files,
_check_project_exists,
_check_python_syntax,
_check_readme_exists,
_check_no_todo_comments,
)
@pytest.fixture()
def empty_project(tmp_path: Path) -> Path:
"""An empty project directory."""
return tmp_path
@pytest.fixture()
def bronze_project(tmp_path: Path) -> Path:
"""A project that should achieve Bronze certification."""
(tmp_path / "main.py").write_text("print('hello')\n")
return tmp_path
@pytest.fixture()
def silver_project(tmp_path: Path) -> Path:
"""A project that should achieve at least Silver."""
(tmp_path / "main.py").write_text("def add(a, b):\n return a + b\n")
tests_dir = tmp_path / "tests"
tests_dir.mkdir()
(tests_dir / "__init__.py").write_text("")
(tests_dir / "test_main.py").write_text(
"from pathlib import Path\nimport sys\n"
"sys.path.insert(0, str(Path(__file__).parent.parent))\n"
"from main import add\n\n"
"def test_add():\n assert add(1, 2) == 3\n"
)
return tmp_path
class TestLevel:
def test_level_ordering(self) -> None:
assert Level.BRONZE < Level.SILVER < Level.GOLD < Level.PLATINUM
def test_label(self) -> None:
assert Level.GOLD.label == "Gold"
assert Level.NONE.label == "Uncertified"
def test_colour_hex(self) -> None:
assert Level.GOLD.colour_hex == "#FFD700"
class TestIndividualChecks:
def test_project_exists_pass(self, tmp_path: Path) -> None:
result = _check_project_exists(tmp_path)
assert result.passed
def test_project_exists_fail(self, tmp_path: Path) -> None:
result = _check_project_exists(tmp_path / "nonexistent")
assert not result.passed
def test_has_source_files_pass(self, bronze_project: Path) -> None:
result = _check_has_source_files(bronze_project)
assert result.passed
def test_has_source_files_fail(self, empty_project: Path) -> None:
result = _check_has_source_files(empty_project)
assert not result.passed
def test_python_syntax_pass(self, bronze_project: Path) -> None:
result = _check_python_syntax(bronze_project)
assert result.passed
def test_python_syntax_fail(self, tmp_path: Path) -> None:
(tmp_path / "bad.py").write_text("def oops(\n")
result = _check_python_syntax(tmp_path)
assert not result.passed
def test_readme_exists_pass(self, tmp_path: Path) -> None:
(tmp_path / "README.md").write_text("# Hello\n")
result = _check_readme_exists(tmp_path)
assert result.passed
def test_readme_exists_fail(self, empty_project: Path) -> None:
result = _check_readme_exists(empty_project)
assert not result.passed
def test_no_todos_pass(self, bronze_project: Path) -> None:
result = _check_no_todo_comments(bronze_project)
assert result.passed
def test_no_todos_fail(self, tmp_path: Path) -> None:
(tmp_path / "main.py").write_text("# TODO: fix this\n")
result = _check_no_todo_comments(tmp_path)
assert not result.passed
class TestCertify:
def test_empty_project_gets_none(self, empty_project: Path) -> None:
report = certify(empty_project)
# Empty dir exists but has no source files
assert report.level == Level.NONE
def test_bronze_project(self, bronze_project: Path) -> None:
report = certify(bronze_project, target_level=Level.BRONZE)
assert report.level >= Level.BRONZE
def test_report_has_results(self, bronze_project: Path) -> None:
report = certify(bronze_project)
assert len(report.results) > 0
assert all(r.name and r.message for r in report.results)
def test_target_level_limits_checks(self, bronze_project: Path) -> None:
report = certify(bronze_project, target_level=Level.BRONZE)
levels_checked = {r.level for r in report.results}
assert Level.PLATINUM not in levels_checked
class TestCertificationReport:
def test_level_all_pass(self) -> None:
from womm.certify import CheckResult
report = CertificationReport(
project_path=Path("/tmp/test"),
project_name="test",
results=[
CheckResult("check1", True, "ok", Level.BRONZE),
CheckResult("check2", True, "ok", Level.SILVER),
],
)
assert report.level >= Level.SILVER
def test_level_with_failure(self) -> None:
from womm.certify import CheckResult
report = CertificationReport(
project_path=Path("/tmp/test"),
project_name="test",
results=[
CheckResult("check1", True, "ok", Level.BRONZE),
CheckResult("check2", False, "nope", Level.SILVER),
],
)
assert report.level == Level.BRONZE