Skip to content

Commit 0fa6e72

Browse files
authored
Merge pull request #125 from wol-soft/attributes
attributes
2 parents c010bb9 + 33e8a84 commit 0fa6e72

File tree

215 files changed

+7312
-3964
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

215 files changed

+7312
-3964
lines changed

.claude/settings.local.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@
44
"Bash(gh issue:*)",
55
"WebFetch(domain:github.com)",
66
"Bash(find:*)",
7-
"Bash(cd C:/git/php-json-schema-model-generator && /c/PHP84/php.exe ./vendor/bin/phpunit 2>&1)",
8-
"Bash(find C:\\\\git\\\\php-json-schema-model-generator:*)",
97
"Bash(tail:*)",
108
"Bash(cd:*)",
119
"WebFetch(domain:api.github.com)",
1210
"Bash(head:*)",
1311
"Bash(grep:*)",
1412
"WebFetch(domain:wiki.php.net)",
15-
"Bash(cd /c/git/php-json-schema-model-generator && ./vendor/bin/phpunit 2>&1)",
1613
"Bash(./vendor/bin/phpunit:*)",
1714
"Bash(php:*)",
1815
"Bash(cat:*)",
@@ -28,10 +25,18 @@
2825
"Bash(gh api:*)",
2926
"Bash(git restore:*)",
3027
"Bash(git stash:*)",
28+
"Bash(git status:*)",
3129
"Bash(composer show:*)",
3230
"Bash(php -r \":*)",
3331
"Bash(gh pr:*)",
34-
"Bash(xargs wc:*)"
32+
"Bash(xargs wc:*)",
33+
"Bash(tee /tmp/phpunit-output.txt)",
34+
"Read(//tmp/**)",
35+
"WebFetch(domain:json-schema.org)",
36+
"WebFetch(domain:datatracker.ietf.org)",
37+
"Bash(for f:*)",
38+
"Bash(do)",
39+
"Bash(done)"
3540
]
3641
}
3742
}

.claude/topics/issue-101/analysis.md

Lines changed: 0 additions & 211 deletions
This file was deleted.

CLAUDE.md

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ user to resolve it.
99

1010
Rules:
1111

12-
- Ask all foreseeable clarifying questions upfront in a single batch before work begins.
12+
- When there are multiple clarifying questions to ask, ask them **one at a time**, in order of
13+
dependency (earlier answers may resolve later questions). Wait for the answer before asking the
14+
next question. This allows the user to discuss each point in depth without being overwhelmed by
15+
a wall of questions.
1316
- If new ambiguities emerge during execution that were not foreseeable upfront, pause and ask
1417
follow-up questions before proceeding past that decision point.
1518
- For high-stakes decisions (architecture, scope, data model, API shape, behaviour changes) always
@@ -19,6 +22,9 @@ Rules:
1922
visible so the user can correct it.
2023
- There must be no silent interpretation or interpolation of under-specified tasks. If something is
2124
unclear, ask. Do not guess and proceed.
25+
- For multi-phase implementations, **never start the next phase without an explicit go-ahead from
26+
the user**. After completing a phase, summarise what was done and wait for confirmation before
27+
proceeding.
2228

2329
When generating a new CLAUDE.md for a repository, include this clarification policy verbatim as a
2430
preamble before all other content.
@@ -48,6 +54,20 @@ composer update
4854

4955
Tests write generated PHP classes to `sys_get_temp_dir()/PHPModelGeneratorTest/Models/` and dump failed classes to `./failed-classes/` (auto-cleaned on bootstrap).
5056

57+
### Running the full test suite
58+
59+
When running the full test suite, always save output to a file so the complete
60+
output is available for analysis without re-running. Use `--display-warnings` to capture warning
61+
details and `--no-coverage` to skip slow coverage collection:
62+
63+
```bash
64+
php -d memory_limit=128M ./vendor/bin/phpunit --no-coverage --display-warnings 2>&1 | sed 's/\x1b\[[0-9;]*m//g' > /tmp/phpunit-output.txt; tail -5 /tmp/phpunit-output.txt
65+
```
66+
67+
Then analyse with: `grep -E "FAIL|ERROR|WARN|Tests:" /tmp/phpunit-output.txt`
68+
69+
After analysis is complete, delete the file: `rm /tmp/phpunit-output.txt`
70+
5171
## Architecture
5272

5373
This library generates PHP model classes from JSON Schema files. The process is a 4-step pipeline:
@@ -72,15 +92,25 @@ This library generates PHP model classes from JSON Schema files. The process is
7292
### Schema Processing
7393

7494
`SchemaProcessor` (`src/SchemaProcessor/SchemaProcessor.php`) orchestrates property parsing:
75-
- Uses `PropertyProcessorFactory` to instantiate the correct processor by JSON type (String, Integer, Number, Boolean, Array, Object, Null, Const, Any, Reference)
76-
- Convention: processor class name is `PHPModelGenerator\PropertyProcessor\Property\{Type}Processor`
95+
- Uses `PropertyFactory` (`src/PropertyProcessor/PropertyFactory.php`) to create and configure each property
96+
- `PropertyFactory` resolves `$ref` references, delegates `object` types to `processSchema`, and for all other types constructs a `Property` directly and applies Draft modifiers
7797
- `ComposedValueProcessorFactory` handles `allOf`, `anyOf`, `oneOf`, `if/then/else`, `not`
7898
- `SchemaDefinitionDictionary` tracks `$ref` definitions to avoid duplicate processing
7999

