MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1// Test objects in if statements
2// Tests property access and truthiness evaluation
3
4console.log("=== Object in If Statements Test ===\n");
5
6// Test 1: Basic object property truthiness
7console.log("Test 1: Object property truthiness");
8let thing = {
9 hasThing: true,
10 hasOther: false,
11 count: 5,
12 name: "test"
13};
14
15if (thing.hasThing) {
16 console.log(" thing.hasThing is truthy: PASS");
17}
18
19if (!thing.hasOther) {
20 console.log(" !thing.hasOther is falsy: PASS");
21}
22
23if (thing.count) {
24 console.log(" thing.count (5) is truthy: PASS");
25}
26
27if (thing.name) {
28 console.log(" thing.name ('test') is truthy: PASS");
29}
30
31// Test 2: Undefined and null properties
32console.log("\nTest 2: Undefined and null properties");
33let obj = {
34 defined: "value",
35 nullValue: null,
36 undefinedValue: undefined,
37 zeroValue: 0,
38 emptyString: ""
39};
40
41if (!obj.nonExistent) {
42 console.log(" !obj.nonExistent (undefined): PASS");
43}
44
45if (!obj.nullValue) {
46 console.log(" !obj.nullValue (null): PASS");
47}
48
49if (!obj.undefinedValue) {
50 console.log(" !obj.undefinedValue (undefined): PASS");
51}
52
53if (!obj.zeroValue) {
54 console.log(" !obj.zeroValue (0): PASS");
55}
56
57if (!obj.emptyString) {
58 console.log(" !obj.emptyString (''): PASS");
59}
60
61if (obj.defined) {
62 console.log(" obj.defined ('value'): PASS");
63}
64
65// Test 3: Nested object properties
66console.log("\nTest 3: Nested object properties");
67let config = {
68 settings: {
69 enabled: true,
70 disabled: false,
71 nested: {
72 deep: "value"
73 }
74 }
75};
76
77if (config.settings) {
78 console.log(" config.settings exists: PASS");
79}
80
81if (config.settings.enabled) {
82 console.log(" config.settings.enabled is true: PASS");
83}
84
85if (!config.settings.disabled) {
86 console.log(" !config.settings.disabled is false: PASS");
87}
88
89if (config.settings.nested) {
90 console.log(" config.settings.nested exists: PASS");
91}
92
93if (config.settings.nested.deep) {
94 console.log(" config.settings.nested.deep has value: PASS");
95}
96
97// Test 4: Function properties
98console.log("\nTest 4: Function properties");
99let api = {
100 hasMethod: function() {
101 return "called";
102 },
103 noMethod: null
104};
105
106if (api.hasMethod) {
107 console.log(" api.hasMethod exists:", api.hasMethod());
108}
109
110if (!api.noMethod) {
111 console.log(" !api.noMethod is null: PASS");
112}
113
114// Test 5: Array properties
115console.log("\nTest 5: Array properties");
116let data = {
117 items: [1, 2, 3],
118 emptyItems: [],
119 noItems: null
120};
121
122if (data.items) {
123 console.log(" data.items exists, length:", data.items.length);
124}
125
126if (data.emptyItems) {
127 console.log(" data.emptyItems exists but empty, length:", data.emptyItems.length);
128}
129
130if (!data.noItems) {
131 console.log(" !data.noItems is null: PASS");
132}
133
134// Test 6: Conditional checks with property access
135console.log("\nTest 6: Conditional property checks");
136let user = {
137 name: "John",
138 age: 30,
139 active: true
140};
141
142if (user.name && user.age) {
143 console.log(" user.name && user.age both exist: PASS");
144}
145
146if (user.active && user.name) {
147 console.log(" user.active && user.name both truthy: PASS");
148}
149
150if (!user.deleted || user.active) {
151 console.log(" !user.deleted || user.active: PASS");
152}
153
154// Test 7: Return based on object property
155console.log("\nTest 7: Return based on property");
156function checkUser(user) {
157 if (!user) return { error: "no user" };
158 if (!user.name) return { error: "no name" };
159 return { success: true, name: user.name };
160}
161
162console.log(" With null:", checkUser(null));
163console.log(" With no name:", checkUser({ age: 25 }));
164console.log(" With name:", checkUser({ name: "Alice" }));
165
166// Test 8: Object itself as condition
167console.log("\nTest 8: Object as condition");
168let obj1 = { value: 1 };
169let obj2 = null;
170let obj3 = undefined;
171
172if (obj1) {
173 console.log(" obj1 (object) is truthy: PASS");
174}
175
176if (!obj2) {
177 console.log(" !obj2 (null) is falsy: PASS");
178}
179
180if (!obj3) {
181 console.log(" !obj3 (undefined) is falsy: PASS");
182}
183
184// Test 9: Boolean properties in complex conditions
185console.log("\nTest 9: Complex boolean property checks");
186let feature = {
187 enabled: true,
188 experimental: false,
189 beta: true,
190 stable: false
191};
192
193if (feature.enabled && feature.beta) {
194 console.log(" enabled && beta: PASS");
195}
196
197if (feature.enabled && !feature.stable) {
198 console.log(" enabled && !stable: PASS");
199}
200
201if (!feature.experimental && !feature.stable) {
202 console.log(" !experimental && !stable: PASS");
203}
204
205// Test 10: Property chain with guard
206console.log("\nTest 10: Safe property access");
207function getValue(obj) {
208 if (!obj) return "no object";
209 if (!obj.data) return "no data";
210 if (!obj.data.value) return "no value";
211 return obj.data.value;
212}
213
214console.log(" With null:", getValue(null));
215console.log(" With no data:", getValue({}));
216console.log(" With no value:", getValue({ data: {} }));
217console.log(" With value:", getValue({ data: { value: "found" } }));
218
219// Test 11: Optional chaining with undefined/null values
220console.log("\nTest 11: Optional chaining (?.)");
221const value = undefined;
222const nullValue = null;
223const obj11 = { nested: { deep: "value" } };
224
225console.log(" value?.thing (undefined):", value?.thing);
226console.log(" nullValue?.thing (null):", nullValue?.thing);
227console.log(" obj11?.nested?.deep:", obj11?.nested?.deep);
228console.log(" obj11?.missing?.deep:", obj11?.missing?.deep);
229
230if (value?.thing) {
231 console.log(" FAIL: value?.thing should be undefined");
232} else {
233 console.log(" value?.thing is falsy: PASS");
234}
235
236if (!nullValue?.thing) {
237 console.log(" !nullValue?.thing is falsy: PASS");
238}
239
240if (obj11?.nested?.deep) {
241 console.log(" obj11?.nested?.deep exists: PASS");
242}
243
244if (!obj11?.missing?.deep) {
245 console.log(" !obj11?.missing?.deep is falsy: PASS");
246}
247
248console.log("\n=== All tests completed ===");