Skip to content

Commit c80185a

Browse files
committed
feat: initial single component preview
1 parent 3e1c4cd commit c80185a

File tree

3 files changed

+160
-31
lines changed

3 files changed

+160
-31
lines changed

.codegenie/customizations/test.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Testing Practices Cheat Sheet
2+
3+
## Testing Libraries and Frameworks
4+
5+
- Jest: Main testing framework used for unit and integration tests
6+
- Mockito: Used for mocking objects and dependencies
7+
- PowerMock: Employed for mocking static methods and constructors
8+
9+
## Mocking and Stubbing Strategies
10+
11+
1. Jest Mock Functions
12+
13+
```javascript
14+
const mockFunction = jest.fn();
15+
mockFunction.mockReturnValue(expectedValue);
16+
```
17+
18+
2. Mockito Mocks
19+
20+
```java
21+
MyClass mockedObject = Mockito.mock(MyClass.class);
22+
Mockito.when(mockedObject.someMethod()).thenReturn(expectedValue);
23+
```
24+
25+
3. PowerMock for Static Methods
26+
```java
27+
PowerMockito.mockStatic(StaticClass.class);
28+
PowerMockito.when(StaticClass.staticMethod()).thenReturn(expectedValue);
29+
```
30+
31+
## Fake Implementations
32+
33+
1. In-memory Database
34+
35+
```javascript
36+
const fakeDatabase = {
37+
users: [],
38+
addUser: function (user) {
39+
this.users.push(user);
40+
},
41+
getUser: function (id) {
42+
return this.users.find((u) => u.id === id);
43+
},
44+
};
45+
```
46+
47+
2. HTTP Request Mocking
48+
```javascript
49+
jest.mock('axios');
50+
axios.get.mockResolvedValue({ data: mockResponseData });
51+
```
52+
53+
## Test Structure
54+
55+
1. Describe-It Pattern
56+
57+
```javascript
58+
describe('MyComponent', () => {
59+
it('should render correctly', () => {
60+
// Test implementation
61+
});
62+
});
63+
```
64+
65+
2. Setup and Teardown
66+
67+
```javascript
68+
beforeEach(() => {
69+
// Setup code
70+
});
71+
72+
afterEach(() => {
73+
// Teardown code
74+
});
75+
```
76+
77+
## Assertion Styles
78+
79+
1. Jest Expect
80+
81+
```javascript
82+
expect(result).toBe(expectedValue);
83+
expect(mockFunction).toHaveBeenCalledTimes(1);
84+
```
85+
86+
2. Mockito Verify
87+
```java
88+
Mockito.verify(mockedObject, Mockito.times(1)).someMethod();
89+
```
90+
91+
## Test Data Generation
92+
93+
1. Factory Functions
94+
95+
```javascript
96+
function createTestUser(overrides = {}) {
97+
return {
98+
id: 1,
99+
name: 'Test User',
100+
101+
...overrides,
102+
};
103+
}
104+
```
105+
106+
2. Faker Library (if used)
107+
```javascript
108+
const faker = require('faker');
109+
const testUser = {
110+
name: faker.name.findName(),
111+
email: faker.internet.email(),
112+
};
113+
```
114+
115+
## Asynchronous Testing
116+
117+
1. Async/Await
118+
119+
```javascript
120+
it('should fetch data asynchronously', async () => {
121+
const result = await fetchData();
122+
expect(result).toBeDefined();
123+
});
124+
```
125+
126+
2. Promise Chaining
127+
```javascript
128+
it('should handle promises', () => {
129+
return somePromiseFunction().then((result) => {
130+
expect(result).toBe(expectedValue);
131+
});
132+
});
133+
```
134+
135+
## Code Coverage
136+
137+
- Jest is configured to collect code coverage
138+
- Aim for high coverage, especially in critical paths
139+
- Use `istanbul` ignore comments for intentionally uncovered code
140+
141+
## Best Practices
142+
143+
1. Test one thing per test case
144+
2. Use descriptive test names
145+
3. Avoid test interdependence
146+
4. Mock external dependencies
147+
5. Use setup and teardown for common operations
148+
6. Prefer realistic test data
149+
7. Test both positive and negative scenarios
150+
8. Keep tests DRY (Don't Repeat Yourself)
151+
9. Regularly run and maintain tests

src/commands/lightning/dev/component.ts

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,48 +5,26 @@
55
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66
*/
77

8-
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
8+
import { SfCommand } from '@salesforce/sf-plugins-core';
99
import { Messages } from '@salesforce/core';
1010
import { cmpDev } from '@lwrjs/api';
1111

1212
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
1313
const messages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'lightning.dev.component');
1414

15-
export type LightningDevComponentResult = {
16-
path: string;
17-
};
18-
19-
export default class LightningDevComponent extends SfCommand<LightningDevComponentResult> {
15+
export default class LightningDevComponent extends SfCommand<void> {
2016
public static readonly summary = messages.getMessage('summary');
2117
public static readonly description = messages.getMessage('description');
2218
public static readonly examples = messages.getMessages('examples');
2319

24-
public static readonly flags = {
25-
name: Flags.string({
26-
summary: messages.getMessage('flags.name.summary'),
27-
description: messages.getMessage('flags.name.description'),
28-
char: 'n',
29-
required: false,
30-
}),
31-
// TODO should this be required or optional?
32-
// We don't technically need this if your components are simple / don't need any data from your org
33-
'target-org': Flags.requiredOrg(),
34-
};
35-
36-
public async run(): Promise<LightningDevComponentResult> {
37-
const { flags } = await this.parse(LightningDevComponent);
20+
public async run(): Promise<void> {
21+
this.log('Starting application on port 3000...');
3822

39-
const name = flags.name ?? 'world';
40-
this.log(`preview component: ${name}`);
23+
const port = parseInt(process.env.PORT ?? '3000', 10);
4124

42-
// TODO implement me
43-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
4425
await cmpDev({
45-
componentName: name,
26+
mode: 'dev',
27+
port,
4628
});
47-
48-
return {
49-
path: '',
50-
};
5129
}
5230
}

src/commands/lightning/dev/site.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import fs from 'node:fs';
88
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
99
import { Messages } from '@salesforce/core';
10-
import { expDev, LocalDevOptions, setupDev } from '@lwrjs/api';
10+
import { expDev, SitesLocalDevOptions, setupDev } from '@lwrjs/api';
1111
import { OrgUtils } from '../../../shared/orgUtils.js';
1212
import { PromptUtils } from '../../../shared/promptUtils.js';
1313
import { ExperienceSite } from '../../../shared/experience/expSite.js';
@@ -86,7 +86,7 @@ export default class LightningDevSite extends SfCommand<void> {
8686

8787
// Start the dev server
8888
const port = parseInt(process.env.PORT ?? '3000', 10);
89-
const startupParams: LocalDevOptions = {
89+
const startupParams: SitesLocalDevOptions = {
9090
sfCLI: true,
9191
authToken,
9292
open: process.env.OPEN_BROWSER === 'false' ? false : true,

0 commit comments

Comments
 (0)