CodeQL model editor: Make Type a selectable model kind for Ruby (#3224)

This commit is contained in:
Shati Patel
2024-01-16 13:17:26 +00:00
committed by GitHub
parent c5517e0aea
commit f993258a27
2 changed files with 94 additions and 10 deletions

View File

@@ -1,5 +1,5 @@
import type { ChangeEvent } from "react";
import { useCallback } from "react";
import { useCallback, useMemo } from "react";
import type {
ModeledMethod,
ModeledMethodType,
@@ -12,19 +12,11 @@ import type { Method } from "../../model-editor/method";
import { createEmptyModeledMethod } from "../../model-editor/modeled-method-empty";
import type { Mutable } from "../../common/mutable";
import { ReadonlyDropdown } from "../common/ReadonlyDropdown";
import type { QueryLanguage } from "../../common/query-language";
import { QueryLanguage } from "../../common/query-language";
import { getModelsAsDataLanguage } from "../../model-editor/languages";
import type { ModelingStatus } from "../../model-editor/shared/modeling-status";
import { InputDropdown } from "./InputDropdown";
const options: Array<{ value: ModeledMethodType; label: string }> = [
{ value: "none", label: "Unmodeled" },
{ value: "source", label: "Source" },
{ value: "sink", label: "Sink" },
{ value: "summary", label: "Flow summary" },
{ value: "neutral", label: "Neutral" },
];
type Props = {
language: QueryLanguage;
method: Method;
@@ -40,6 +32,21 @@ export const ModelTypeDropdown = ({
modelingStatus,
onChange,
}: Props): JSX.Element => {
const options = useMemo(() => {
const baseOptions: Array<{ value: ModeledMethodType; label: string }> = [
{ value: "none", label: "Unmodeled" },
{ value: "source", label: "Source" },
{ value: "sink", label: "Sink" },
{ value: "summary", label: "Flow summary" },
{ value: "neutral", label: "Neutral" },
];
if (language === QueryLanguage.Ruby) {
baseOptions.push({ value: "type", label: "Type" });
}
return baseOptions;
}, [language]);
const handleChange = useCallback(
(e: ChangeEvent<HTMLSelectElement>) => {
const modelsAsDataLanguage = getModelsAsDataLanguage(language);

View File

@@ -0,0 +1,77 @@
import { userEvent } from "@testing-library/user-event";
import { render, screen } from "@testing-library/react";
import { createNoneModeledMethod } from "../../../../test/factories/model-editor/modeled-method-factories";
import { QueryLanguage } from "../../../common/query-language";
import { ModelTypeDropdown } from "../ModelTypeDropdown";
import { createMethod } from "../../../../test/factories/model-editor/method-factories";
describe(ModelTypeDropdown.name, () => {
const onChange = jest.fn();
beforeEach(() => {
onChange.mockReset();
});
it("allows changing the type", async () => {
const method = createMethod();
const modeledMethod = createNoneModeledMethod();
render(
<ModelTypeDropdown
language={QueryLanguage.Java}
modeledMethod={modeledMethod}
modelingStatus="unsaved"
onChange={onChange}
method={method}
/>,
);
await userEvent.selectOptions(screen.getByRole("combobox"), "source");
expect(onChange).toHaveBeenCalledWith(
expect.objectContaining({
type: "source",
}),
);
});
it("allows changing the type to 'Type' for Ruby", async () => {
const method = createMethod();
const modeledMethod = createNoneModeledMethod();
render(
<ModelTypeDropdown
language={QueryLanguage.Ruby}
modeledMethod={modeledMethod}
modelingStatus="unsaved"
onChange={onChange}
method={method}
/>,
);
await userEvent.selectOptions(screen.getByRole("combobox"), "type");
expect(onChange).toHaveBeenCalledWith(
expect.objectContaining({
type: "type",
}),
);
});
it("does not allow changing the type to 'Type' for Java", async () => {
const method = createMethod();
const modeledMethod = createNoneModeledMethod();
render(
<ModelTypeDropdown
language={QueryLanguage.Java}
modeledMethod={modeledMethod}
modelingStatus="unsaved"
onChange={onChange}
method={method}
/>,
);
expect(
screen.queryByRole("option", { name: "Type" }),
).not.toBeInTheDocument();
});
});