Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scaffolds: Don't generate unused methods #6221

Merged
merged 31 commits into from Sep 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a51bd69
Scaffolds: Don't generate unused methods
Tobbe Aug 16, 2022
8f047cd
Update test snapshots
Tobbe Aug 16, 2022
ec54e35
Updat test-project fixture
Tobbe Aug 16, 2022
84c37ab
Add missing test-project fixtures
Tobbe Aug 16, 2022
b03d69f
Re-add resolutions to test-project fixure
Tobbe Aug 16, 2022
90b1aac
Merge branch 'main' into tobbe-scaffold-unused-methods
Tobbe Aug 16, 2022
b29f87d
Move formatting functions to a separate file
Tobbe Aug 17, 2022
6e00c48
Merge branch 'main' of https://github.com/redwoodjs/redwood into tobb…
Tobbe Sep 16, 2022
6298ff8
Update fixture and start fixing tests
Tobbe Sep 16, 2022
876fbe4
Fix cli tests
Tobbe Sep 16, 2022
7eb4f7a
Merge branch 'main' into tobbe-scaffold-unused-methods
Tobbe Sep 16, 2022
1efe375
Update formattingFunctions
Tobbe Sep 16, 2022
01fd84b
Merge branch 'main' into tobbe-scaffold-unused-methods
Tobbe Sep 16, 2022
d76cdf3
Fix formattingFunction output filename
Tobbe Sep 17, 2022
78f491b
Update test project fixture
Tobbe Sep 17, 2022
279746e
Merge branch 'main' into tobbe-scaffold-unused-methods
Tobbe Sep 17, 2022
6db3537
Add tests for formattingFunctions
Tobbe Sep 17, 2022
4429a0e
scaffold 19 files
Tobbe Sep 17, 2022
5908b10
Import screen
Tobbe Sep 18, 2022
532b743
Merge branch 'main' into tobbe-scaffold-unused-methods
Tobbe Sep 18, 2022
7fbb0c5
Change name of formatters file
Tobbe Sep 18, 2022
3919917
Merge branch 'main' into tobbe-scaffold-unused-methods
Tobbe Sep 19, 2022
3cc5d07
Merge branch 'main' of https://github.com/redwoodjs/redwood into tobb…
Tobbe Sep 19, 2022
84ec112
Update snapshots
Tobbe Sep 19, 2022
ea90bdd
Merge branch 'tobbe-scaffold-unused-methods' of https://github.com/To…
Tobbe Sep 19, 2022
7ca7551
Better variable names
Tobbe Sep 20, 2022
7d9629c
Add support for JS projects too, and better test coverage
Tobbe Sep 20, 2022
2b92533
Add humanize-string to rw app
Tobbe Sep 20, 2022
b34071c
Separate task for installing helper packages
Tobbe Sep 21, 2022
6ef72d1
Check package.json for installed package
Tobbe Sep 21, 2022
5586e10
TransformTSToJS
Tobbe Sep 21, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -10,7 +10,7 @@ export const standard = defineScenario<Prisma.PostCreateArgs>({
body: 'String',
author: {
create: {
email: 'String8713726',
email: 'String4857147',
hashedPassword: 'String',
fullName: 'String',
salt: 'String',
Expand All @@ -24,7 +24,7 @@ export const standard = defineScenario<Prisma.PostCreateArgs>({
body: 'String',
author: {
create: {
email: 'String8610091',
email: 'String1125871',
hashedPassword: 'String',
fullName: 'String',
salt: 'String',
Expand Down
Expand Up @@ -6,15 +6,15 @@ export const standard = defineScenario<Prisma.UserCreateArgs>({
user: {
one: {
data: {
email: 'String7466649',
email: 'String4815975',
hashedPassword: 'String',
fullName: 'String',
salt: 'String',
},
},
two: {
data: {
email: 'String5806082',
email: 'String3376651',
hashedPassword: 'String',
fullName: 'String',
salt: 'String',
Expand Down
2 changes: 1 addition & 1 deletion __fixtures__/test-project/web/package.json
Expand Up @@ -22,7 +22,7 @@
"react-dom": "17.0.2"
},
"devDependencies": {
"autoprefixer": "^10.4.10",
"autoprefixer": "^10.4.11",
"postcss": "^8.4.16",
"postcss-loader": "^7.0.1",
"prettier-plugin-tailwindcss": "^0.1.13",
Expand Down
@@ -1,4 +1,3 @@
import humanize from 'humanize-string'
import type {
DeleteContactMutationVariables,
FindContactById,
Expand All @@ -8,6 +7,8 @@ import { Link, routes, navigate } from '@redwoodjs/router'
import { useMutation } from '@redwoodjs/web'
import { toast } from '@redwoodjs/web/toast'

import { timeTag } from 'src/lib/formatters'

const DELETE_CONTACT_MUTATION = gql`
mutation DeleteContactMutation($id: Int!) {
deleteContact(id: $id) {
Expand All @@ -16,39 +17,6 @@ const DELETE_CONTACT_MUTATION = gql`
}
`

const formatEnum = (values: string | string[] | null | undefined) => {
if (values) {
if (Array.isArray(values)) {
const humanizedValues = values.map((value) => humanize(value))
return humanizedValues.join(', ')
} else {
return humanize(values as string)
}
}
}

const jsonDisplay = (obj: unknown) => {
return (
<pre>
<code>{JSON.stringify(obj, null, 2)}</code>
</pre>
)
}

const timeTag = (datetime?: string) => {
return (
datetime && (
<time dateTime={datetime} title={datetime}>
{new Date(datetime).toUTCString()}
</time>
)
)
}

const checkboxInputTag = (checked: boolean) => {
return <input type="checkbox" checked={checked} disabled />
}

interface Props {
contact: NonNullable<FindContactById['contact']>
}
Expand Down
@@ -1,4 +1,3 @@
import humanize from 'humanize-string'
import type {
DeleteContactMutationVariables,
FindContacts,
Expand All @@ -9,6 +8,7 @@ import { useMutation } from '@redwoodjs/web'
import { toast } from '@redwoodjs/web/toast'

import { QUERY } from 'src/components/Contact/ContactsCell'
import { timeTag, truncate } from 'src/lib/formatters'

const DELETE_CONTACT_MUTATION = gql`
mutation DeleteContactMutation($id: Int!) {
Expand All @@ -18,45 +18,6 @@ const DELETE_CONTACT_MUTATION = gql`
}
`

const MAX_STRING_LENGTH = 150

const formatEnum = (values: string | string[] | null | undefined) => {
if (values) {
if (Array.isArray(values)) {
const humanizedValues = values.map((value) => humanize(value))
return humanizedValues.join(', ')
} else {
return humanize(values as string)
}
}
}

const truncate = (value: string | number) => {
const output = value?.toString()
if (output?.length > MAX_STRING_LENGTH) {
return output.substring(0, MAX_STRING_LENGTH) + '...'
}
return output ?? ''
}

const jsonTruncate = (obj: unknown) => {
return truncate(JSON.stringify(obj, null, 2))
}

const timeTag = (datetime?: string) => {
return (
datetime && (
<time dateTime={datetime} title={datetime}>
{new Date(datetime).toUTCString()}
</time>
)
)
}

const checkboxInputTag = (checked: boolean) => {
return <input type="checkbox" checked={checked} disabled />
}

const ContactsList = ({ contacts }: FindContacts) => {
const [deleteContact] = useMutation(DELETE_CONTACT_MUTATION, {
onCompleted: () => {
Expand Down
36 changes: 2 additions & 34 deletions __fixtures__/test-project/web/src/components/Post/Post/Post.tsx
@@ -1,10 +1,11 @@
import humanize from 'humanize-string'
import type { DeletePostMutationVariables, FindPostById } from 'types/graphql'

import { Link, routes, navigate } from '@redwoodjs/router'
import { useMutation } from '@redwoodjs/web'
import { toast } from '@redwoodjs/web/toast'

import { timeTag } from 'src/lib/formatters'

const DELETE_POST_MUTATION = gql`
mutation DeletePostMutation($id: Int!) {
deletePost(id: $id) {
Expand All @@ -13,39 +14,6 @@ const DELETE_POST_MUTATION = gql`
}
`

const formatEnum = (values: string | string[] | null | undefined) => {
if (values) {
if (Array.isArray(values)) {
const humanizedValues = values.map((value) => humanize(value))
return humanizedValues.join(', ')
} else {
return humanize(values as string)
}
}
}

const jsonDisplay = (obj: unknown) => {
return (
<pre>
<code>{JSON.stringify(obj, null, 2)}</code>
</pre>
)
}

const timeTag = (datetime?: string) => {
return (
datetime && (
<time dateTime={datetime} title={datetime}>
{new Date(datetime).toUTCString()}
</time>
)
)
}

const checkboxInputTag = (checked: boolean) => {
return <input type="checkbox" checked={checked} disabled />
}

interface Props {
post: NonNullable<FindPostById['post']>
}
Expand Down
@@ -1,11 +1,11 @@
import humanize from 'humanize-string'
import type { DeletePostMutationVariables, FindPosts } from 'types/graphql'

import { Link, routes } from '@redwoodjs/router'
import { useMutation } from '@redwoodjs/web'
import { toast } from '@redwoodjs/web/toast'

import { QUERY } from 'src/components/Post/PostsCell'
import { timeTag, truncate } from 'src/lib/formatters'

const DELETE_POST_MUTATION = gql`
mutation DeletePostMutation($id: Int!) {
Expand All @@ -15,45 +15,6 @@ const DELETE_POST_MUTATION = gql`
}
`

const MAX_STRING_LENGTH = 150

const formatEnum = (values: string | string[] | null | undefined) => {
if (values) {
if (Array.isArray(values)) {
const humanizedValues = values.map((value) => humanize(value))
return humanizedValues.join(', ')
} else {
return humanize(values as string)
}
}
}

const truncate = (value: string | number) => {
const output = value?.toString()
if (output?.length > MAX_STRING_LENGTH) {
return output.substring(0, MAX_STRING_LENGTH) + '...'
}
return output ?? ''
}

const jsonTruncate = (obj: unknown) => {
return truncate(JSON.stringify(obj, null, 2))
}

const timeTag = (datetime?: string) => {
return (
datetime && (
<time dateTime={datetime} title={datetime}>
{new Date(datetime).toUTCString()}
</time>
)
)
}

const checkboxInputTag = (checked: boolean) => {
return <input type="checkbox" checked={checked} disabled />
}

const PostsList = ({ posts }: FindPosts) => {
const [deletePost] = useMutation(DELETE_POST_MUTATION, {
onCompleted: () => {
Expand Down
115 changes: 115 additions & 0 deletions __fixtures__/test-project/web/src/lib/formatters.test.tsx
@@ -0,0 +1,115 @@
import { render, waitFor, screen } from '@redwoodjs/testing/web'

import {
formatEnum,
jsonTruncate,
truncate,
timeTag,
checkboxInputTag,
} from './formatters'

describe('formatEnum', () => {
it('handles nullish values', () => {
expect(formatEnum(null)).toEqual('')
expect(formatEnum('')).toEqual('')
expect(formatEnum(undefined)).toEqual('')
})

it('formats a list of values', () => {
expect(
formatEnum(['RED', 'ORANGE', 'YELLOW', 'GREEN', 'BLUE', 'VIOLET'])
).toEqual('Red, Orange, Yellow, Green, Blue, Violet')
})

it('formats a single value', () => {
expect(formatEnum('DARK_BLUE')).toEqual('Dark blue')
})

it('returns an empty string for values of the wrong type (for JS projects)', () => {
// @ts-expect-error - Testing JS scenario
expect(formatEnum(5)).toEqual('')
})
})

describe('truncate', () => {
it('truncates really long strings', () => {
expect(truncate('na '.repeat(1000) + 'batman').length).toBeLessThan(1000)
expect(truncate('na '.repeat(1000) + 'batman')).not.toMatch(/batman/)
})

it('does not modify short strings', () => {
expect(truncate('Short strinG')).toEqual('Short strinG')
})

it('adds ... to the end of truncated strings', () => {
expect(truncate('repeat'.repeat(1000))).toMatch(/\w\.\.\.$/)
})

it('accepts numbers', () => {
expect(truncate(123)).toEqual('123')
expect(truncate(0)).toEqual('0')
expect(truncate(0o000)).toEqual('0')
})

it('handles arguments of invalid type', () => {
// @ts-expect-error - Testing JS scenario
expect(truncate(false)).toEqual('false')

expect(truncate(undefined)).toEqual('')
expect(truncate(null)).toEqual('')
})
})

describe('jsonTruncate', () => {
it('truncates large json structures', () => {
expect(
jsonTruncate({
foo: 'foo',
bar: 'bar',
baz: 'baz',
kittens: 'kittens meow',
bazinga: 'Sheldon',
nested: {
foobar: 'I have no imagination',
two: 'Second nested item',
},
five: 5,
bool: false,
})
).toMatch(/.+\n.+\w\.\.\.$/s)
})
})

describe('timeTag', () => {
it('renders a date', async () => {
render(<div>{timeTag(new Date('1970-08-20').toUTCString())}</div>)

await waitFor(() => screen.getByText(/1970.*00:00:00/))
})

it('can take an empty input string', async () => {
expect(timeTag('')).toEqual('')
})
})

describe('checkboxInputTag', () => {
it('can be checked', () => {
render(checkboxInputTag(true))
expect(screen.getByRole('checkbox')).toBeChecked()
})

it('can be unchecked', () => {
render(checkboxInputTag(false))
expect(screen.getByRole('checkbox')).not.toBeChecked()
})

it('is disabled when checked', () => {
render(checkboxInputTag(true))
expect(screen.getByRole('checkbox')).toBeDisabled()
})

it('is disabled when unchecked', () => {
render(checkboxInputTag(false))
expect(screen.getByRole('checkbox')).toBeDisabled()
})
})