utopia-analyzer 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. utopia_analyzer-1.0.0/LICENSE +21 -0
  2. utopia_analyzer-1.0.0/PKG-INFO +194 -0
  3. utopia_analyzer-1.0.0/README.md +151 -0
  4. utopia_analyzer-1.0.0/pyproject.toml +35 -0
  5. utopia_analyzer-1.0.0/setup.cfg +4 -0
  6. utopia_analyzer-1.0.0/tests/test_archetypes.py +58 -0
  7. utopia_analyzer-1.0.0/tests/test_formatters.py +122 -0
  8. utopia_analyzer-1.0.0/tests/test_github_client.py +258 -0
  9. utopia_analyzer-1.0.0/tests/test_improvement_plan.py +93 -0
  10. utopia_analyzer-1.0.0/tests/test_recruiter.py +129 -0
  11. utopia_analyzer-1.0.0/tests/test_report.py +94 -0
  12. utopia_analyzer-1.0.0/tests/test_roast.py +102 -0
  13. utopia_analyzer-1.0.0/tests/test_scoring.py +109 -0
  14. utopia_analyzer-1.0.0/utopia/__init__.py +3 -0
  15. utopia_analyzer-1.0.0/utopia/__main__.py +6 -0
  16. utopia_analyzer-1.0.0/utopia/archetypes.py +168 -0
  17. utopia_analyzer-1.0.0/utopia/cli.py +107 -0
  18. utopia_analyzer-1.0.0/utopia/formatters/__init__.py +1 -0
  19. utopia_analyzer-1.0.0/utopia/formatters/json_output.py +50 -0
  20. utopia_analyzer-1.0.0/utopia/formatters/markdown_output.py +96 -0
  21. utopia_analyzer-1.0.0/utopia/formatters/terminal.py +130 -0
  22. utopia_analyzer-1.0.0/utopia/github_client.py +517 -0
  23. utopia_analyzer-1.0.0/utopia/improvement_plan.py +120 -0
  24. utopia_analyzer-1.0.0/utopia/recruiter.py +221 -0
  25. utopia_analyzer-1.0.0/utopia/report.py +76 -0
  26. utopia_analyzer-1.0.0/utopia/roast.py +121 -0
  27. utopia_analyzer-1.0.0/utopia/scoring.py +377 -0
  28. utopia_analyzer-1.0.0/utopia_analyzer.egg-info/PKG-INFO +194 -0
  29. utopia_analyzer-1.0.0/utopia_analyzer.egg-info/SOURCES.txt +31 -0
  30. utopia_analyzer-1.0.0/utopia_analyzer.egg-info/dependency_links.txt +1 -0
  31. utopia_analyzer-1.0.0/utopia_analyzer.egg-info/entry_points.txt +2 -0
  32. utopia_analyzer-1.0.0/utopia_analyzer.egg-info/requires.txt +4 -0
  33. utopia_analyzer-1.0.0/utopia_analyzer.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Khizar Arain
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,194 @@
1
+ Metadata-Version: 2.4
2
+ Name: utopia-analyzer
3
+ Version: 1.0.0
4
+ Summary: Transforms any GitHub profile into a professional developer intelligence report
5
+ Author-email: Khizer Arain <your@email.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2024 Khizar Arain
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/khizerarain/utopia
29
+ Project-URL: Repository, https://github.com/khizerarain/utopia
30
+ Keywords: github,portfolio,cli,developer-tools,analytics
31
+ Classifier: Programming Language :: Python :: 3
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Classifier: Operating System :: OS Independent
34
+ Classifier: Environment :: Console
35
+ Requires-Python: >=3.10
36
+ Description-Content-Type: text/markdown
37
+ License-File: LICENSE
38
+ Requires-Dist: click>=8.0
39
+ Requires-Dist: rich>=13.0
40
+ Requires-Dist: requests>=2.28
41
+ Requires-Dist: python-dotenv>=1.0
42
+ Dynamic: license-file
43
+
44
+ # UTOPIA
45
+
46
+ > Analyze any GitHub profile and generate a professional developer portfolio report with scoring, archetypes, and recruiter insights.
47
+
48
+ **UTOPIA** (Ultimate Technical Overview & Portfolio Intelligence Analyzer) is a Python CLI tool that transforms any public GitHub profile into a detailed intelligence report. It scores the profile across six weighted categories, detects the developer's archetype, simulates an AI recruiter verdict, breaks down the tech stack, roasts bad habits (if asked nicely), and generates a 30-day improvement plan.
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ pip install utopia-cli
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ```bash
59
+ utopia khizerarain
60
+ utopia khizerarain --roast
61
+ utopia khizerarain --output markdown --save report.md
62
+ utopia khizerarain --token YOUR_GITHUB_TOKEN
63
+ ```
64
+
65
+ ## Publishing to PyPI (for maintainers)
66
+
67
+ ```bash
68
+ pip install build twine
69
+ python -m build
70
+ twine upload dist/*
71
+ ```
72
+
73
+ ## Built With
74
+
75
+ - [Python](https://www.python.org/) — core language
76
+ - [Click](https://click.palletsprojects.com/) — CLI framework
77
+ - [Rich](https://rich.readthedocs.io/) — terminal formatting and charts
78
+
79
+ ## Development Installation
80
+
81
+ 1. Clone the repository:
82
+
83
+ ```bash
84
+ git clone https://github.com/khizerarain/utopia.git
85
+ cd utopia
86
+ ```
87
+
88
+ 2. Install dependencies:
89
+
90
+ ```bash
91
+ pip install -r requirements.txt
92
+ ```
93
+
94
+ ## Development Usage
95
+
96
+ ```bash
97
+ # Basic terminal report
98
+ python -m utopia.cli torvalds
99
+
100
+ # Use a GitHub token for higher rate limits
101
+ python -m utopia.cli torvalds --token ghp_xxxxxxxx
102
+
103
+ # Roast mode
104
+ python -m utopia.cli torvalds --roast
105
+
106
+ # Save as JSON
107
+ python -m utopia.cli torvalds --output json --save report.json
108
+
109
+ # Save as Markdown
110
+ python -m utopia.cli torvalds --output markdown --save report.md
111
+
112
+ # Disable colors
113
+ python -m utopia.cli torvalds --no-color
114
+
115
+ # Refresh cached data
116
+ python -m utopia.cli torvalds --no-cache
117
+ ```
118
+
119
+ ## Sample Output
120
+
121
+ ```
122
+ ┌───────────────────────────────────┐
123
+ │ UTOPIA Portfolio Report: torvalds │
124
+ │ UTOPIA SCORE: 80/100 │
125
+ │ Portfolio Grade: B- │
126
+ └───────────────────────────────────┘
127
+
128
+ Project Quality │ 23/25 │ ████████████████████████████░░ 92%
129
+ Activity │ 20/20 │ ██████████████████████████████ 98%
130
+ Documentation │ 11/15 │ ██████████████████████░░░░░░░░ 72%
131
+ Tech Diversity │ 2/15 │ ████░░░░░░░░░░░░░░░░░░░░░░░░░░ 13%
132
+ Impact │ 15/15 │ ██████████████████████████████ 100%
133
+ Open Source │ 10/10 │ ████████████████████████████░░ 95%
134
+
135
+ You are:
136
+ Backend Engineer ██████████████░░░░░░ 70.0%
137
+ DevOps Engineer ██████████████░░░░░░ 70.0%
138
+ AI/ML Developer ██████████░░░░░░░░░░ 50.0%
139
+ Data Engineer ██████████░░░░░░░░░░ 50.0%
140
+
141
+ Would I hire this developer?
142
+ YES
143
+
144
+ Reasons:
145
+ ✓ Projects show ongoing maintenance
146
+ ✓ Projects are well explained
147
+ ✓ Repositories show solid engineering
148
+ ✓ Includes automated tests
149
+
150
+ Strengths:
151
+ ✓ Strong community impact
152
+ ✓ Active development history
153
+ ✓ Active open-source contributor
154
+
155
+ Weaknesses:
156
+ ✗ Tech stack is narrow
157
+ ✗ Needs more README documentation
158
+ ✗ Project quality could improve
159
+
160
+ Tech Stack Breakdown
161
+ C ████████████████████ 97.7%
162
+ Assembly ░░░░░░░░░░░░░░░░░░░░ 0.7%
163
+ Shell ░░░░░░░░░░░░░░░░░░░░ 0.4%
164
+ Rust ░░░░░░░░░░░░░░░░░░░░ 0.3%
165
+ Other ░░░░░░░░░░░░░░░░░░░░ 0.9%
166
+
167
+ 30-Day Upgrade Plan
168
+ Week 1:
169
+ • Contribute to an open-source project outside your main stack
170
+ Week 2:
171
+ • Improve README files across your top repos
172
+ Week 3:
173
+ • Refactor your most-starred project and add missing features
174
+ Week 4:
175
+ • Review and merge community PRs in your own repos
176
+ ```
177
+
178
+ ## GitHub Token
179
+
180
+ GitHub's unauthenticated API limit is 60 requests per hour. For full analysis, create a Personal Access Token:
181
+
182
+ 1. Go to **Settings → Developer settings → Personal access tokens → Tokens (classic)**
183
+ 2. Generate a new token with `public_repo` scope
184
+ 3. Use `--token <PAT>` or set `GITHUB_TOKEN` in a `.env` file
185
+
186
+ ## Running Tests
187
+
188
+ ```bash
189
+ python -m pytest tests/ -v
190
+ ```
191
+
192
+ ## License
193
+
194
+ MIT
@@ -0,0 +1,151 @@
1
+ # UTOPIA
2
+
3
+ > Analyze any GitHub profile and generate a professional developer portfolio report with scoring, archetypes, and recruiter insights.
4
+
5
+ **UTOPIA** (Ultimate Technical Overview & Portfolio Intelligence Analyzer) is a Python CLI tool that transforms any public GitHub profile into a detailed intelligence report. It scores the profile across six weighted categories, detects the developer's archetype, simulates an AI recruiter verdict, breaks down the tech stack, roasts bad habits (if asked nicely), and generates a 30-day improvement plan.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install utopia-cli
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```bash
16
+ utopia khizerarain
17
+ utopia khizerarain --roast
18
+ utopia khizerarain --output markdown --save report.md
19
+ utopia khizerarain --token YOUR_GITHUB_TOKEN
20
+ ```
21
+
22
+ ## Publishing to PyPI (for maintainers)
23
+
24
+ ```bash
25
+ pip install build twine
26
+ python -m build
27
+ twine upload dist/*
28
+ ```
29
+
30
+ ## Built With
31
+
32
+ - [Python](https://www.python.org/) — core language
33
+ - [Click](https://click.palletsprojects.com/) — CLI framework
34
+ - [Rich](https://rich.readthedocs.io/) — terminal formatting and charts
35
+
36
+ ## Development Installation
37
+
38
+ 1. Clone the repository:
39
+
40
+ ```bash
41
+ git clone https://github.com/khizerarain/utopia.git
42
+ cd utopia
43
+ ```
44
+
45
+ 2. Install dependencies:
46
+
47
+ ```bash
48
+ pip install -r requirements.txt
49
+ ```
50
+
51
+ ## Development Usage
52
+
53
+ ```bash
54
+ # Basic terminal report
55
+ python -m utopia.cli torvalds
56
+
57
+ # Use a GitHub token for higher rate limits
58
+ python -m utopia.cli torvalds --token ghp_xxxxxxxx
59
+
60
+ # Roast mode
61
+ python -m utopia.cli torvalds --roast
62
+
63
+ # Save as JSON
64
+ python -m utopia.cli torvalds --output json --save report.json
65
+
66
+ # Save as Markdown
67
+ python -m utopia.cli torvalds --output markdown --save report.md
68
+
69
+ # Disable colors
70
+ python -m utopia.cli torvalds --no-color
71
+
72
+ # Refresh cached data
73
+ python -m utopia.cli torvalds --no-cache
74
+ ```
75
+
76
+ ## Sample Output
77
+
78
+ ```
79
+ ┌───────────────────────────────────┐
80
+ │ UTOPIA Portfolio Report: torvalds │
81
+ │ UTOPIA SCORE: 80/100 │
82
+ │ Portfolio Grade: B- │
83
+ └───────────────────────────────────┘
84
+
85
+ Project Quality │ 23/25 │ ████████████████████████████░░ 92%
86
+ Activity │ 20/20 │ ██████████████████████████████ 98%
87
+ Documentation │ 11/15 │ ██████████████████████░░░░░░░░ 72%
88
+ Tech Diversity │ 2/15 │ ████░░░░░░░░░░░░░░░░░░░░░░░░░░ 13%
89
+ Impact │ 15/15 │ ██████████████████████████████ 100%
90
+ Open Source │ 10/10 │ ████████████████████████████░░ 95%
91
+
92
+ You are:
93
+ Backend Engineer ██████████████░░░░░░ 70.0%
94
+ DevOps Engineer ██████████████░░░░░░ 70.0%
95
+ AI/ML Developer ██████████░░░░░░░░░░ 50.0%
96
+ Data Engineer ██████████░░░░░░░░░░ 50.0%
97
+
98
+ Would I hire this developer?
99
+ YES
100
+
101
+ Reasons:
102
+ ✓ Projects show ongoing maintenance
103
+ ✓ Projects are well explained
104
+ ✓ Repositories show solid engineering
105
+ ✓ Includes automated tests
106
+
107
+ Strengths:
108
+ ✓ Strong community impact
109
+ ✓ Active development history
110
+ ✓ Active open-source contributor
111
+
112
+ Weaknesses:
113
+ ✗ Tech stack is narrow
114
+ ✗ Needs more README documentation
115
+ ✗ Project quality could improve
116
+
117
+ Tech Stack Breakdown
118
+ C ████████████████████ 97.7%
119
+ Assembly ░░░░░░░░░░░░░░░░░░░░ 0.7%
120
+ Shell ░░░░░░░░░░░░░░░░░░░░ 0.4%
121
+ Rust ░░░░░░░░░░░░░░░░░░░░ 0.3%
122
+ Other ░░░░░░░░░░░░░░░░░░░░ 0.9%
123
+
124
+ 30-Day Upgrade Plan
125
+ Week 1:
126
+ • Contribute to an open-source project outside your main stack
127
+ Week 2:
128
+ • Improve README files across your top repos
129
+ Week 3:
130
+ • Refactor your most-starred project and add missing features
131
+ Week 4:
132
+ • Review and merge community PRs in your own repos
133
+ ```
134
+
135
+ ## GitHub Token
136
+
137
+ GitHub's unauthenticated API limit is 60 requests per hour. For full analysis, create a Personal Access Token:
138
+
139
+ 1. Go to **Settings → Developer settings → Personal access tokens → Tokens (classic)**
140
+ 2. Generate a new token with `public_repo` scope
141
+ 3. Use `--token <PAT>` or set `GITHUB_TOKEN` in a `.env` file
142
+
143
+ ## Running Tests
144
+
145
+ ```bash
146
+ python -m pytest tests/ -v
147
+ ```
148
+
149
+ ## License
150
+
151
+ MIT
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "utopia-analyzer"
7
+ version = "1.0.0"
8
+ description = "Transforms any GitHub profile into a professional developer intelligence report"
9
+ readme = "README.md"
10
+ license = { file = "LICENSE" }
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "Khizer Arain", email = "your@email.com" }]
13
+ keywords = ["github", "portfolio", "cli", "developer-tools", "analytics"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ "Environment :: Console",
19
+ ]
20
+ dependencies = [
21
+ "click>=8.0",
22
+ "rich>=13.0",
23
+ "requests>=2.28",
24
+ "python-dotenv>=1.0",
25
+ ]
26
+
27
+ [project.scripts]
28
+ utopia = "utopia.cli:main"
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/khizerarain/utopia"
32
+ Repository = "https://github.com/khizerarain/utopia"
33
+
34
+ [tool.setuptools.packages.find]
35
+ include = ["utopia*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,58 @@
1
+ """Tests for the archetype detection module."""
2
+
3
+ from utopia.archetypes import detect_archetypes
4
+ from utopia.github_client import ProfileData, RepoData
5
+ from tests.test_scoring import make_profile, make_repo
6
+
7
+
8
+ def test_backend_archetype_detected():
9
+ repos = [
10
+ make_repo(language="Python", topics=["api", "backend", "database"]),
11
+ make_repo(language="Go", topics=["microservices"]),
12
+ ]
13
+ profile = make_profile(
14
+ repos=repos,
15
+ total_languages={"Python": 500000, "Go": 200000},
16
+ )
17
+ results = detect_archetypes(profile)
18
+ top = results[0]
19
+ assert top.key == "backend"
20
+ assert top.percentage > 0
21
+
22
+
23
+ def test_frontend_archetype_detected():
24
+ repos = [
25
+ make_repo(language="TypeScript", topics=["react", "frontend", "ui"]),
26
+ make_repo(language="JavaScript", topics=["vue"]),
27
+ ]
28
+ profile = make_profile(
29
+ repos=repos,
30
+ total_languages={"TypeScript": 400000, "JavaScript": 100000},
31
+ )
32
+ results = detect_archetypes(profile)
33
+ assert any(r.key == "frontend" and r.percentage > 0 for r in results)
34
+
35
+
36
+ def test_full_stack_derived_from_both():
37
+ repos = [
38
+ make_repo(language="Python", topics=["api", "backend"]),
39
+ make_repo(language="TypeScript", topics=["react", "frontend"]),
40
+ ]
41
+ profile = make_profile(
42
+ repos=repos,
43
+ total_languages={"Python": 300000, "TypeScript": 300000},
44
+ )
45
+ results = detect_archetypes(profile)
46
+ assert any(r.key == "full_stack" for r in results)
47
+
48
+
49
+ def test_devops_signals_detected():
50
+ repos = [
51
+ make_repo(language="Python", has_workflows=True, has_dockerfile=True, topics=["docker", "kubernetes"]),
52
+ ]
53
+ profile = make_profile(
54
+ repos=repos,
55
+ total_languages={"Python": 100000},
56
+ )
57
+ results = detect_archetypes(profile)
58
+ assert any(r.key == "devops" and r.percentage > 0 for r in results)
@@ -0,0 +1,122 @@
1
+ """Tests for the output formatters."""
2
+
3
+ import json
4
+ from datetime import datetime, timedelta, timezone
5
+
6
+ from utopia.formatters import json_output, markdown_output, terminal
7
+ from utopia.github_client import ProfileData, RepoData
8
+ from utopia.report import build_report
9
+
10
+
11
+ def _now_iso(days_ago: int = 0) -> str:
12
+ dt = datetime.now(timezone.utc) - timedelta(days=days_ago)
13
+ return dt.isoformat().replace("+00:00", "Z")
14
+
15
+
16
+ def make_repo(**kwargs) -> RepoData:
17
+ defaults = {
18
+ "name": "repo",
19
+ "description": "A repo",
20
+ "language": "Python",
21
+ "stars": 5,
22
+ "forks": 1,
23
+ "size_kb": 500,
24
+ "created_at": _now_iso(365),
25
+ "updated_at": _now_iso(10),
26
+ "pushed_at": _now_iso(10),
27
+ "has_readme": True,
28
+ "readme_word_count": 120,
29
+ "open_issues_count": 0,
30
+ "topics": ["api", "backend"],
31
+ "license": "MIT",
32
+ "is_fork": False,
33
+ "is_archived": False,
34
+ "languages": {"Python": 10000},
35
+ "commit_activity": [2] * 52,
36
+ "has_tests": False,
37
+ "has_workflows": False,
38
+ "has_dockerfile": False,
39
+ }
40
+ defaults.update(kwargs)
41
+ return RepoData(**defaults)
42
+
43
+
44
+ def make_profile(repos=None, **kwargs) -> ProfileData:
45
+ total_languages: dict[str, int] = {}
46
+ for repo in repos or []:
47
+ for lang, bytes_count in repo.languages.items():
48
+ total_languages[lang] = total_languages.get(lang, 0) + bytes_count
49
+ return ProfileData(
50
+ username="testuser",
51
+ name="Test",
52
+ bio=None,
53
+ followers=10,
54
+ following=0,
55
+ public_repos_count=len(repos) if repos else 0,
56
+ created_at=_now_iso(1000),
57
+ repos=repos or [],
58
+ merged_prs_count=2,
59
+ total_languages=total_languages,
60
+ **kwargs,
61
+ )
62
+
63
+
64
+ def _sample_report(roast: bool = False):
65
+ repos = [
66
+ make_repo(name="api", language="Python", topics=["api", "backend"]),
67
+ make_repo(name="ui", language="JavaScript", topics=["react", "frontend"]),
68
+ ]
69
+ profile = make_profile(repos=repos)
70
+ return build_report(profile, roast_mode=roast)
71
+
72
+
73
+ def test_terminal_render_no_color():
74
+ report = _sample_report()
75
+ output = terminal.render(report, no_color=True)
76
+ assert "UTOPIA SCORE" in output
77
+ assert "Project Quality" in output
78
+ assert "You are:" in output
79
+ assert "Would I hire" in output
80
+
81
+
82
+ def test_terminal_render_with_roast():
83
+ report = _sample_report(roast=True)
84
+ output = terminal.render(report, no_color=True)
85
+ assert "UTOPIA ROAST" in output
86
+
87
+
88
+ def test_json_output_is_valid():
89
+ report = _sample_report()
90
+ output = json_output.render(report)
91
+ data = json.loads(output)
92
+ assert data["username"] == "testuser"
93
+ assert "score" in data
94
+ assert "archetypes" in data
95
+ assert "recruiter" in data
96
+ assert "improvement_plan" in data
97
+
98
+
99
+ def test_json_output_includes_roast_when_enabled():
100
+ report = _sample_report(roast=True)
101
+ output = json_output.render(report)
102
+ data = json.loads(output)
103
+ assert "roast" in data
104
+
105
+
106
+ def test_markdown_output_contains_sections():
107
+ report = _sample_report(roast=True)
108
+ output = markdown_output.render(report)
109
+ assert "# UTOPIA Portfolio Report: testuser" in output
110
+ assert "## Score Breakdown" in output
111
+ assert "## Developer Archetype" in output
112
+ assert "## Recruiter Verdict" in output
113
+ assert "## Portfolio Roast" in output
114
+ assert "## 30-Day Upgrade Plan" in output
115
+
116
+
117
+ def test_markdown_output_ascii_safe():
118
+ report = _sample_report()
119
+ output = markdown_output.render(report)
120
+ # Markdown bars should use only ASCII chars
121
+ assert "█" not in output
122
+ assert "░" not in output