MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 154 lines 3.3 kB view raw
1// Test class function (method) hoisting behavior 2// Class methods can be called regardless of their definition order within the class body 3// But classes themselves are NOT hoisted like function declarations 4 5console.log("=== Test 1: Methods calling other methods defined later ==="); 6class Calculator { 7 calculate(x) { 8 return this.double(x) + this.triple(x); 9 } 10 11 double(x) { 12 return x * 2; 13 } 14 15 triple(x) { 16 return x * 3; 17 } 18} 19 20let calc = new Calculator(); 21console.log("calculate(5) should be 25:", calc.calculate(5)); 22 23console.log("\n=== Test 2: Constructor calling methods defined after it ==="); 24class Greeter { 25 constructor(name) { 26 this.name = name; 27 this.greeting = this.makeGreeting(); 28 } 29 30 makeGreeting() { 31 return "Hello, " + this.name + "!"; 32 } 33} 34 35let greeter = new Greeter("World"); 36console.log("greeting should be 'Hello, World!':", greeter.greeting); 37 38console.log("\n=== Test 3: Method calling method defined before constructor ==="); 39class Parser { 40 parse(input) { 41 return this.validate(input); 42 } 43 44 constructor() { 45 this.initialized = true; 46 } 47 48 validate(input) { 49 return input.length > 0; 50 } 51} 52 53let parser = new Parser(); 54console.log("parse('test') should be true:", parser.parse("test")); 55 56console.log("\n=== Test 4: Mutual method references ==="); 57class Counter { 58 increment() { 59 this.value = this.getValue() + 1; 60 } 61 62 decrement() { 63 this.value = this.getValue() - 1; 64 } 65 66 constructor(initial) { 67 this.value = initial; 68 } 69 70 getValue() { 71 return this.value; 72 } 73} 74 75let counter = new Counter(10); 76counter.increment(); 77console.log("after increment should be 11:", counter.getValue()); 78counter.decrement(); 79counter.decrement(); 80console.log("after two decrements should be 9:", counter.getValue()); 81 82console.log("\n=== Test 5: Deep method call chain ==="); 83class Chain { 84 a() { 85 return this.b() + 1; 86 } 87 88 b() { 89 return this.c() + 2; 90 } 91 92 c() { 93 return this.d() + 3; 94 } 95 96 d() { 97 return 10; 98 } 99} 100 101let chain = new Chain(); 102console.log("a() should be 16 (10+3+2+1):", chain.a()); 103 104console.log("\n=== Test 6: Class NOT hoisted (should error if accessed before) ==="); 105try { 106 let early = new NotYetDefined(); 107 console.log("ERROR: Should not reach here"); 108} catch (e) { 109 console.log("Correctly caught error - class not hoisted"); 110} 111 112class NotYetDefined { 113 constructor() { 114 this.value = 42; 115 } 116} 117 118let late = new NotYetDefined(); 119console.log("After definition, value should be 42:", late.value); 120 121console.log("\n=== Test 7: Static methods hoisting within class ==="); 122class StaticTest { 123 static compute() { 124 return StaticTest.helper() * 2; 125 } 126 127 static helper() { 128 return 21; 129 } 130} 131 132console.log("StaticTest.compute() should be 42:", StaticTest.compute()); 133 134console.log("\n=== Test 8: Getter/setter order independence ==="); 135class GetSet { 136 get doubled() { 137 return this._val * 2; 138 } 139 140 constructor(val) { 141 this._val = val; 142 } 143 144 set doubled(val) { 145 this._val = val / 2; 146 } 147} 148 149let gs = new GetSet(5); 150console.log("doubled should be 10:", gs.doubled); 151gs.doubled = 20; 152console.log("after setting doubled=20, _val should be 10:", gs._val); 153 154console.log("\n=== All class function hoisting tests completed ===");