Skip to content

Commit

Permalink
Fix case where loop callback returns something other than element, im…
Browse files Browse the repository at this point in the history
…prove tests, ensure key is always provided as a string
  • Loading branch information
leebyron committed Apr 2, 2019
1 parent 8dc929d commit f001a5e
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 10 deletions.
11 changes: 4 additions & 7 deletions react-loops.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function For(props) {
}

function mapIteration(mapper, item, index, length, key) {
var itemChildren =
var result =
mapper.length === 1
? mapper(item)
: mapper(item, {
Expand All @@ -142,13 +142,10 @@ function mapIteration(mapper, item, index, length, key) {
isFirst: index === 0,
isLast: index === length - 1
});
if (React.Children.count(itemChildren) === 1) {
var child = React.Children.only(itemChildren);
return child.props.hasOwnProperty("key")
? child
: React.cloneElement(child, { key: key });
if (React.isValidElement(result) && !result.props.hasOwnProperty("key")) {
return React.cloneElement(result, { key: String(key) });
}
return itemChildren;
return result;
}

/**
Expand Down
44 changes: 41 additions & 3 deletions react-loops.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@ import TestRenderer from "react-test-renderer";
import { For, If, ElseIf, Else } from "./react-loops.js";

function expectRenderToEqual(actual, expected) {
expect(TestRenderer.create(actual).toJSON()).toEqual(
TestRenderer.create(expected).toJSON()
);
const consoleError = console.error;
try {
console.error = message => {
throw new Error(message);
};
expect(TestRenderer.create(actual).toJSON()).toEqual(
TestRenderer.create(expected).toJSON()
);
} finally {
console.error = consoleError;
}
}

function expectRenderToThrow(actual, error) {
Expand Down Expand Up @@ -90,6 +98,36 @@ describe("react-loops", () => {
);
});

it("loops with a non-element string return", () => {
const list = ["A", "B", "C"];
expectRenderToEqual(
<For of={list} as={item => item} />,
<>
{"A"}
{"B"}
{"C"}
</>
);
});

it("loops with a non-element Array return", () => {
const list = ["A", "B", "C"];
expectRenderToEqual(
<For
of={list}
as={item => [<li key="0">{item}</li>, <li key="1">{item}</li>]}
/>,
<>
<li key="woof">A</li>
<li>A</li>
<li>B</li>
<li>B</li>
<li>C</li>
<li>C</li>
</>
);
});

it("loops an Array with metadata", () => {
const list = ["A", "B", "C"];
expectRenderToEqual(
Expand Down

0 comments on commit f001a5e

Please # to comment.