Great, thank you. Now using the below test file for the `noUnloadListeners` function, write tests for `noMissingNoopenerAttribute`

---
import { describe, expect, it } from 'vitest';
import { codeBlock } from 'common-tags';
import type { ProjectData } from '../project-data';
import { parseFileContents } from '../utils/parse-js-ts';
import { noUnloadListeners } from './no-unload-listeners';

const FILE\_PATH = 'apps/docs/pages/index.jsx';

function createMockProjectData(isTestEnabled = true): ProjectData {
 return {
 getConformanceConfig(): { isTestEnabled: (\_rule: string) => boolean } {
 return {
 isTestEnabled: (\_rule: string): boolean => isTestEnabled,
 };
 },
 getWorkspaceName: (): string => 'test-workspace',
 } as ProjectData;
}

describe('noUnloadListeners', () => {
 it('returns no errors when there are no unload event listeners.', () => {
 const codeAst = parseFileContents(
 codeBlock`
 export default function Index() {
 return Hello world;
 }
 `,
 FILE\_PATH,
 );
 const errors = noUnloadListeners(
 createMockProjectData(),
 FILE\_PATH,
 codeAst,
 );
 expect(errors).toMatchInlineSnapshot('[]');
 });

 it('returns an error when window.unload exists.', () => {
 const codeAst = parseFileContents(
 codeBlock`
 export default function handlePageUnload() {
 window.onunload = (event) => {
 console.log('Page is about to be unloaded.');
 };
 }
 `,
 FILE\_PATH,
 );
 const errors = noUnloadListeners(
 createMockProjectData(),
 FILE\_PATH,
 codeAst,
 );
 expect(errors).toMatchInlineSnapshot(`
 [
 {
 "location": {
 "filePath": "apps/docs/pages/index.jsx",
 "range": {
 "end": [
 3,
 3,
 ],
 "start": [
 1,
 2,
 ],
 },
 "workspace": "test-workspace",
 },
 "message": "The \`unload\` event does not fire reliably and listening for it can prevent browser optimizations like the Back-Forward Cache (bfcache).

 Consider using the \`pagehide\`, \`visibilitychange\`, or \`beforeunload\` events instead.

 See https://web.dev/bfcache for more information.",
 "testName": "BFCACHE\_INTEGRITY\_NO\_UNLOAD\_LISTENERS",
 },
 ]
 `);
 });

 it("returns an error when window.addEventListener('unload') exists.", () => {
 const codeAst = parseFileContents(
 codeBlock`
 export default function Index() {
 window.addEventListener('unload', () => {});
 }
 `,
 FILE\_PATH,
 );

 const errors = noUnloadListeners(
 createMockProjectData(),
 FILE\_PATH,
 codeAst,
 );
 expect(errors).toMatchInlineSnapshot(`
 [
 {
 "location": {
 "filePath": "apps/docs/pages/index.jsx",
 "range": {
 "end": [
 1,
 45,
 ],
 "start": [
 1,
 2,
 ],
 },
 "workspace": "test-workspace",
 },
 "message": "The \`unload\` event does not fire reliably and listening for it can prevent browser optimizations like the Back-Forward Cache (bfcache).

 Consider using the \`pagehide\`, \`visibilitychange\`, or \`beforeunload\` events instead.

 See https://web.dev/bfcache for more information.",
 "testName": "BFCACHE\_INTEGRITY\_NO\_UNLOAD\_LISTENERS",
 },
 ]
 `);
 });

 it('returns no errors when window.addEventListener is used to listen to any other event.', () => {
 const codeAst = parseFileContents(
 codeBlock`
 export default function Index() {
 window.addEventListener('pagehide', () => {});
 }
 `,
 FILE\_PATH,
 );

 const errors = noUnloadListeners(
 createMockProjectData(),
 FILE\_PATH,
 codeAst,
 );
 expect(errors).toMatchInlineSnapshot('[]');
 });

 it('returns no errors when rule is disabled.', () => {
 const codeAst = parseFileContents(
 codeBlock`
 export default function Index() {
 window.onunload = () => {};
 }
 `,
 FILE\_PATH,
 );
 const errors = noUnloadListeners(
 createMockProjectData(false),
 FILE\_PATH,
 codeAst,
 );
 expect(errors).toMatchInlineSnapshot('[]');
 });
});
---
고마워요. 이제 아래 테스트 파일을 사용하여 `noUnloadListeners` 함수에 대한 테스트를 작성하고 `noMissingNoopenerAttribute`에 대한 테스트를 작성합니다.---'vitest'에서 { describe, expect, it }를 가져옵니다;'common-tags'에서 { codeBlock }을 임포트합니다;'../project-data'에서 유형 { ProjectData }를 가져옵니다;import { parseFileContents } '../utils/parse-js-ts'에서 가져옵니다;'./no-unload-listeners'에서 { noUnloadListeners }를 임포트합니다;const FILE\_PATH = 'apps/docs/pages/index.jsx';함수 createMockProjectData(isTestEnabled = true): ProjectData { 반환 { getConformanceConfig(): { isTestEnabled: (\_rule: string) => boolean } { 반환 { isTestEnabled: (\_rule: string): boolean => isTestEnabled, }; }, getWorkspaceName: (): 문자열 => 'test-workspace', }를 프로젝트 데이터로 저장합니다;}describe('noUnloadListeners', () => { it('언로드 이벤트 리스너가 없을 때 에러를 반환하지 않습니다.', () => { const codeAst = parseFileContents( codeBlock` export 기본 함수 Index() { return Hello world; } `, FILE\_PATH, ); const errors = noUnloadListeners( createMockProjectData(), FILE\_PATH, codeAst, ); expect(errors).toMatchInlineSnapshot('[]'); }); it('window.unload가 존재할 때 오류를 반환합니다.', () => { const codeAst = parseFileContents( codeBlock` 내보내기 기본 함수 handlePageUnload() { window.onunload = (event) => { console.log('페이지가 언로드되려고 합니다.'); }; } `, FILE\_PATH, ); const errors = noUnloadListeners( createMockProjectData(), FILE\_PATH, codeAst, ); expect(errors).toMatchInlineSnapshot(` [ { "위치": { "파일 경로": "apps/docs/pages/index.jsx", "범위": { "end": [ 3, 3, ], "start": [ 1, 2, ], }, "작업 공간": "test-workspace", }, "메시지": "\`언로드\` 이벤트는 안정적으로 실행되지 않으며 이를 수신하면 역방향 캐시(bfcache)와 같은 브라우저 최적화를 방지할 수 있습니다. 대신 \`pagehide\`, \`visibilitychange\` 또는 \`beforeunload\` 이벤트를 사용하는 것을 고려하십시오. 자세한 내용은 https://web.dev/bfcache 을 참조하세요.", "testName": "bfcache\_integrity\_no\_unload\_listeners", }, ] `); }); it("window.addEventListener('unload')가 존재할 때 오류를 반환합니다.", () => { const codeAst = parseFileContents( codeBlock` 내보내기 기본 함수 Index() { window.addEventListener('unload', () => {}); } `, FILE\_PATH, ); const errors = noUnloadListeners( createMockProjectData(), FILE\_PATH, codeAst, ); expect(errors).toMatchInlineSnapshot(` [ { "위치": { "파일 경로": "apps/docs/pages/index.jsx", "범위": { "end": [ 1, 45, ], "start": [ 1, 2, ], }, "작업 공간": "test-workspace", }, "메시지": "\`언로드\` 이벤트는 안정적으로 실행되지 않으며 이를 수신하면 역방향 캐시(bfcache)와 같은 브라우저 최적화를 방지할 수 있습니다. 대신 \`pagehide\`, \`visibilitychange\` 또는 \`beforeunload\` 이벤트를 사용하는 것을 고려하십시오. 자세한 내용은 https://web.dev/bfcache 을 참조하세요.", "testName": "bfcache\_integrity\_no\_unload\_listeners", }, ] `); }); it('window.addEventListener가 다른 이벤트를 수신하는 데 사용될 때 오류를 반환하지 않습니다.', () => { const codeAst = parseFileContents( codeBlock` 내보내기 기본 함수 Index() { window.addEventListener('pagehide', () => {}); } `, FILE\_PATH, ); const errors = noUnloadListeners( createMockProjectData(), FILE\_PATH, codeAst, ); expect(errors).toMatchInlineSnapshot('[]'); }); it('규칙이 비활성화되면 오류를 반환하지 않습니다.', () => { const codeAst = parseFileContents( codeBlock` 내보내기 기본 함수 Index() { window.onunload = () => {}; } `, FILE\_PATH, ); const errors = noUnloadListeners( createMockProjectData(false), FILE\_PATH, codeAst, ); expect(errors).toMatchInlineSnapshot('[]'); });});---