Skip to content

Commit

Permalink
[Modify] Modify tests for setBodyStyle and clearBodyStyle functions
Browse files Browse the repository at this point in the history
  • Loading branch information
jagaapple committed Mar 21, 2020
1 parent 9d02140 commit f26cbbf
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 16 deletions.
82 changes: 71 additions & 11 deletions src/item/body.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,65 @@ import * as sinon from "sinon";
import { clearBodyStyle, setBodyStyle } from "./body";

describe("setBodyStyle", () => {
let dummyDocumentElement: Document;
let dummyElement: HTMLElement;
let elementCreatorMock: sinon.SinonStub<Parameters<Document["createElement"]>, ReturnType<Document["createElement"]>>;
let elementAttributeSetterSpy: sinon.SinonSpy<Parameters<Element["setAttribute"]>, ReturnType<Element["setAttribute"]>>;
let childAppenderSpy: sinon.SinonSpy<Parameters<Node["appendChild"]>, ReturnType<Node["appendChild"]>>;

beforeEach(() => {
elementAttributeSetterSpy = sinon.spy() as any;
dummyElement = { setAttribute: elementAttributeSetterSpy, textContent: "" } as any;

elementCreatorMock = sinon.mock().returns(dummyElement) as any;
childAppenderSpy = sinon.spy() as any;
dummyDocumentElement = { createElement: elementCreatorMock, head: { appendChild: childAppenderSpy } } as any;
});
afterEach(() => {
sinon.restore();
});

it('should set `style.userSelect` to "none"', () => {
const bodyElement = { style: {} } as HTMLElement;

setBodyStyle(bodyElement, undefined);
setBodyStyle(bodyElement, undefined, dummyDocumentElement);
expect(bodyElement.style.userSelect).toBe("none");
});

context("when `draggingCusrsorStyle` is undefined", () => {
it("should not call `document.createElement`", () => {
const bodyElement = { style: {} } as HTMLElement;

setBodyStyle(bodyElement, undefined, dummyDocumentElement);
expect(elementCreatorMock.called).toBe(false);
});

it("should not call `document.head.appendChild`", () => {
const bodyElement = { style: {} } as HTMLElement;

setBodyStyle(bodyElement, undefined, dummyDocumentElement);
expect(childAppenderSpy.called).toBe(false);
});
});

context("when `draggingCusrsorStyle` is not undefined", () => {
const draggingCusrsorStyle = "dummy";

it('should set `style.userSelect` to "none"', () => {
const bodyElement = { style: {} } as HTMLElement;

setBodyStyle(bodyElement, undefined);
setBodyStyle(bodyElement, draggingCusrsorStyle, dummyDocumentElement);
expect(bodyElement.style.userSelect).toBe("none");
});

it("should set `style.cursor` to the string", () => {
it("should create a style element, set attributes, and append to a document element", () => {
const bodyElement = { style: {} } as HTMLElement;
const draggingCusrsorStyle = "dummy";

setBodyStyle(bodyElement, draggingCusrsorStyle);
expect(bodyElement.style.cursor).toBe(draggingCusrsorStyle);
setBodyStyle(bodyElement, draggingCusrsorStyle, dummyDocumentElement);
expect(elementCreatorMock.calledOnceWith("style")).toBe(true);
expect(dummyElement.textContent).toBe(`* { cursor: ${draggingCusrsorStyle} !important; }`);
expect(elementAttributeSetterSpy.calledOnceWith("id", "react-sortful-global-style")).toBe(true);
expect(childAppenderSpy.calledOnceWith(dummyElement)).toBe(true);
});
});
});
Expand All @@ -34,24 +72,46 @@ describe("clearBodyStyle", () => {
Parameters<CSSStyleDeclaration["removeProperty"]>,
ReturnType<CSSStyleDeclaration["removeProperty"]>
>;
let dummyDocumentElement: Document;
let dummyElement: HTMLElement;
let elementGetterMock: sinon.SinonStub<Parameters<Document["getElementById"]>, ReturnType<Document["getElementById"]>>;
let elementRemoverSpy: sinon.SinonSpy<Parameters<Element["remove"]>, ReturnType<Element["remove"]>>;

beforeAll(() => {
beforeEach(() => {
propertyRemoverSpy = sinon.spy() as any;
bodyElement = { style: { removeProperty: propertyRemoverSpy } } as any;

elementRemoverSpy = sinon.spy() as any;
dummyElement = { remove: elementRemoverSpy } as any;

elementGetterMock = sinon.mock().returns(dummyElement) as any;
dummyDocumentElement = { getElementById: elementGetterMock } as any;
});
afterEach(() => {
sinon.restore();
});

it('should call `style.removeProperty` with "user-select" of `bodyElement`', () => {
clearBodyStyle(bodyElement);
clearBodyStyle(bodyElement, dummyDocumentElement);

expect(propertyRemoverSpy.calledWith("user-select")).toBe(true);
});

it('should call `style.removeProperty` with "cursor" of `bodyElement`', () => {
clearBodyStyle(bodyElement);
it("should remove a style element created by react-sortful", () => {
clearBodyStyle(bodyElement, dummyDocumentElement);

expect(elementGetterMock.calledOnceWith("react-sortful-global-style")).toBe(true);
expect(elementRemoverSpy.calledOnce).toBe(true);
});

context("when `documentElement.getElementById` returns null", () => {
beforeEach(() => {
elementGetterMock = sinon.mock().returns(null) as any;
dummyDocumentElement = { getElementById: elementGetterMock } as any;
});

expect(propertyRemoverSpy.calledWith("cursor")).toBe(true);
it("should not raise any errors", () => {
expect(() => clearBodyStyle(bodyElement, dummyDocumentElement)).not.toThrowError();
});
});
});
19 changes: 14 additions & 5 deletions src/item/body.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
const styleElementId = "react-sortful-global-style";

export const setBodyStyle = (bodyElement: HTMLElement, draggingCusrsorStyle: string | undefined) => {
export const setBodyStyle = (
bodyElement: HTMLElement,
draggingCusrsorStyle: string | undefined,
// istanbul ignore next
documentElement = document,
) => {
// Disables to select elements in entire page.
bodyElement.style.userSelect = "none";

// Applies a cursor style when dragging.
if (draggingCusrsorStyle != undefined) {
const styleElement = document.createElement("style");
const styleElement = documentElement.createElement("style");
styleElement.textContent = `* { cursor: ${draggingCusrsorStyle} !important; }`;
styleElement.setAttribute("id", styleElementId);

document.head.appendChild(styleElement);
documentElement.head.appendChild(styleElement);
}
};

export const clearBodyStyle = (bodyElement: HTMLElement) => {
export const clearBodyStyle = (
bodyElement: HTMLElement,
// istanbul ignore next
documentElement = document,
) => {
// Enables to select elements in entire page.
bodyElement.style.removeProperty("user-select");

// Resets a cursor style when dragging.
document.getElementById(styleElementId)?.remove();
documentElement.getElementById(styleElementId)?.remove();
};

0 comments on commit f26cbbf

Please sign in to comment.