Skip to content

Commit

Permalink
refactor(curriculum): remove Enzyme from reuseable profile (freeCodeC…
Browse files Browse the repository at this point in the history
…amp#58480)

Co-authored-by: Jessica Wilkins <[email protected]>
  • Loading branch information
ojeytonwilliams and jdwilkin4 authored Jan 30, 2025
1 parent 3371ba8 commit afade4a
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 111 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,18 @@ Also, return a pair of parentheses with an empty string inside of them for now.
You should create and export a `Card` functional component. Don't forget to return an empty string inside it.

```js
const mockedComponent = Enzyme.mount(
React.createElement(window.index.Card)
);

assert.lengthOf(mockedComponent.find('Card'), 1);
assert.isFunction(window.index.Card);
```

Your `Card` component should have a `name`, `title`, and `bio` props.

```js
const mockedComponent = Enzyme.mount(
React.createElement(window.index.Card)
);

const componentFunction = mockedComponent.type();
const propsSource = componentFunction.toString();

assert.match(propsSource, /\bname\b/);
assert.match(propsSource, /\btitle\b/);
assert.match(propsSource, /\bbio\b/);
const functionRegex = __helpers.functionRegex("Card", null, { capture: true });
const match = code.match(functionRegex);
const functionDefinition = match[0];
assert.match(functionDefinition, /\{[^{]*name[^{]*\}/);
assert.match(functionDefinition, /\{[^{]*title[^{]*\}/);
assert.match(functionDefinition, /\{[^{]*bio[^{]*\}/);
```

# --seed--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,23 @@ Inside the return, remove the empty string, then create a `div` element with a `

# --hints--

You should not have an empty string in your Card component.
Your `Card` component should not render an empty string.

```js
assert.notMatch(code, /""/)
async () => {
const testElem = await __prepTestComponent(window.index.Card);
assert.notEqual(testElem.innerHTML, '');
}
```

You should create a `div` element with the `className` `card` at the top level of your `Card` component.

```js
const mockedComponent = Enzyme.mount(
React.createElement(window.index.Card)
);

assert.equal(mockedComponent.childAt(0).type(), 'div');
assert.isTrue(mockedComponent.childAt(0).hasClass('card'));
async () => {
const testElem = await __prepTestComponent(window.index.Card);
const div = testElem.firstElementChild;
assert.include([...div?.classList], 'card');
}
```
# --seed--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,64 +16,56 @@ Also, inside the `div`, create a paragraph with the `className` of `card-title`
You should create an `h2` element inside your `div` element.

```js
const mockedComponent = Enzyme.mount(
React.createElement(window.index.Card)
);

const h2Elem = mockedComponent.find('h2');

assert.equal(h2Elem.parent().type(), 'div');
async () => {
const testElem = await __prepTestComponent(window.index.Card);
const h2Elem = testElem.querySelector('div > h2');
assert.exists(h2Elem);
}
```

Your `h2` element should have `{name}` as its text content.

```js
const mockedComponent = Enzyme.mount(
React.createElement(window.index.Card, { name: 'nameVal' })
);

const h2Elem = mockedComponent.find('h2');

assert.equal(h2Elem.text(), 'nameVal');
async () => {
const testElem = await __prepTestComponent(window.index.Card, { name: 'nameVal' });
const h2Elem = testElem.querySelector('div > h2');
// trimming because we don't need to be picky about whitespace
assert.equal(h2Elem.textContent.trim(), 'nameVal');
}
```

You should create a `p` tag with the `className` of `card-title` inside your `div` element.

```js
const mockedComponent = Enzyme.mount(
React.createElement(window.index.Card)
);

const pElem = mockedComponent.find('p.card-title');

assert.equal(pElem.parent().type(), 'div');
async () => {
const testElem = await __prepTestComponent(window.index.Card);
const pElem = testElem.querySelector('div > p.card-title');
assert.exists(pElem);
}
```

Your `p` element with `className` of `card-title` should have `{title}` as its text content.

```js
const mockedComponent = Enzyme.mount(
React.createElement(window.index.Card, { title: 'titleVal' })
);

const pElem = mockedComponent.find('p.card-title');

assert.equal(pElem.text(), 'titleVal');
assert.equal(pElem.parent().type(), 'div');
async () => {
const testElem = await __prepTestComponent(window.index.Card, { title: 'titleVal' });
const pElem = testElem.querySelector('div > p.card-title');
// trimming because we don't need to be picky about whitespace
assert.equal(pElem.textContent.trim(), 'titleVal');
}
```

You should create another `p` element with `{bio}` as its text.

```js
const mockedComponent = Enzyme.mount(
React.createElement(window.index.Card, { bio: 'bioVal' })
);

const secondPElem = mockedComponent.children().childAt(2)

assert.equal(secondPElem.type(), 'p')
assert.equal(secondPElem.text(), 'bioVal');
assert.equal(secondPElem.parent().type(), 'div');
async () => {
const testElem = await __prepTestComponent(window.index.Card, {title: 'titleVal', bio: 'bioVal' });
// trimming because we don't need to be picky about whitespace
const texts = [...testElem.querySelectorAll('div > p')].map((p) => p.textContent.trim());
const bioText = texts.find((text) => text.includes('bioVal'));
assert.exists(bioText);
assert.equal(bioText, 'bioVal');
}
```

# --seed--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@ Inside the `App` component, return a pair of parentheses containing an empty str
You should export an `App` functional component.

```js
const mockedComponent = Enzyme.mount(
React.createElement(window.index.App)
);
assert.isFunction(window.index.App);
```

Your `App` component should return an empty string.

assert.lengthOf(mockedComponent.find('App'), 1);
```js
// This isn't a perfect test, since various return values are converted into
// empty strings, but it has to be a valid React component.
async() => {
const testElem = await __prepTestComponent(window.index.App);
assert.equal(testElem.textContent, '');
}
```

# --seed--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,35 @@ Inside your return statement, replace the empty string with a `div` element with

# --hints--

You should not have an empty string in your Card component.
Your `App` component should not render an empty string.

```js
assert.notMatch(code, /""/)
async () => {
const testElem = await __prepTestComponent(window.index.App);
assert.notEqual(testElem.innerHTML, '');
}
```

You should create a `div` element with the class `flex-container`.
Your `App` component should return a single `div` element.

```js
const mockedComponent = Enzyme.mount(
React.createElement(window.index.App)
);
async () => {
const testElem = await __prepTestComponent(window.index.App);
assert.equal(testElem.firstElementChild?.tagName, 'DIV');
assert.lengthOf(testElem.children, 1);
}
```
Your `div` should have a `className` property of `flex-container`.
assert.equal(mockedComponent.childAt(0).type(), 'div');
assert.isTrue(mockedComponent.childAt(0).hasClass('flex-container'));
```js
async () => {
const testElem = await __prepTestComponent(window.index.App);
assert.include([...testElem.firstElementChild.classList], 'flex-container');
}
```
# --seed--
## --seed-contents--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,48 @@ dashedName: step-6

# --description--

Now, use the `Card` component with the `name` prop set to `"Mark"`, the `title` prop set to `"Frontend developer"`, and the `bio` set to `"I like to work with different frontend technologies and play video games."`
Now, put the `Card` component into your `App` component. Give it the `name` prop set to `"Mark"`, the `title` prop set to `"Frontend developer"`, and the `bio` set to `"I like to work with different frontend technologies and play video games."`

# --hints--

You should use the `Card` component as an element with a `name` prop set to `"Mark"`.
You should use the `Card` component in your `App` component.

```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.App));
const cardItem = mockedComponent.find(window.index.Card);

const cardItemsProps = cardItem.props()

assert.equal(cardItem.props().name, "Mark")
async () => {
const testElem = await __prepTestComponent(window.index.App);
const card = testElem.querySelector('.card');
assert.exists(card);
}
```

You should use the `Card` component as an element with a `title` prop set to `"Frontend developer"`.
You should pass the `name` prop with value `"Mark"` to your `Card` component.

```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.App));
const cardItem = mockedComponent.find(window.index.Card);

const cardItemsProps = cardItem.props()

assert.equal(cardItem.props().title, "Frontend developer")
async () => {
const testElem = await __prepTestComponent(window.index.App);
const card = testElem.querySelector('.card');
assert.equal(card.querySelector('h2').textContent, 'Mark');
}
```

You should use the `Card` component as an element with a `bio` prop set to `"I like to work with different frontend technologies and play video games."`.
You should pass the `title` prop with value `"Frontend developer"` to your `Card` component.

```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.App));
const cardItem = mockedComponent.find(window.index.Card);
async () => {
const testElem = await __prepTestComponent(window.index.App);
const card = testElem.querySelector('.card');
assert.equal(card.querySelector('.card-title').textContent, 'Frontend developer');
}
```

const cardItemsProps = cardItem.props()
You should pass the `bio` prop with value `"I like to work with different frontend technologies and play video games."` to your `Card` component.

assert.equal(cardItem.props().bio, "I like to work with different frontend technologies and play video games.")
```js
async () => {
const testElem = await __prepTestComponent(window.index.App);
const card = testElem.querySelector('.card');
assert.equal(card.querySelector('p:last-child').textContent, 'I like to work with different frontend technologies and play video games.');
}
```

# --seed--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,34 @@ With that, your reusable profile card component project is complete!

# --hints--

You should use the `Card` component as an element with the appropriate props and first card values.
You should not modify the existing `Card` component in your `App` component.

```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.App));
const cardItems = mockedComponent.find(window.index.Card);
const zerothCard = document.querySelectorAll('.card')[0];

assert.equal(zerothCard.querySelector('h2').textContent, 'Mark');
assert.equal(zerothCard.querySelector('.card-title').textContent, 'Frontend developer');
assert.equal(zerothCard.querySelector('p:last-child').textContent, 'I like to work with different frontend technologies and play video games.');
```

const propsList = cardItems.map(item => item.props());
You should use the `Card` component as an element with the appropriate props and first card values.

assert.deepEqual(propsList[1], {
name: 'Tiffany',
title: 'Engineering manager',
bio: 'I have worked in tech for 15 years and love to help people grow in this industry.'
});
```js
const firstCard = document.querySelectorAll('.card')[1];

assert.equal(firstCard.querySelector('h2').textContent, 'Tiffany');
assert.equal(firstCard.querySelector('.card-title').textContent, 'Engineering manager');
assert.equal(firstCard.querySelector('p:last-child').textContent, 'I have worked in tech for 15 years and love to help people grow in this industry.');
```

You should use the `Card` component as an element with the appropriate props and second card values.

```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.App));
const cardItems = mockedComponent.find(window.index.Card);

const propsList = cardItems.map(item => item.props());
const secondCard = document.querySelectorAll('.card')[2];

assert.deepEqual(propsList[2], {
name: 'Doug',
title: 'Backend developer',
bio: 'I have been a software developer for over 20 years and I love working with Go and Rust.'
});
assert.equal(secondCard.querySelector('h2').textContent, 'Doug');
assert.equal(secondCard.querySelector('.card-title').textContent, 'Backend developer');
assert.equal(secondCard.querySelector('p:last-child').textContent, 'I have been a software developer for over 20 years and I love working with Go and Rust.');
```

# --seed--
Expand Down
17 changes: 17 additions & 0 deletions tools/client-plugins/browser-scripts/frame-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@ async function initTestFrame(e: InitTestFrameArg = { code: {} }) {
return o;
};

const __prepTestComponent = async (
component: React.ComponentType | React.FunctionComponent | string,
props: Record<string, unknown>
) => {
const testDiv = document.createElement('div');
const createdElement = window.React.createElement(component, props);

// @ts-expect-error the React version is determined at runtime so we can't define the types here
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/require-await
await window.React?.act(async () => {
// @ts-expect-error Same for ReactDOM as for React
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
window.ReactDOM?.createRoot(testDiv).render(createdElement);
});
return testDiv;
};

const { default: chai } = await import(/* webpackChunkName: "chai" */ 'chai');
const assert = chai.assert;
const __helpers = helpers;
Expand Down

0 comments on commit afade4a

Please sign in to comment.