File size: 4,459 Bytes
e706de2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**

 * Solution 1: Multiplier Runnable

 *

 * This solution demonstrates:

 * - Extending the Runnable base class

 * - Storing configuration in constructor

 * - Implementing the _call() method

 * - Input validation

 */

import { Runnable } from '../../../../src/index.js';

/**

 * MultiplierRunnable - Multiplies input by a factor

 */
class MultiplierRunnable extends Runnable {
    constructor(factor) {
        super(); // Always call super() first!

        // Validate factor
        if (typeof factor !== 'number') {
            throw new Error('Factor must be a number');
        }

        this.factor = factor;
    }

    async _call(input, config) {
        // Validate input
        if (typeof input !== 'number') {
            throw new Error('Input must be a number');
        }

        // Perform multiplication
        return input * this.factor;
    }

    // Optional: Override toString for better debugging
    toString() {
        return `MultiplierRunnable(Γ—${this.factor})`;
    }
}

// ============================================================================
// Tests
// ============================================================================

async function runTests() {
    console.log('πŸ§ͺ Testing MultiplierRunnable Solution...\n');

    try {
        // Test 1: Basic multiplication
        console.log('Test 1: Basic multiplication');
        const times3 = new MultiplierRunnable(3);
        const result1 = await times3.invoke(5);
        console.assert(result1 === 15, `Expected 15, got ${result1}`);
        console.log('βœ… 3 Γ— 5 = 15');
        console.log(`   Runnable: ${times3.toString()}\n`);

        // Test 2: Different factor
        console.log('Test 2: Different factor');
        const times10 = new MultiplierRunnable(10);
        const result2 = await times10.invoke(7);
        console.assert(result2 === 70, `Expected 70, got ${result2}`);
        console.log('βœ… 10 Γ— 7 = 70\n');

        // Test 3: Negative numbers
        console.log('Test 3: Negative numbers');
        const times2 = new MultiplierRunnable(2);
        const result3 = await times2.invoke(-5);
        console.assert(result3 === -10, `Expected -10, got ${result3}`);
        console.log('βœ… 2 Γ— -5 = -10\n');

        // Test 4: Decimal numbers
        console.log('Test 4: Decimal numbers');
        const times1_5 = new MultiplierRunnable(1.5);
        const result4 = await times1_5.invoke(4);
        console.assert(result4 === 6, `Expected 6, got ${result4}`);
        console.log('βœ… 1.5 Γ— 4 = 6\n');

        // Test 5: Zero
        console.log('Test 5: Multiply by zero');
        const times0 = new MultiplierRunnable(0);
        const result5 = await times0.invoke(100);
        console.assert(result5 === 0, `Expected 0, got ${result5}`);
        console.log('βœ… 0 Γ— 100 = 0\n');

        // Test 6: Error handling - invalid factor
        console.log('Test 6: Error handling - invalid factor');
        try {
            new MultiplierRunnable('not a number');
            console.error('❌ Should have thrown error');
        } catch (error) {
            console.log('βœ… Correctly throws error for invalid factor\n');
        }

        // Test 7: Error handling - invalid input
        console.log('Test 7: Error handling - invalid input');
        try {
            const times5 = new MultiplierRunnable(5);
            await times5.invoke('not a number');
            console.error('❌ Should have thrown error');
        } catch (error) {
            console.log('βœ… Correctly throws error for invalid input\n');
        }

        // Test 8: Works with batch
        console.log('Test 8: Batch processing');
        const times2_batch = new MultiplierRunnable(2);
        const results = await times2_batch.batch([1, 2, 3, 4, 5]);
        console.log(`   Input:  [1, 2, 3, 4, 5]`);
        console.log(`   Output: [${results.join(', ')}]`);
        console.assert(JSON.stringify(results) === JSON.stringify([2, 4, 6, 8, 10]));
        console.log('βœ… Batch processing works\n');

        console.log('πŸŽ‰ All tests passed!');
    } catch (error) {
        console.error('❌ Test failed:', error.message);
        console.error(error.stack);
    }
}

// Run tests
if (import.meta.url === `file://${process.argv[1]}`) {
    runTests();
}

export { MultiplierRunnable };