1+ import { Component } from '../../src/ECS/Component' ;
2+ import { Entity } from '../../src/ECS/Entity' ;
3+
4+ // 测试组件
5+ class TestComponent extends Component {
6+ public value : number = 100 ;
7+ public onAddedCalled = false ;
8+ public onRemovedCalled = false ;
9+ public onEnabledCalled = false ;
10+ public onDisabledCalled = false ;
11+ public updateCalled = false ;
12+
13+ public override onAddedToEntity ( ) : void {
14+ this . onAddedCalled = true ;
15+ }
16+
17+ public override onRemovedFromEntity ( ) : void {
18+ this . onRemovedCalled = true ;
19+ }
20+
21+ public override onEnabled ( ) : void {
22+ this . onEnabledCalled = true ;
23+ }
24+
25+ public override onDisabled ( ) : void {
26+ this . onDisabledCalled = true ;
27+ }
28+
29+ public override update ( ) : void {
30+ this . updateCalled = true ;
31+ }
32+ }
33+
34+ class AnotherTestComponent extends Component {
35+ public name : string = 'test' ;
36+ }
37+
38+ describe ( 'Component - 组件基类测试' , ( ) => {
39+ let component : TestComponent ;
40+ let entity : Entity ;
41+
42+ beforeEach ( ( ) => {
43+ // Reset component ID generator to avoid BigInt issues
44+ Component . _idGenerator = 0 ;
45+ component = new TestComponent ( ) ;
46+ entity = new Entity ( 'TestEntity' , 1 ) ;
47+ } ) ;
48+
49+ describe ( '基本功能' , ( ) => {
50+ test ( '应该能够创建组件实例' , ( ) => {
51+ expect ( component ) . toBeInstanceOf ( Component ) ;
52+ expect ( component ) . toBeInstanceOf ( TestComponent ) ;
53+ expect ( component . id ) . toBeGreaterThanOrEqual ( 0 ) ;
54+ } ) ;
55+
56+ test ( '每个组件应该有唯一的ID' , ( ) => {
57+ const component1 = new TestComponent ( ) ;
58+ const component2 = new TestComponent ( ) ;
59+ const component3 = new AnotherTestComponent ( ) ;
60+
61+ expect ( component1 . id ) . not . toBe ( component2 . id ) ;
62+ expect ( component2 . id ) . not . toBe ( component3 . id ) ;
63+ expect ( component1 . id ) . not . toBe ( component3 . id ) ;
64+ } ) ;
65+
66+ test ( '组件ID应该递增分配' , ( ) => {
67+ const startId = Component . _idGenerator ;
68+ const component1 = new TestComponent ( ) ;
69+ const component2 = new TestComponent ( ) ;
70+
71+ expect ( component2 . id ) . toBe ( component1 . id + 1 ) ;
72+ expect ( component1 . id ) . toBeGreaterThanOrEqual ( startId ) ;
73+ } ) ;
74+ } ) ;
75+
76+ describe ( '启用状态管理' , ( ) => {
77+ test ( '组件默认应该是启用的' , ( ) => {
78+ expect ( component . enabled ) . toBe ( true ) ;
79+ } ) ;
80+
81+ test ( '设置组件禁用状态应该工作' , ( ) => {
82+ component . enabled = false ;
83+ expect ( component . enabled ) . toBe ( false ) ;
84+ expect ( component . onDisabledCalled ) . toBe ( true ) ;
85+ } ) ;
86+
87+ test ( '重新启用组件应该工作' , ( ) => {
88+ component . enabled = false ;
89+ component . onDisabledCalled = false ;
90+ component . onEnabledCalled = false ;
91+
92+ component . enabled = true ;
93+ expect ( component . enabled ) . toBe ( true ) ;
94+ expect ( component . onEnabledCalled ) . toBe ( true ) ;
95+ } ) ;
96+
97+ test ( '设置相同的状态不应该触发回调' , ( ) => {
98+ component . enabled = true ; // 已经是true
99+ expect ( component . onEnabledCalled ) . toBe ( false ) ;
100+
101+ component . enabled = false ;
102+ component . onDisabledCalled = false ;
103+
104+ component . enabled = false ; // 已经是false
105+ expect ( component . onDisabledCalled ) . toBe ( false ) ;
106+ } ) ;
107+
108+ test ( '组件启用状态应该受实体状态影响' , ( ) => {
109+ entity . addComponent ( component ) ;
110+ expect ( component . enabled ) . toBe ( true ) ;
111+
112+ // 禁用实体应该让组件表现为禁用
113+ entity . enabled = false ;
114+ expect ( component . enabled ) . toBe ( false ) ;
115+
116+ // 重新启用实体
117+ entity . enabled = true ;
118+ expect ( component . enabled ) . toBe ( true ) ;
119+ } ) ;
120+
121+ test ( '组件自身禁用时即使实体启用也应该是禁用的' , ( ) => {
122+ entity . addComponent ( component ) ;
123+
124+ component . enabled = false ;
125+ entity . enabled = true ;
126+
127+ expect ( component . enabled ) . toBe ( false ) ;
128+ } ) ;
129+
130+ test ( '没有实体时组件状态应该只取决于自身' , ( ) => {
131+ // 组件还没有添加到实体
132+ expect ( component . enabled ) . toBe ( true ) ;
133+
134+ component . enabled = false ;
135+ expect ( component . enabled ) . toBe ( false ) ;
136+ } ) ;
137+ } ) ;
138+
139+ describe ( '更新顺序' , ( ) => {
140+ test ( '组件默认更新顺序应该是0' , ( ) => {
141+ expect ( component . updateOrder ) . toBe ( 0 ) ;
142+ } ) ;
143+
144+ test ( '应该能够设置更新顺序' , ( ) => {
145+ component . updateOrder = 10 ;
146+ expect ( component . updateOrder ) . toBe ( 10 ) ;
147+
148+ component . updateOrder = - 5 ;
149+ expect ( component . updateOrder ) . toBe ( - 5 ) ;
150+ } ) ;
151+ } ) ;
152+
153+ describe ( '生命周期回调' , ( ) => {
154+ test ( '添加到实体时应该调用onAddedToEntity' , ( ) => {
155+ expect ( component . onAddedCalled ) . toBe ( false ) ;
156+
157+ entity . addComponent ( component ) ;
158+ expect ( component . onAddedCalled ) . toBe ( true ) ;
159+ } ) ;
160+
161+ test ( '从实体移除时应该调用onRemovedFromEntity' , ( ) => {
162+ entity . addComponent ( component ) ;
163+ expect ( component . onRemovedCalled ) . toBe ( false ) ;
164+
165+ entity . removeComponent ( component ) ;
166+ expect ( component . onRemovedCalled ) . toBe ( true ) ;
167+ } ) ;
168+
169+ test ( '启用时应该调用onEnabled' , ( ) => {
170+ component . enabled = false ;
171+ component . onEnabledCalled = false ;
172+
173+ component . enabled = true ;
174+ expect ( component . onEnabledCalled ) . toBe ( true ) ;
175+ } ) ;
176+
177+ test ( '禁用时应该调用onDisabled' , ( ) => {
178+ expect ( component . onDisabledCalled ) . toBe ( false ) ;
179+
180+ component . enabled = false ;
181+ expect ( component . onDisabledCalled ) . toBe ( true ) ;
182+ } ) ;
183+ } ) ;
184+
185+ describe ( '更新方法' , ( ) => {
186+ test ( 'update方法应该可以被调用' , ( ) => {
187+ expect ( component . updateCalled ) . toBe ( false ) ;
188+
189+ component . update ( ) ;
190+ expect ( component . updateCalled ) . toBe ( true ) ;
191+ } ) ;
192+
193+ test ( '基类的默认生命周期方法应该安全调用' , ( ) => {
194+ const baseComponent = new ( class extends Component { } ) ( ) ;
195+
196+ // 这些方法不应该抛出异常
197+ expect ( ( ) => {
198+ baseComponent . onAddedToEntity ( ) ;
199+ baseComponent . onRemovedFromEntity ( ) ;
200+ baseComponent . onEnabled ( ) ;
201+ baseComponent . onDisabled ( ) ;
202+ baseComponent . update ( ) ;
203+ } ) . not . toThrow ( ) ;
204+ } ) ;
205+ } ) ;
206+
207+ describe ( '实体关联' , ( ) => {
208+ test ( '组件应该能够访问其所属的实体' , ( ) => {
209+ entity . addComponent ( component ) ;
210+ expect ( component . entity ) . toBe ( entity ) ;
211+ } ) ;
212+
213+ test ( '组件移除后entity引用行为' , ( ) => {
214+ entity . addComponent ( component ) ;
215+ expect ( component . entity ) . toBe ( entity ) ;
216+
217+ entity . removeComponent ( component ) ;
218+ // 移除后entity引用可能被清空,这是正常行为
219+ // 具体行为取决于实现,这里只测试不会抛出异常
220+ expect ( ( ) => {
221+ const _ = component . entity ;
222+ } ) . not . toThrow ( ) ;
223+ } ) ;
224+ } ) ;
225+
226+ describe ( '边界情况' , ( ) => {
227+ test ( '多次启用禁用应该工作正常' , ( ) => {
228+ for ( let i = 0 ; i < 10 ; i ++ ) {
229+ component . enabled = false ;
230+ expect ( component . enabled ) . toBe ( false ) ;
231+
232+ component . enabled = true ;
233+ expect ( component . enabled ) . toBe ( true ) ;
234+ }
235+ } ) ;
236+
237+ test ( '极端更新顺序值应该被接受' , ( ) => {
238+ component . updateOrder = 999999 ;
239+ expect ( component . updateOrder ) . toBe ( 999999 ) ;
240+
241+ component . updateOrder = - 999999 ;
242+ expect ( component . updateOrder ) . toBe ( - 999999 ) ;
243+ } ) ;
244+
245+ test ( '大量组件创建应该有不同的ID' , ( ) => {
246+ const components : Component [ ] = [ ] ;
247+ const count = 1000 ;
248+
249+ for ( let i = 0 ; i < count ; i ++ ) {
250+ components . push ( new TestComponent ( ) ) ;
251+ }
252+
253+ // 检查所有ID都不同
254+ const ids = new Set ( components . map ( c => c . id ) ) ;
255+ expect ( ids . size ) . toBe ( count ) ;
256+ } ) ;
257+ } ) ;
258+
259+ describe ( '继承和多态' , ( ) => {
260+ test ( '不同类型的组件应该都继承自Component' , ( ) => {
261+ const test1 = new TestComponent ( ) ;
262+ const test2 = new AnotherTestComponent ( ) ;
263+
264+ expect ( test1 ) . toBeInstanceOf ( Component ) ;
265+ expect ( test2 ) . toBeInstanceOf ( Component ) ;
266+ expect ( test1 ) . toBeInstanceOf ( TestComponent ) ;
267+ expect ( test2 ) . toBeInstanceOf ( AnotherTestComponent ) ;
268+ } ) ;
269+
270+ test ( '组件应该能够重写基类方法' , ( ) => {
271+ const test = new TestComponent ( ) ;
272+ test . update ( ) ;
273+
274+ expect ( test . updateCalled ) . toBe ( true ) ;
275+ } ) ;
276+ } ) ;
277+ } ) ;
0 commit comments