// ============================================================================
// Comprehensive Array Callback Methods Test
// Tests all 8 methods: forEach, map, filter, reduce, find, findIndex, some, every
// ============================================================================

console.log("=== ARRAY CALLBACK METHODS TEST ===\n");

// Test data
var numbers = [1, 2, 3, 4, 5];
var mixed = [10, 15, 20, 25, 30];
var strings = ["apple", "banana", "cherry"];

// ============================================================================
// TEST 1: forEach - Should execute callback for each element
// ============================================================================
console.log("TEST 1: forEach");
var forEachResults = [];
numbers.forEach(function(x, idx) {
    forEachResults.push(x * 2);
    console.log("  forEach: index=" + idx + " value=" + x + " doubled=" + (x * 2));
});
console.log("  Results array: " + forEachResults.join(", "));
console.log("  Expected: 2, 4, 6, 8, 10");
console.log("");

// ============================================================================
// TEST 2: map - Should transform each element
// ============================================================================
console.log("TEST 2: map");
var mapped = numbers.map(function(x) {
    return x * 3;
});
console.log("  Original: " + numbers.join(", "));
console.log("  Mapped:   " + mapped.join(", "));
console.log("  Expected: 3, 9, 15, 21, 27");
console.log("");

// Test map with index
var mappedWithIndex = numbers.map(function(x, idx) {
    return x + idx;
});
console.log("  Mapped with index: " + mappedWithIndex.join(", "));
console.log("  Expected: 1, 3, 5, 7, 9");
console.log("");

// ============================================================================
// TEST 3: filter - Should keep only elements that pass test
// ============================================================================
console.log("TEST 3: filter");
var evens = numbers.filter(function(x) {
    return x % 2 === 0;
});
console.log("  Original: " + numbers.join(", "));
console.log("  Evens:    " + evens.join(", "));
console.log("  Expected: 2, 4");
console.log("");

var bigNumbers = mixed.filter(function(x) {
    return x > 15;
});
console.log("  Original: " + mixed.join(", "));
console.log("  > 15:     " + bigNumbers.join(", "));
console.log("  Expected: 20, 25, 30");
console.log("");

// ============================================================================
// TEST 4: reduce - Should accumulate a single value
// ============================================================================
console.log("TEST 4: reduce");
var sum = numbers.reduce(function(acc, x) {
    return acc + x;
}, 0);
console.log("  Sum of [1,2,3,4,5]: " + sum);
console.log("  Expected: 15");
console.log("");

var product = numbers.reduce(function(acc, x) {
    return acc * x;
}, 1);
console.log("  Product of [1,2,3,4,5]: " + product);
console.log("  Expected: 120");
console.log("");

// Reduce without initial value
var sum2 = numbers.reduce(function(acc, x) {
    return acc + x;
});
console.log("  Sum without initial value: " + sum2);
console.log("  Expected: 15");
console.log("");

// ============================================================================
// TEST 5: find - Should return first element that passes test
// ============================================================================
console.log("TEST 5: find");
var found = mixed.find(function(x) {
    return x > 20;
});
console.log("  Array: " + mixed.join(", "));
console.log("  First > 20: " + found);
console.log("  Expected: 25");
console.log("");

var notFound = numbers.find(function(x) {
    return x > 100;
});
console.log("  First > 100: " + notFound);
console.log("  Expected: undefined");
console.log("");

// ============================================================================
// TEST 6: findIndex - Should return index of first element that passes test
// ============================================================================
console.log("TEST 6: findIndex");
var foundIndex = mixed.findIndex(function(x) {
    return x > 20;
});
console.log("  Array: " + mixed.join(", "));
console.log("  Index of first > 20: " + foundIndex);
console.log("  Expected: 3");
console.log("");

var notFoundIndex = numbers.findIndex(function(x) {
    return x > 100;
});
console.log("  Index of first > 100: " + notFoundIndex);
console.log("  Expected: -1");
console.log("");

// ============================================================================
// TEST 7: some - Should return true if ANY element passes test
// ============================================================================
console.log("TEST 7: some");
var hasEven = numbers.some(function(x) {
    return x % 2 === 0;
});
console.log("  Array: " + numbers.join(", "));
console.log("  Has even number: " + hasEven);
console.log("  Expected: true");
console.log("");

var hasNegative = numbers.some(function(x) {
    return x < 0;
});
console.log("  Has negative: " + hasNegative);
console.log("  Expected: false");
console.log("");

// ============================================================================
// TEST 8: every - Should return true if ALL elements pass test
// ============================================================================
console.log("TEST 8: every");
var allPositive = numbers.every(function(x) {
    return x > 0;
});
console.log("  Array: " + numbers.join(", "));
console.log("  All positive: " + allPositive);
console.log("  Expected: true");
console.log("");

var allEven = numbers.every(function(x) {
    return x % 2 === 0;
});
console.log("  All even: " + allEven);
console.log("  Expected: false");
console.log("");

// ============================================================================
// TEST 9: Nested/Complex callbacks
// ============================================================================
console.log("TEST 9: Complex nested callbacks");

// Map inside filter
var complex1 = numbers.filter(function(x) {
    return x > 2;
}).map(function(x) {
    return x * 10;
});
console.log("  Filter > 2, then map * 10: " + complex1.join(", "));
console.log("  Expected: 30, 40, 50");
console.log("");

// Reduce to build object-like structure (using arrays as objects)
var grouped = numbers.reduce(function(acc, x) {
    // Group by even/odd (we'll just track counts as we can't do objects yet)
    if (x % 2 === 0) {
        return acc + 1;  // Count evens
    }
    return acc;
}, 0);
console.log("  Count of even numbers: " + grouped);
console.log("  Expected: 2");
console.log("");

// ============================================================================
// TEST 10: Edge cases
// ============================================================================
console.log("TEST 10: Edge cases");

// Empty array
var emptyMap = [].map(function(x) { return x * 2; });
console.log("  Empty array map: " + emptyMap.length);
console.log("  Expected: 0");
console.log("");

var emptyFilter = [].filter(function(x) { return true; });
console.log("  Empty array filter: " + emptyFilter.length);
console.log("  Expected: 0");
console.log("");

var emptyEvery = [].every(function(x) { return false; });
console.log("  Empty array every: " + emptyEvery);
console.log("  Expected: true");
console.log("");

var emptySome = [].some(function(x) { return true; });
console.log("  Empty array some: " + emptySome);
console.log("  Expected: false");
console.log("");

// Single element
var singleMap = [42].map(function(x) { return x * 2; });
console.log("  Single element map: " + singleMap[0]);
console.log("  Expected: 84");
console.log("");

// ============================================================================
// TEST 11: Callback receives correct arguments (element, index)
// ============================================================================
console.log("TEST 11: Callback arguments");
var argTest = [10, 20, 30];
argTest.forEach(function(elem, idx) {
    console.log("  elem=" + elem + " index=" + idx + " (expected: " + (idx * 10 + 10) + ", " + idx + ")");
});
console.log("");

// ============================================================================
// SUMMARY
// ============================================================================
console.log("=== ALL TESTS COMPLETE ===");
console.log("If all output matches expected values, array methods are working correctly!");


