Update provenance when inputs change (#3064)

This commit is contained in:
Charis Kyriakou
2023-11-13 14:55:20 +00:00
committed by GitHub
parent ab4717c540
commit 3ac8a816ef
6 changed files with 70 additions and 13 deletions

View File

@@ -126,3 +126,38 @@ export function isModelAccepted(
modeledMethod.provenance !== "ai-generated"
);
}
/**
* Calculates the new provenance for a modeled method based on the current provenance.
* @param modeledMethod The modeled method if there is one.
* @returns The new provenance.
*/
export function calculateNewProvenance(
modeledMethod: ModeledMethod | undefined,
) {
if (!modeledMethod || !modeledMethodSupportsProvenance(modeledMethod)) {
// If nothing has been modeled or the modeled method does not support
// provenance, we assume that the user has entered it manually.
return "manual";
}
switch (modeledMethod.provenance) {
case "df-generated":
// If the method has been generated and there has been a change, we assume
// that the user has manually edited it.
return "df-manual";
case "df-manual":
// If the method has had manual edits, we want the provenance to stay the same.
return "df-manual";
case "ai-generated":
// If the method has been generated and there has been a change, we assume
// that the user has manually edited it.
return "ai-manual";
case "ai-manual":
// If the method has had manual edits, we want the provenance to stay the same.
return "ai-manual";
default:
// The method has been modeled manually.
return "manual";
}
}

View File

@@ -2,6 +2,7 @@ import * as React from "react";
import { ChangeEvent, useCallback, useMemo } from "react";
import {
ModeledMethod,
calculateNewProvenance,
isModelAccepted,
modeledMethodSupportsInput,
} from "../../model-editor/modeled-method";
@@ -53,6 +54,7 @@ export const ModelInputDropdown = ({
onChange({
...modeledMethod,
provenance: calculateNewProvenance(modeledMethod),
input: target.value,
});
},

View File

@@ -5,6 +5,7 @@ import {
ModeledMethodKind,
modeledMethodSupportsKind,
isModelAccepted,
calculateNewProvenance,
} from "../../model-editor/modeled-method";
import { getModelsAsDataLanguage } from "../../model-editor/languages";
import { QueryLanguage } from "../../common/query-language";
@@ -52,6 +53,7 @@ export const ModelKindDropdown = ({
onChange({
...modeledMethod,
provenance: calculateNewProvenance(modeledMethod),
kind,
});
},

View File

@@ -2,6 +2,7 @@ import * as React from "react";
import { ChangeEvent, useCallback, useMemo } from "react";
import {
ModeledMethod,
calculateNewProvenance,
isModelAccepted,
modeledMethodSupportsOutput,
} from "../../model-editor/modeled-method";
@@ -54,6 +55,7 @@ export const ModelOutputDropdown = ({
onChange({
...modeledMethod,
provenance: calculateNewProvenance(modeledMethod),
output: target.value,
});
},

View File

@@ -1,11 +1,10 @@
import * as React from "react";
import { ChangeEvent, useCallback } from "react";
import {
calculateNewProvenance,
isModelAccepted,
ModeledMethod,
modeledMethodSupportsProvenance,
ModeledMethodType,
Provenance,
} from "../../model-editor/modeled-method";
import { Method } from "../../model-editor/method";
import { createEmptyModeledMethod } from "../../model-editor/modeled-method-empty";
@@ -43,15 +42,6 @@ export const ModelTypeDropdown = ({
(e: ChangeEvent<HTMLSelectElement>) => {
const modelsAsDataLanguage = getModelsAsDataLanguage(language);
let newProvenance: Provenance = "manual";
if (modeledMethod && modeledMethodSupportsProvenance(modeledMethod)) {
if (modeledMethod.provenance === "df-generated") {
newProvenance = "df-manual";
} else if (modeledMethod.provenance === "ai-generated") {
newProvenance = "ai-manual";
}
}
const emptyModeledMethod = createEmptyModeledMethod(
e.target.value as ModeledMethodType,
method,
@@ -67,7 +57,7 @@ export const ModelTypeDropdown = ({
updatedModeledMethod.output = "ReturnValue";
}
if ("provenance" in updatedModeledMethod) {
updatedModeledMethod.provenance = newProvenance;
updatedModeledMethod.provenance = calculateNewProvenance(modeledMethod);
}
if ("kind" in updatedModeledMethod) {
updatedModeledMethod.kind = "value";

View File

@@ -27,7 +27,7 @@ describe(MethodRow.name, () => {
input: "Argument[0]",
output: "ReturnValue",
kind: "taint",
provenance: "df-generated",
provenance: "manual",
};
const onChange = jest.fn();
@@ -111,6 +111,32 @@ describe(MethodRow.name, () => {
]);
});
it("changes the provenance when the kind is changed", async () => {
const modeledMethodWithGeneratedProvenance: ModeledMethod = {
...modeledMethod,
provenance: "df-generated",
};
render({ modeledMethods: [modeledMethodWithGeneratedProvenance] });
onChange.mockReset();
expect(screen.getByRole("combobox", { name: "Kind" })).toHaveValue("taint");
await userEvent.selectOptions(
screen.getByRole("combobox", { name: "Kind" }),
"value",
);
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenCalledWith(method.signature, [
{
...modeledMethod,
kind: "value",
provenance: "df-manual",
},
]);
});
it("has the correct input options", () => {
render();