Add extension points for source tree (#1816)

This change will add an extension point which allows to wrap the source tree. This is required in order to use a context provider e.g. to capture a selected file. Another extension point allows to add a row between the row of a file.
In order to implement the extension points ui-extensions has now a wrapper property and passes the children of an extension point to implementing extension.
This commit is contained in:
Sebastian Sdorra
2021-09-30 16:41:04 +02:00
committed by GitHub
parent 2b85081032
commit f5d9855a24
8 changed files with 279 additions and 70 deletions

View File

@@ -21,9 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React from "react";
import React, { FC } from "react";
import ExtensionPoint from "./ExtensionPoint";
import { shallow, mount } from "enzyme";
// eslint-disable-next-line no-restricted-imports
import "@scm-manager/ui-tests/enzyme";
import binder from "./binder";
@@ -89,7 +90,7 @@ describe("ExtensionPoint test", () => {
<ExtensionPoint
name="something.special"
props={{
value: "Awesome"
value: "Awesome",
}}
/>
);
@@ -126,7 +127,7 @@ describe("ExtensionPoint test", () => {
it("should pass the context of the parent component", () => {
const UserContext = React.createContext({
name: "anonymous"
name: "anonymous",
});
type HelloProps = {
@@ -148,7 +149,7 @@ describe("ExtensionPoint test", () => {
return (
<UserContext.Provider
value={{
name: "Trillian"
name: "Trillian",
}}
>
<ExtensionPoint name="hello" />
@@ -187,7 +188,7 @@ describe("ExtensionPoint test", () => {
};
mockedBinder.hasExtension.mockReturnValue(true);
mockedBinder.getExtension.mockReturnValue(<Label name="One" />);
mockedBinder.getExtension.mockReturnValue(Label);
const rendered = mount(<ExtensionPoint name="something.special" props={{ name: "Two" }} />);
expect(rendered.text()).toBe("Extension Two");
@@ -203,11 +204,79 @@ describe("ExtensionPoint test", () => {
const transformer = (props: object) => {
return {
...props,
name: "Two"
name: "Two",
};
};
const rendered = mount(<ExtensionPoint name="something.special" propTransformer={transformer} />);
expect(rendered.text()).toBe("Extension Two");
});
it("should pass children as props", () => {
const label: FC = ({ children }) => {
return (
<>
<label>Bound Extension</label>
<details>{children}</details>
</>
);
};
mockedBinder.hasExtension.mockReturnValue(true);
mockedBinder.getExtension.mockReturnValue(label);
const rendered = mount(
<ExtensionPoint name="something.special">
<p>Cool stuff</p>
</ExtensionPoint>
);
const text = rendered.text();
expect(text).toContain("Bound Extension");
expect(text).toContain("Cool stuff");
});
it("should wrap children with multiple extensions", () => {
const w1: FC = ({ children }) => (
<>
<label>Outer {"-> "}</label>
<details>{children}</details>
</>
);
const w2: FC = ({ children }) => (
<>
<label>Inner {"-> "}</label>
<details>{children}</details>
</>
);
mockedBinder.hasExtension.mockReturnValue(true);
mockedBinder.getExtensions.mockReturnValue([w1, w2]);
const rendered = mount(
<ExtensionPoint name="something.special" renderAll={true} wrapper={true}>
<p>Children</p>
</ExtensionPoint>
);
const text = rendered.text();
expect(text).toEqual("Outer -> Inner -> Children");
});
it("should render children of non fc", () => {
const nonfc = (
<div>
<label>Non fc with children</label>
</div>
);
mockedBinder.hasExtension.mockReturnValue(true);
mockedBinder.getExtension.mockReturnValue(nonfc);
const rendered = mount(
<ExtensionPoint name="something.special">
<p>Children</p>
</ExtensionPoint>
);
const text = rendered.text();
expect(text).toEqual("Non fc with children");
});
});