Skip to content

Commit 8cbace8

Browse files
feat(native): Add toBeEmptyElement (#142)
1 parent 79bea9d commit 8cbace8

File tree

3 files changed

+85
-13
lines changed

3 files changed

+85
-13
lines changed

packages/native/src/lib/ElementAssertion.ts

+33-7
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
import { Assertion, AssertionError } from "@assertive-ts/core";
22
import { get } from "dot-prop-immutable";
3+
import { Children } from "react";
34
import { ReactTestInstance } from "react-test-renderer";
45

6+
import { instanceToString } from "./helpers/helpers";
7+
58
export class ElementAssertion extends Assertion<ReactTestInstance> {
69
public constructor(actual: ReactTestInstance) {
710
super(actual);
811
}
912

1013
public override toString = (): string => {
11-
if (this.actual === null) {
12-
return "null";
13-
}
14-
15-
return `<${this.actual.type.toString()} ... />`;
14+
return instanceToString(this.actual);
1615
};
1716

1817
/**
@@ -32,7 +31,7 @@ export class ElementAssertion extends Assertion<ReactTestInstance> {
3231
});
3332
const invertedError = new AssertionError({
3433
actual: this.actual,
35-
message: `Expected element ${this.toString()} to NOT be disabled.`,
34+
message: `Expected element ${this.toString()} NOT to be disabled.`,
3635
});
3736

3837
return this.execute({
@@ -58,7 +57,7 @@ export class ElementAssertion extends Assertion<ReactTestInstance> {
5857
});
5958
const invertedError = new AssertionError({
6059
actual: this.actual,
61-
message: `Expected element ${this.toString()} to NOT be enabled.`,
60+
message: `Expected element ${this.toString()} NOT to be enabled.`,
6261
});
6362

6463
return this.execute({
@@ -68,6 +67,33 @@ export class ElementAssertion extends Assertion<ReactTestInstance> {
6867
});
6968
}
7069

70+
/**
71+
* Check if the element is empty.
72+
*
73+
* @example
74+
* ```
75+
* expect(element).toBeEmpty();
76+
* ```
77+
*
78+
* @returns the assertion instance
79+
*/
80+
public toBeEmpty(): this {
81+
const error = new AssertionError({
82+
actual: this.actual,
83+
message: `Expected element ${this.toString()} to be empty.`,
84+
});
85+
const invertedError = new AssertionError({
86+
actual: this.actual,
87+
message: `Expected element ${this.toString()} NOT to be empty.`,
88+
});
89+
90+
return this.execute({
91+
assertWhen: Children.count(this.actual.props.children) === 0,
92+
error,
93+
invertedError,
94+
});
95+
}
96+
7197
private isElementDisabled(element: ReactTestInstance): boolean {
7298
const { type } = element;
7399
const elementType = type.toString();
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ReactTestInstance } from "react-test-renderer";
2+
3+
/**
4+
* Converts a ReactTestInstance to a string representation.
5+
*
6+
* @param instance The ReactTestInstance to convert.
7+
* @returns A string representation of the instance.
8+
*/
9+
export function instanceToString(instance: ReactTestInstance | null): string {
10+
if (instance === null) {
11+
return "null";
12+
}
13+
14+
return `<${instance.type.toString()} ... />`;
15+
}

packages/native/test/lib/ElementAssertion.test.tsx

+37-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { render } from "@testing-library/react-native";
33
import {
44
View,
55
TextInput,
6+
Text,
67
} from "react-native";
78

89
import { ElementAssertion } from "../../src/lib/ElementAssertion";
@@ -34,7 +35,7 @@ describe("[Unit] ElementAssertion.test.ts", () => {
3435
.toHaveMessage("Expected element <TextInput ... /> to be disabled.");
3536
expect(() => test.not.toBeEnabled())
3637
.toThrowError(AssertionError)
37-
.toHaveMessage("Expected element <TextInput ... /> to NOT be enabled.");
38+
.toHaveMessage("Expected element <TextInput ... /> NOT to be enabled.");
3839
});
3940
});
4041
});
@@ -59,7 +60,7 @@ describe("[Unit] ElementAssertion.test.ts", () => {
5960
.toHaveMessage("Expected element <View ... /> to be enabled.");
6061
expect(() => parent.not.toBeDisabled())
6162
.toThrowError(AssertionError)
62-
.toHaveMessage("Expected element <View ... /> to NOT be disabled.");
63+
.toHaveMessage("Expected element <View ... /> NOT to be disabled.");
6364
});
6465
});
6566

@@ -83,13 +84,13 @@ describe("[Unit] ElementAssertion.test.ts", () => {
8384
.toHaveMessage("Expected element <View ... /> to be disabled.");
8485
expect(() => parent.not.toBeEnabled())
8586
.toThrowError(AssertionError)
86-
.toHaveMessage("Expected element <View ... /> to NOT be enabled.");
87+
.toHaveMessage("Expected element <View ... /> NOT to be enabled.");
8788
expect(() => child.toBeDisabled())
8889
.toThrowError(AssertionError)
8990
.toHaveMessage("Expected element <View ... /> to be disabled.");
9091
expect(() => child.not.toBeEnabled())
9192
.toThrowError(AssertionError)
92-
.toHaveMessage("Expected element <View ... /> to NOT be enabled.");
93+
.toHaveMessage("Expected element <View ... /> NOT to be enabled.");
9394
});
9495
});
9596
});
@@ -114,7 +115,7 @@ describe("[Unit] ElementAssertion.test.ts", () => {
114115
.toHaveMessage("Expected element <View ... /> to be enabled.");
115116
expect(() => child.not.toBeDisabled())
116117
.toThrowError(AssertionError)
117-
.toHaveMessage("Expected element <View ... /> to NOT be disabled.");
118+
.toHaveMessage("Expected element <View ... /> NOT to be disabled.");
118119
});
119120

120121
it("returns error for parent element", () => {
@@ -124,9 +125,39 @@ describe("[Unit] ElementAssertion.test.ts", () => {
124125
.toHaveMessage("Expected element <View ... /> to be disabled.");
125126
expect(() => parent.not.toBeEnabled())
126127
.toThrowError(AssertionError)
127-
.toHaveMessage("Expected element <View ... /> to NOT be enabled.");
128+
.toHaveMessage("Expected element <View ... /> NOT to be enabled.");
128129
});
129130
});
130131
});
131132
});
133+
134+
describe(".toBeEmpty", () => {
135+
context("when the element is empty", () => {
136+
it("returns the assertion instance", () => {
137+
const element = render(<View testID="id" />);
138+
const test = new ElementAssertion(element.getByTestId("id"));
139+
140+
expect(test.toBeEmpty()).toBe(test);
141+
expect(() => test.not.toBeEmpty())
142+
.toThrowError(AssertionError)
143+
.toHaveMessage("Expected element <View ... /> NOT to be empty.");
144+
});
145+
});
146+
147+
context("when the element is NOT empty", () => {
148+
it("throws an error", () => {
149+
const element = render(
150+
<View testID="id">
151+
<Text>{"Not empty"}</Text>
152+
</View>,
153+
);
154+
const test = new ElementAssertion(element.getByTestId("id"));
155+
156+
expect(test.not.toBeEmpty()).toBeEqual(test);
157+
expect(() => test.toBeEmpty())
158+
.toThrowError(AssertionError)
159+
.toHaveMessage("Expected element <View ... /> to be empty.");
160+
});
161+
});
162+
});
132163
});

0 commit comments

Comments
 (0)