@simplysm/eslint-plugin 12.9.17 → 12.9.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,21 +8,22 @@ export default {
8
8
  description: "'NotImplementError' 사용 경고",
9
9
  },
10
10
  schema: [],
11
+ messages: {
12
+ noThrowNotImplementError: "{{text}}",
13
+ },
11
14
  },
12
- create: (context) => {
15
+ defaultOptions: [],
16
+ create(context) {
13
17
  const parserServices = getParserServices(context);
14
- const program = parserServices.program;
15
- const checker = program.getTypeChecker();
18
+ const checker = parserServices.program.getTypeChecker();
16
19
 
17
- function tryGetThrowArgumentType(node) {
20
+ const tryGetThrowArgumentType = (node) => {
18
21
  switch (node.type) {
19
22
  case AST_NODE_TYPES.Identifier:
20
23
  case AST_NODE_TYPES.CallExpression:
21
24
  case AST_NODE_TYPES.NewExpression:
22
- case AST_NODE_TYPES.MemberExpression: {
23
- const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);
24
- return checker.getTypeAtLocation(tsNode);
25
- }
25
+ case AST_NODE_TYPES.MemberExpression:
26
+ return checker.getTypeAtLocation(parserServices.esTreeNodeToTSNodeMap.get(node));
26
27
 
27
28
  case AST_NODE_TYPES.AssignmentExpression:
28
29
  return tryGetThrowArgumentType(node.right);
@@ -43,28 +44,39 @@ export default {
43
44
  default:
44
45
  return undefined;
45
46
  }
46
- }
47
+ };
47
48
 
48
- function checkThrowArgument(node) {
49
- if (node.type === AST_NODE_TYPES.AwaitExpression || node.type === AST_NODE_TYPES.YieldExpression) {
49
+ const checkThrowArgument = (node) => {
50
+ if (
51
+ node.type === AST_NODE_TYPES.AwaitExpression ||
52
+ node.type === AST_NODE_TYPES.YieldExpression
53
+ ) {
50
54
  return;
51
55
  }
52
56
 
53
57
  const type = tryGetThrowArgumentType(node);
54
- if (type && type.getSymbol() && type.getSymbol().getName() === "NotImplementError") {
58
+ if (type?.getSymbol()?.getName() === "NotImplementError") {
59
+ let msg;
60
+
61
+ if (
62
+ node.type === AST_NODE_TYPES.NewExpression &&
63
+ node.arguments?.[0]?.type === AST_NODE_TYPES.Literal
64
+ ) {
65
+ msg = String(node.arguments[0].value ?? "");
66
+ }
67
+
55
68
  context.report({
56
- node: node,
57
- message: node["arguments"]["value"] || "구현되어있지 않습니다", //"'NotImplementError'를 'throw'하고 있습니다."
69
+ node,
70
+ messageId: "noThrowNotImplementError",
71
+ data: { text: msg ?? "구현되어있지 않습니다" },
58
72
  });
59
73
  }
60
- }
74
+ };
61
75
 
62
76
  return {
63
77
  ThrowStatement(node) {
64
- if (node.argument) {
65
- checkThrowArgument(node.argument);
66
- }
78
+ checkThrowArgument(node.argument);
67
79
  },
68
80
  };
69
81
  },
70
- };
82
+ };
@@ -1,6 +1,6 @@
1
1
  import { RuleTester } from 'eslint';
2
- import rule from '../src/rules/ng-template-no-todo-comments';
3
- import { describe, expect, it } from "vitest";
2
+ import rule from '../src/rules/ng-template-no-todo-comments.js';
3
+ import { describe, expect } from "vitest";
4
4
  import { templateParser } from "angular-eslint";
5
5
 
6
6
  describe('ng-template-no-todo-comments 규칙 테스트', () => {
@@ -19,50 +19,50 @@ describe('ng-template-no-todo-comments 규칙 테스트', () => {
19
19
  // ESLint 9 플랫 설정 형식 사용
20
20
  const ruleTester = new RuleTester({
21
21
  languageOptions: {
22
- parser: templateParser
23
- }
22
+ parser: templateParser,
23
+ },
24
24
  });
25
25
 
26
26
  // 기본 템플릿 테스트
27
27
  describe('기본 템플릿 테스트', () => {
28
28
  // 유효한 템플릿 테스트 (규칙 위반 없음)
29
- it('정상적인 HTML 템플릿은 경고가 없어야 함', () => {
29
+ describe('정상적인 HTML 템플릿은 경고가 없어야 함', () => {
30
30
  ruleTester.run('ng-template-no-todo-comments', rule, {
31
31
  valid: [
32
32
  {
33
33
  code: createComponentWithTemplate('<div>정상적인 HTML 템플릿</div>'),
34
- filename: 'test.component.ts'
35
- }
34
+ filename: 'test.component.ts',
35
+ },
36
36
  ],
37
- invalid: []
37
+ invalid: [],
38
38
  });
39
39
  });
40
40
 
41
- it('일반 주석은 경고가 없어야 함', () => {
41
+ describe('일반 주석은 경고가 없어야 함', () => {
42
42
  ruleTester.run('ng-template-no-todo-comments', rule, {
43
43
  valid: [
44
44
  {
45
45
  code: createComponentWithTemplate('<!-- 일반 주석 -->'),
46
- filename: 'test.component.ts'
47
- }
46
+ filename: 'test.component.ts',
47
+ },
48
48
  ],
49
- invalid: []
49
+ invalid: [],
50
50
  });
51
51
  });
52
52
 
53
- it('NOTE 주석은 경고가 없어야 함', () => {
53
+ describe('NOTE 주석은 경고가 없어야 함', () => {
54
54
  ruleTester.run('ng-template-no-todo-comments', rule, {
55
55
  valid: [
56
56
  {
57
57
  code: createComponentWithTemplate('<!-- NOTE: 이것은 메모입니다 -->'),
58
- filename: 'test.component.ts'
59
- }
58
+ filename: 'test.component.ts',
59
+ },
60
60
  ],
61
- invalid: []
61
+ invalid: [],
62
62
  });
63
63
  });
64
64
 
65
- it('여러 줄의 일반 주석은 경고가 없어야 함', () => {
65
+ describe('여러 줄의 일반 주석은 경고가 없어야 함', () => {
66
66
  ruleTester.run('ng-template-no-todo-comments', rule, {
67
67
  valid: [
68
68
  {
@@ -70,30 +70,29 @@ describe('ng-template-no-todo-comments 규칙 테스트', () => {
70
70
  <!-- 여러 줄에 걸친
71
71
  일반 주석입니다 -->
72
72
  </div>`),
73
- filename: 'test.component.ts'
74
- }
73
+ filename: 'test.component.ts',
74
+ },
75
75
  ],
76
- invalid: []
76
+ invalid: [],
77
77
  });
78
78
  });
79
79
  });
80
80
 
81
- // TODO 주석 테스트
82
81
  describe('TODO 주석 테스트', () => {
83
- it('단일 TODO 주석은 경고가 발생해야 함', () => {
82
+ describe('단일 TODO 주석은 경고가 발생해야 함', () => {
84
83
  ruleTester.run('ng-template-no-todo-comments', rule, {
85
84
  valid: [],
86
85
  invalid: [
87
86
  {
88
87
  code: createComponentWithTemplate('<!-- TODO: 이 기능 구현 필요 -->'),
89
88
  filename: 'test.component.ts',
90
- errors: [{ messageId: 'noTodo' }]
91
- }
92
- ]
89
+ errors: [{ messageId: 'noTodo' }],
90
+ },
91
+ ],
93
92
  });
94
93
  });
95
94
 
96
- it('요소 내부의 TODO 주석은 경고가 발생해야 함', () => {
95
+ describe('요소 내부의 TODO 주석은 경고가 발생해야 함', () => {
97
96
  ruleTester.run('ng-template-no-todo-comments', rule, {
98
97
  valid: [],
99
98
  invalid: [
@@ -103,13 +102,13 @@ describe('ng-template-no-todo-comments 규칙 테스트', () => {
103
102
  <span>임시 내용</span>
104
103
  </div>`),
105
104
  filename: 'test.component.ts',
106
- errors: [{ messageId: 'noTodo' }]
107
- }
108
- ]
105
+ errors: [{ messageId: 'noTodo' }],
106
+ },
107
+ ],
109
108
  });
110
109
  });
111
110
 
112
- it('주석 텍스트 안에 TODO 키워드가 있으면 경고가 발생해야 함', () => {
111
+ describe('주석 텍스트 안에 TODO 키워드가 있으면 경고가 발생해야 함', () => {
113
112
  ruleTester.run('ng-template-no-todo-comments', rule, {
114
113
  valid: [],
115
114
  invalid: [
@@ -118,13 +117,13 @@ describe('ng-template-no-todo-comments 규칙 테스트', () => {
118
117
  <!-- 이 부분은 TODO: 수정이 필요합니다 -->
119
118
  </div>`),
120
119
  filename: 'test.component.ts',
121
- errors: [{ messageId: 'noTodo' }]
122
- }
123
- ]
120
+ errors: [{ messageId: 'noTodo' }],
121
+ },
122
+ ],
124
123
  });
125
124
  });
126
125
 
127
- it('여러 줄 주석 내의 TODO 키워드도 감지해야 함', () => {
126
+ describe('여러 줄 주석 내의 TODO 키워드도 감지해야 함', () => {
128
127
  ruleTester.run('ng-template-no-todo-comments', rule, {
129
128
  valid: [],
130
129
  invalid: [
@@ -137,13 +136,13 @@ describe('ng-template-no-todo-comments 규칙 테스트', () => {
137
136
  -->
138
137
  </div>`),
139
138
  filename: 'test.component.ts',
140
- errors: [{ messageId: 'noTodo' }]
141
- }
142
- ]
139
+ errors: [{ messageId: 'noTodo' }],
140
+ },
141
+ ],
143
142
  });
144
143
  });
145
144
 
146
- it('여러 개의 TODO 주석은 각각 감지되어야 함', () => {
145
+ describe('여러 개의 TODO 주석은 각각 감지되어야 함', () => {
147
146
  ruleTester.run('ng-template-no-todo-comments', rule, {
148
147
  valid: [],
149
148
  invalid: [
@@ -154,17 +153,17 @@ describe('ng-template-no-todo-comments 규칙 테스트', () => {
154
153
  filename: 'test.component.ts',
155
154
  errors: [
156
155
  { messageId: 'noTodo' },
157
- { messageId: 'noTodo' }
158
- ]
159
- }
160
- ]
156
+ { messageId: 'noTodo' },
157
+ ],
158
+ },
159
+ ],
161
160
  });
162
161
  });
163
162
  });
164
163
 
165
164
  // ng-template 지시자 테스트
166
165
  describe('ng-template 지시자 테스트', () => {
167
- it('ng-template 안의 TODO 주석을 감지해야 함', () => {
166
+ describe('ng-template 안의 TODO 주석을 감지해야 함', () => {
168
167
  ruleTester.run('ng-template-no-todo-comments', rule, {
169
168
  valid: [],
170
169
  invalid: [
@@ -180,13 +179,13 @@ describe('ng-template-no-todo-comments 규칙 테스트', () => {
180
179
  export class TestComponent {}
181
180
  `,
182
181
  filename: 'test.component.ts',
183
- errors: [{ messageId: 'noTodo' }]
184
- }
185
- ]
182
+ errors: [{ messageId: 'noTodo' }],
183
+ },
184
+ ],
186
185
  });
187
186
  });
188
187
 
189
- it('ng-template 지시자가 있는 경우에도 정상 작동해야 함', () => {
188
+ describe('ng-template 지시자가 있는 경우에도 정상 작동해야 함', () => {
190
189
  ruleTester.run('ng-template-no-todo-comments', rule, {
191
190
  valid: [
192
191
  {
@@ -205,14 +204,14 @@ describe('ng-template-no-todo-comments 규칙 테스트', () => {
205
204
  })
206
205
  export class TestComponent {}
207
206
  `,
208
- filename: 'test.component.ts'
209
- }
207
+ filename: 'test.component.ts',
208
+ },
210
209
  ],
211
- invalid: []
210
+ invalid: [],
212
211
  });
213
212
  });
214
213
 
215
- it('ng-template 지시자가 있는 경우 TODO 주석을 감지해야 함', () => {
214
+ describe('ng-template 지시자가 있는 경우 TODO 주석을 감지해야 함', () => {
216
215
  ruleTester.run('ng-template-no-todo-comments', rule, {
217
216
  valid: [],
218
217
  invalid: [
@@ -233,16 +232,16 @@ describe('ng-template-no-todo-comments 규칙 테스트', () => {
233
232
  export class TestComponent {}
234
233
  `,
235
234
  filename: 'test.component.ts',
236
- errors: [{ messageId: 'noTodo' }]
237
- }
238
- ]
235
+ errors: [{ messageId: 'noTodo' }],
236
+ },
237
+ ],
239
238
  });
240
239
  });
241
240
  });
242
241
 
243
242
  // 정규식 테스트
244
243
  describe('정규식 패턴 테스트', () => {
245
- it('정규식이 올바르게 TODO 주석을 감지해야 함', () => {
244
+ describe('정규식이 올바르게 TODO 주석을 감지해야 함', () => {
246
245
  const testHtml = `
247
246
  <!-- 일반 주석 -->
248
247
  <!-- TODO: 할 일 항목 -->
@@ -0,0 +1,213 @@
1
+ import { afterAll, describe, it } from 'vitest';
2
+ import { RuleTester } from '@typescript-eslint/rule-tester';
3
+ import rule from '../src/rules/ts-no-buffer-in-typedarray-context.js';
4
+
5
+ // vitest 훅 바인딩
6
+ RuleTester.afterAll = afterAll;
7
+ RuleTester.it = it;
8
+ RuleTester.itOnly = it.only;
9
+ RuleTester.describe = describe;
10
+
11
+ const ruleTester = new RuleTester({
12
+ languageOptions: {
13
+ parserOptions: {
14
+ projectService: {
15
+ allowDefaultProject: ['*.ts*'],
16
+ },
17
+ },
18
+ },
19
+ });
20
+
21
+ describe('ts-no-buffer-in-typedarray-context 규칙', () => {
22
+ describe('허용되는 코드들 (valid)', () => {
23
+ describe('Buffer를 new TypedArray(buffer)로 감싸서 사용하는 경우', () => {
24
+ ruleTester.run('ts-no-buffer-in-typedarray-context', rule, {
25
+ valid: [
26
+ {
27
+ code: `
28
+ const buf = Buffer.from('abc');
29
+ const arr = new Uint8Array(buf);
30
+ `,
31
+ },
32
+ ],
33
+ invalid: [],
34
+ });
35
+ });
36
+
37
+ describe('TypedArray를 반환할 때 Buffer를 변환해서 사용하는 경우', () => {
38
+ ruleTester.run('ts-no-buffer-in-typedarray-context', rule, {
39
+ valid: [
40
+ {
41
+ code: `
42
+ const buf = Buffer.from('abc');
43
+ function get(): Uint8Array {
44
+ return new Uint8Array(buf);
45
+ }
46
+ `,
47
+ },
48
+ ],
49
+ invalid: [],
50
+ });
51
+ });
52
+
53
+ describe('TypedArray를 받는 함수에 Buffer가 아닌 TypedArray 인스턴스를 넘기는 경우', () => {
54
+ ruleTester.run('ts-no-buffer-in-typedarray-context', rule, {
55
+ valid: [
56
+ {
57
+ code: `
58
+ const buf = Buffer.from('abc');
59
+ function process(data: Uint8Array) {}
60
+ process(new Uint8Array(buf));
61
+ `,
62
+ },
63
+ ],
64
+ invalid: [],
65
+ });
66
+ });
67
+ });
68
+
69
+ describe('오류가 발생해야 하는 코드들 (invalid)', () => {
70
+ describe('Buffer를 TypedArray 타입 변수에 직접 할당하는 경우', () => {
71
+ ruleTester.run('ts-no-buffer-in-typedarray-context', rule, {
72
+ valid: [],
73
+ invalid: [
74
+ {
75
+ code: `
76
+ const buf = Buffer.from('abc');
77
+ const arr: Uint8Array = buf;
78
+ `,
79
+ errors: [
80
+ {
81
+ messageId: 'directBuffer',
82
+ data: { expected: 'Uint8Array' },
83
+ },
84
+ ],
85
+ },
86
+ ],
87
+ });
88
+ });
89
+
90
+ describe('Buffer를 TypedArray를 기대하는 함수 인자에 직접 전달하는 경우', () => {
91
+ ruleTester.run('ts-no-buffer-in-typedarray-context', rule, {
92
+ valid: [],
93
+ invalid: [
94
+ {
95
+ code: `
96
+ const buf = Buffer.from('abc');
97
+ function process(data: Float32Array) {}
98
+ process(buf);
99
+ `,
100
+ errors: [
101
+ {
102
+ messageId: 'directBuffer',
103
+ data: { expected: 'Float32Array' },
104
+ },
105
+ ],
106
+ },
107
+ ],
108
+ });
109
+ });
110
+
111
+ describe('Buffer를 TypedArray를 반환해야 하는 함수에서 직접 반환하는 경우', () => {
112
+ ruleTester.run('ts-no-buffer-in-typedarray-context', rule, {
113
+ valid: [],
114
+ invalid: [
115
+ {
116
+ code: `
117
+ const buf = Buffer.from('abc');
118
+ function give(): Int16Array {
119
+ return buf;
120
+ }
121
+ `,
122
+ errors: [
123
+ {
124
+ messageId: 'directBuffer',
125
+ data: { expected: 'Int16Array' },
126
+ },
127
+ ],
128
+ },
129
+ ],
130
+ });
131
+ });
132
+
133
+ describe('TypedArray 배열에 Buffer를 직접 넣는 경우', () => {
134
+ ruleTester.run('ts-no-buffer-in-typedarray-context', rule, {
135
+ valid: [],
136
+ invalid: [
137
+ {
138
+ code: `
139
+ const buf = Buffer.from('abc');
140
+ const arr: Uint8Array[] = [buf];
141
+ `,
142
+ errors: [
143
+ {
144
+ messageId: 'directBuffer',
145
+ data: { expected: 'Uint8Array' },
146
+ },
147
+ ],
148
+ },
149
+ ],
150
+ });
151
+ });
152
+
153
+ describe('객체 속성에 TypedArray를 기대하는데 Buffer를 넣는 경우', () => {
154
+ ruleTester.run('ts-no-buffer-in-typedarray-context', rule, {
155
+ valid: [],
156
+ invalid: [
157
+ {
158
+ code: `
159
+ const buf = Buffer.from('abc');
160
+ const obj: { x: Int32Array } = { x: buf };
161
+ `,
162
+ errors: [
163
+ {
164
+ messageId: 'directBuffer',
165
+ data: { expected: 'Int32Array' },
166
+ },
167
+ ],
168
+ },
169
+ ],
170
+ });
171
+ });
172
+
173
+ describe('조건부 표현식에서 Buffer가 TypedArray로 기대되는 경우', () => {
174
+ ruleTester.run('ts-no-buffer-in-typedarray-context', rule, {
175
+ valid: [],
176
+ invalid: [
177
+ {
178
+ code: `
179
+ const buf = Buffer.from('abc');
180
+ const x: Uint8Array = Math.random() > 0.5 ? buf : new Uint8Array();
181
+ `,
182
+ errors: [
183
+ {
184
+ messageId: 'directBuffer',
185
+ data: { expected: 'Uint8Array' },
186
+ },
187
+ ],
188
+ },
189
+ ],
190
+ });
191
+ });
192
+
193
+ describe('Buffer 사용이 허용되어야 하는 Buffer.정적메서드 호출', () => {
194
+ ruleTester.run('ts-no-buffer-in-typedarray-context', rule, {
195
+ valid: [
196
+ {
197
+ code: `
198
+ const list: Buffer[] = [Buffer.from("a"), Buffer.from("b")];
199
+ Buffer.concat(list); // 허용
200
+ `,
201
+ },
202
+ {
203
+ code: `
204
+ const buf = Buffer.from("a");
205
+ Buffer.concat([buf]); // 허용
206
+ `,
207
+ },
208
+ ],
209
+ invalid: [],
210
+ });
211
+ });
212
+ });
213
+ });