Write a function expect that helps developers test their code. It should take in any value val and return an object with the following two functions.
toBe(val) accepts another value and returns true if the two values === each other. If they are not equal, it should throw an error "Not Equal".notToBe(val) accepts another value and returns true if the two values !== each other. If they are equal, it should throw an error "Equal".
Example 1:
Input: func = () => expect(5).toBe(5)
Output: {"value": true}
Explanation: 5 === 5 so this expression returns true.
Example 2:
Input: func = () => expect(5).toBe(null)
Output: {"error": "Not Equal"}
Explanation: 5 !== null so this expression throw the error "Not Equal".
Example 3:
Input: func = () => expect(5).notToBe(null)
Output: {"value": true}
Explanation: 5 !== null so this expression returns true.
Problem Overview: You implement a tiny assertion utility similar to what testing frameworks provide. The function expect(val) returns an object with two methods: toBe(val2) and notToBe(val2). If the condition fails, the method throws an error. Otherwise it returns true. The challenge is mainly about structuring the returned behavior using language features such as closures or object-oriented programming.
Approach 1: Closure-Based Approach (O(1) time, O(1) space)
The closure approach captures the original value inside the scope of expect. The function returns an object containing toBe and notToBe methods, and both methods reference the captured value. When toBe(val2) runs, it directly compares the stored value with val2. If they are strictly equal, return true; otherwise throw an error such as "Not Equal". The notToBe method performs the opposite check and throws an error like "Equal" when the values match. This works because closures preserve access to variables defined in the outer function even after that function finishes execution.
The key insight is that you do not need persistent state outside the function. The captured variable inside the closure behaves like private data. This makes the implementation concise and idiomatic in languages such as JavaScript or Python where functions can return objects containing nested functions.
Approach 2: Class-Based Approach (O(1) time, O(1) space)
The class-based design wraps the value inside an instance field. Instead of relying on lexical scope, the stored value becomes a property of the class object. The constructor receives the value, and the methods toBe and notToBe operate on that stored field.
During execution, expect(val) simply returns a new instance of the class. Each method performs a direct equality comparison with the stored value and throws the appropriate error when the condition fails. This approach mirrors how many testing libraries internally implement assertions. It fits naturally in strongly object-oriented languages such as C++, Java, and C# where encapsulation through classes is the standard pattern.
The advantage is structural clarity. State and behavior are grouped inside a single class, which makes the implementation straightforward when closures are less idiomatic or unavailable.
Recommended for interviews: The closure-based implementation is typically the expected answer when the problem is asked in JavaScript because it demonstrates understanding of closures and lexical scope. The class-based approach is equally correct and often preferred in languages centered around object-oriented design. Interviewers mainly look for correct comparison logic, proper error handling, and a clean API design.
The closure-based approach makes use of JavaScript's closure capabilities to encapsulate the comparison logic within the returned object. The main idea here is to utilize closures to maintain the original value passed to the expect function, and then provide methods that perform the respective comparisons. This approach leverages the benefits of closures to maintain a clean and functional interface.
In JavaScript, the expect function returns an object with two methods: toBe and notToBe. These methods use closures to access the value originally passed into expect. When toBe is called, it checks if the values are strictly equal and returns true or throws an error appropriately. Similarly, notToBe checks for inequality and handles it in the same manner. The use of closures allows these methods to always reference the correct original val that expect was called with.
JavaScript
Python
Time Complexity: O(1) for both toBe and notToBe methods as they perform constant time operations.
Space Complexity: O(1) since the space required does not grow with the size of the input.
The class-based approach in languages like C++, C#, and Java exploits object-oriented programming features to achieve encapsulation and method binding. Here, the idea is to define a class that keeps track of the initial value and provides methods that can be invoked on it to perform the required checks. This method is beneficial for languages where closures don't exist or are cumbersome to implement, maintaining a clear object-oriented design.
In C++, the Expect class is used to encapsulate the initial value. The constructor initializes this value and the methods toBe and notToBe perform the comparisons. If conditions are not satisfied, they throw runtime errors. This class-based approach leverages C++'s support for OOP to provide a straightforward implementation.
Time Complexity: O(1) for both methods.
Space Complexity: O(1).
TypeScript
JavaScript
| Approach | Complexity |
|---|---|
| Closure-Based Approach | Time Complexity: O(1) for both |
| Class-Based Approach | Time Complexity: O(1) for both methods. |
| Default Approach | — |
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Closure-Based Implementation | O(1) | O(1) | Best for JavaScript/Python when demonstrating closure and lexical scope concepts |
| Class-Based Implementation | O(1) | O(1) | Preferred in C++, Java, and C# where object-oriented patterns are standard |
2704. To Be Or Not To Be - Leetcode JavaScript Solution with Explanation • Endeavour Monk • 9,164 views views
Watch 9 more video solutions →Practice To Be Or Not To Be with our built-in code editor and test cases.
Practice on FleetCode