100+
### Draft System (`src/Draft/`)
101+
102+
The Draft system defines per-type modifier and validator registrations:
103+
- **`DraftInterface`** / **`DraftBuilder`** / **`Draft`** — Draft definition, builder, and built (immutable) registry
104+
- **`Draft_07.php`** — The JSON Schema Draft 7 definition; registers all types, modifiers, and validator factories
105+
- **`Element/Type`** — One entry per JSON Schema type; holds an ordered list of `ModifierInterface` instances
106+
- **`Modifier/`**`TypeCheckModifier`, `ConstModifier`, `NumberModifier`, `NullModifier`, `ObjectType/ObjectModifier`, `DefaultValueModifier`, `DefaultArrayToEmptyArrayModifier`; each implements `ModifierInterface::modify()`
107+
- **`Model/Validator/Factory/`**`AbstractValidatorFactory` subclasses keyed to schema keywords (e.g. `MinLengthPropertyValidatorFactory` for `minLength`); run as modifiers when a matching key exists in the schema
108+
109+
`PropertyFactory::applyDraftModifiers` resolves `getCoveredTypes($type)` (which always includes `'any'`) and runs every modifier for each covered type in order.
110+
80111
### Property Processors (`src/PropertyProcessor/`)
81112

82-
- `Property/` — One processor per JSON Schema type
83-
- `ComposedValue/` — Processors for composition keywords
113+
- `ComposedValue/` — Processors for composition keywords (`allOf`, `anyOf`, `oneOf`, `if/then/else`, `not`)
84114
- `Filter/` — Custom filter processing
85115
- `Decorator/` — Property decorators (ObjectInstantiation, PropertyTransfer, IntToFloatCast, etc.)
86116

@@ -104,6 +134,17 @@ Implement `SchemaProviderInterface` to supply schemas from custom sources. Built
104134

105135
`AbstractPHPModelGeneratorTestCase` is the base class for all tests. Tests generate model classes into a temp directory and then instantiate/exercise them to verify validation behavior. The `tests/manual/` directory contains standalone scripts excluded from the test suite.
106136

137+
#### Test case consolidation
138+
139+
Each call to `generateClassFromFile` triggers a code generation pass, which is the dominant cost in the test suite. **Minimise the number of distinct `generateClassFromFile` calls** by combining assertions that share the same schema file and `GeneratorConfiguration` into a single test method.
140+
141+
Rules:
142+
143+
- Group assertions by `(schema file, GeneratorConfiguration)` pair. All assertions that can use the same generated class belong in one test method.
144+
- A single test method may cover multiple behaviours (e.g. key naming, round-trip, `$except`, custom serializer) as long as they all operate on the same generated class. Use clear inline comments to separate the logical sections.
145+
- Only split into separate test methods when the behaviours require genuinely different configurations, or when combining them would make the test too complex to understand at a glance.
146+
- The goal is the balance between runtime efficiency (fewer generations) and readability (each method remains comprehensible). Avoid both extremes: a single monolithic test and a proliferation of single-assertion tests.
147+
107148
### JSON Schema style
108149

109150
In test schema files (`tests/Schema/**/*.json`), every object value must be expanded across multiple lines — never written inline. Use this style:
@@ -131,6 +172,33 @@ property, duplicate property names with unresolvable type conflicts, and any oth
131172
that cannot produce a correct PHP model. Fail loudly at generation time so the developer sees the
132173
problem immediately rather than receiving silently incorrect generated code.
133174

175+
### Filter callable classes must be in the production library
176+
177+
A `FilterInterface::getFilter()` callable is embedded verbatim in generated PHP code and is
178+
called at runtime — without the generator package being present. Any class referenced in
179+
`getFilter()` must therefore live in `php-json-schema-model-generator-production`, not in this
180+
generator package. Using a generator-package class as a filter callable will produce generated
181+
code that fails at runtime whenever the generator is not installed.
182+
183+
If a production-library class lacks the required type hints (needed for reflection-based type
184+
derivation), the fix is to add or update the callable in the production library, not to create
185+
a wrapper class here.
186+
187+
### Staging changes
188+
189+
After finishing an implementation task, always stage all relevant changed files for commit using
190+
`git add`. Do not wait for the user to ask — stage immediately when the work is done.
191+
192+
### Reading files
193+
194+
Always use the dedicated `Read` tool to read file contents. Never use `sed`, `head`, `tail`, `cat`, or `awk` to read or extract portions of files. The `Read` tool supports `offset` and `limit` parameters for reading partial files when needed.
195+
196+
### Variable naming
197+
198+
Never use single-character variable names. All variables must have meaningful, descriptive names
199+
that convey their purpose. For example, use `$typeName` instead of `$t`, `$validator` instead of
200+
`$v`, `$property` instead of `$p`.
201+
134202
### PHP import style
135203

136204
Always add `use` imports for every class referenced in a file, including global PHP classes such as

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
}
1212
],
1313
"require": {
14-
"wol-soft/php-json-schema-model-generator-production": "^0.21.1",
14+
"wol-soft/php-json-schema-model-generator-production": "dev-master",
1515
"wol-soft/php-micro-template": "^1.10.2",
1616

1717
"php": ">=8.4",

docs/requirements.txt

-1004 Bytes
Binary file not shown.

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
#
5959
# This is also used if you do content translation via gettext catalogs.
6060
# Usually you set "language" from the command line for these cases.
61-
language = None
61+
language = 'en'
6262

6363
# List of patterns, relative to source directory, that match files and
6464
# directories to ignore when looking for source files.

0 commit comments

Comments
 (0)