Skip to content

Json patch, initial pr, structures only#1525

Open
suarezrominajulieta wants to merge 5 commits intomasterfrom
feature/jsonPatch
Open

Json patch, initial pr, structures only#1525
suarezrominajulieta wants to merge 5 commits intomasterfrom
feature/jsonPatch

Conversation

@suarezrominajulieta
Copy link
Copy Markdown
Collaborator

@suarezrominajulieta suarezrominajulieta commented Apr 26, 2026

Summary

Introduces the foundational gene structure and builder needed to model JSON Patch

New files

Gene model (core/src/main/kotlin/.../search/gene/patch/)

  • JsonPatchOperationGene — enum-backed gene representing a single RFC 6902 op (add, remove, replace, move, copy, test)
  • JsonPatchPathOnlyGene — composite gene for ops that only require a path field (remove)
  • JsonPatchPathValueGene — composite gene for ops that require path + value (add, replace, test)
  • JsonPatchFromPathGene — composite gene for ops that require path + from (move, copy)
  • JsonPatchDocumentGene — top-level gene representing a full JSON Patch document (array of operation objects); handles serialization to JSON and mutation logic

Builder (core/src/main/kotlin/.../problem/rest/builder/)

  • JsonPatchGeneBuilder — constructs a JsonPatchDocumentGene from an OpenAPI schema, mapping PATCH request body fields to the appropriate sub-gene variant

Tests (core/src/test/kotlin/...)

  • Unit tests for each gene class and the builder
  • GeneSamplerForTests and GeneNumberOfGenesTest updated to include new gene types

What's NOT included yet

  • Integration with RestActionBuilderV3 (wiring the builder into the main action pipeline)
  • E2E test against a real PATCH endpoint

Notes

This is a structural PR — all new classes compile and their unit tests pass, but the genes are not yet invoked during actual fuzzing runs.

@suarezrominajulieta suarezrominajulieta marked this pull request as ready for review April 27, 2026 11:33
@jgaleotti
Copy link
Copy Markdown
Collaborator

Hi @suarezrominajulieta, first ask for my review and then, when I aprove the PR, I will request @arcuri82 's review.

@suarezrominajulieta suarezrominajulieta removed the request for review from arcuri82 April 27, 2026 16:45
@suarezrominajulieta
Copy link
Copy Markdown
Collaborator Author

suarezrominajulieta commented Apr 27, 2026

Hi @jgaleotti ! Okey, done :)

* Provides heuristics that extract valid JSON Pointer paths from a resource schema
* and group them by field type to construct type-safe path-value pairs.
*/
object JsonPatchGeneBuilder {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why it is saying that it provides "heuristics"? This class deterministically creates an JsonPathGene from a given schema

resourceSchema: Gene?
): ArrayGene<ChoiceGene<JsonPatchOperationGene>> {

val allPaths = JsonPatchGeneBuilder.extractAllPaths(resourceSchema)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if resourceSchema is null?

val choices = mutableListOf<JsonPatchOperationGene>()

// Operations that only need a path
choices.add(JsonPatchPathOnlyGene("remove", pathEnum.copy() as EnumGene<String>))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace "remove" and other strings with constants


// Operations that need path + value; pairs are grouped by schema field type
val pathValueEntries = JsonPatchGeneBuilder.buildPathValueEntries(allPaths)
val effectiveEntries: List<PairGene<EnumGene<String>, Gene>> =
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does effectiveEntries mean? Shouldn't this list be called pathValuePairGenes?

val fromGene: EnumGene<String>,
val pathGene: EnumGene<String>,
geneName: String = "${operationName}Op"
) : JsonPatchOperationGene(geneName, operationName, listOf(fromGene, pathGene)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check that the operation name is move or copy. Why does it add the "Op" ?

operationsArr: ArrayGene<ChoiceGene<JsonPatchOperationGene>>
) : CompositeFixedGene(name, listOf(operationsArr)) {

constructor(name: String, resourceSchema: Gene? = null)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this logic to JsonPatchDocumentGeneBuilder

* Provides heuristics that extract valid JSON Pointer paths from a resource schema
* and group them by field type to construct type-safe path-value pairs.
*/
object JsonPatchGeneBuilder {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not include the schema extraction heuristics in this PR

class JsonPatchPathOnlyGene(
operationName: String,
val pathGene: EnumGene<String>,
geneName: String = "${operationName}Op"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we have operationName and geneName?

targetFormat: OutputFormat?,
extraCheck: Boolean
): String {
val activePair = pathValueChoice.activeGene()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as previous comments

* The primary constructor builds the operations array from [resourceSchema].
* The private secondary constructor accepts a pre-built array, used internally by [copyContent].
*/
class JsonPatchDocumentGene private constructor(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this private constructor?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants