about summary refs log tree commit diff stats
path: root/js/where/where.test.html
diff options
context:
space:
mode:
Diffstat (limited to 'js/where/where.test.html')
-rw-r--r--js/where/where.test.html247
1 files changed, 247 insertions, 0 deletions
diff --git a/js/where/where.test.html b/js/where/where.test.html
new file mode 100644
index 0000000..161ecf1
--- /dev/null
+++ b/js/where/where.test.html
@@ -0,0 +1,247 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <title>Where?</title>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <style>
+        body { 
+            font-family: monospace; 
+            padding: 20px; 
+            max-width: 800px;
+            margin: 0 auto;
+            line-height: 1.6;
+        }
+        .console { 
+            background: #f5f5f5;
+            padding: 20px;
+            border-radius: 4px;
+            margin-top: 20px;
+        }
+        .example {
+            background: #e9f5ff;
+            padding: 15px;
+            border-radius: 4px;
+            margin: 10px 0;
+        }
+        code {
+            background: #f0f0f0;
+            padding: 2px 4px;
+            border-radius: 3px;
+        }
+        pre {
+            background: #f8f8f8;
+            padding: 15px;
+            border-radius: 4px;
+            overflow-x: auto;
+        }
+    </style>
+</head>
+<body>
+    <h1>Where?</h1>
+
+    <section>
+        <h2>Overview</h2>
+        <p>
+            This <code>where()</code> function aims to provide sql-like filtering for arrays of objects.
+            It allows you to filter collections using simple or complex criteria, including nested properties.
+        </p>
+        <p>
+            Could you usually use <code>Array.filter()</code> instead? Yes, almost always. But I think this is a bit prettier.
+        </p>
+    </section>
+
+    <section>
+        <h2>Basic Usage</h2>
+        <div class="example">
+            <pre>
+const users = [
+    { name: 'Tziporah', age: 30 },
+    { name: 'Bruce', age: 25 },
+    { name: 'Ruth', age: 30 }
+];
+
+// Find everyone who is 30 years old
+const thirtyYearOlds = where(users, { age: 30 });
+// Result: [{ name: 'Tziporah', age: 30 }, { name: 'Ruth', age: 30 }]</pre>
+        </div>
+    </section>
+
+    <section>
+        <h2>More Advanced Features</h2>
+        
+        <h3>1. Nested Object Properties</h3>
+        <div class="example">
+            <pre>
+const users = [
+    { 
+        name: 'Bruce',
+        preferences: { 
+            theme: 'dark',
+            notifications: { email: true }
+        }
+    }
+];
+
+// Find people with the dark theme enabled
+const darkThemeUsers = where(users, {
+    preferences: { theme: 'dark' }
+});</pre>
+        </div>
+
+        <h3>2. Dot Notation</h3>
+        <div class="example">
+            <pre>
+// Same query using dot notation
+const darkThemeUsers = where(users, {
+    'preferences.theme': 'dark'
+});</pre>
+        </div>
+
+        <h3>3. Multiple Criteria</h3>
+        <div class="example">
+            <pre>
+// Find folks who are 30 AND prefer dark theme
+const result = where(users, {
+    age: 30,
+    'preferences.theme': 'dark'
+});</pre>
+        </div>
+
+        <h3>4. Array Matching</h3>
+        <div class="example">
+            <pre>
+const users = [
+    { 
+        name: 'Jeremiah',
+        hobbies: ['reading', 'music']
+    }
+];
+
+// Find people with exact hobby matches
+const readers = where(users, {
+    hobbies: ['reading', 'music']
+});</pre>
+        </div>
+    </section>
+
+    <section>
+        <h2>The Key Features</h2>
+        <ul>
+            <li>Deep object comparison</li>
+            <li>Handles null/undefined values</li>
+            <li>Supports nested object and dot notation</li>
+            <li>Exact array matching</li>
+            <li>Multiple criteria (AND logic)</li>
+            <li>Memoized for performance 🏃‍♂️</li>
+        </ul>
+    </section>
+
+    <section>
+        <h2>Limitations & Edge Cases</h2>
+        
+        <h3>1. Partial Array Matches</h3>
+        <div class="example">
+            <pre>
+const users = [
+    { 
+        name: 'Bruce',
+        hobbies: ['reading', 'music', 'hiking']
+    }
+];
+
+// This won't match Bruce's hobbies
+const result = where(users, {
+    hobbies: ['reading', 'music']
+}); // Returns []
+
+// Arrays must match exactly in length and content</pre>
+        </div>
+
+        <h3>2. OR Operations</h3>
+        <div class="example">
+            <pre>
+// This won't work for finding users aged 25 OR 30
+const result = where(users, {
+    age: [25, 30]  // This looks for an exact array match
+});
+
+// Consider using Array.filter() directly for OR operations:
+const result = users.filter(user => 
+    user.age === 25 || user.age === 30
+);</pre>
+        </div>
+
+        <h3>3. Complex Comparisons</h3>
+        <div class="example">
+            <pre>
+// These operations are NOT supported:
+where(users, {
+    age: (age) => age > 30,     // Function predicates
+    salary: { $gt: 50000 },     // MongoDB-style operators 🤮
+    'name.length': 4            // Property operations
+});</pre>
+        </div>
+
+        <h3>4. Regular Expressions</h3>
+        <div class="example">
+            <pre>
+// RegExp matching also isn't implemented
+where(users, {
+    email: /.*@gmail\.com$/
+});
+
+// Use Array.filter() instead:
+const gmailUsers = users.filter(user => 
+    /.*@gmail\.com$/.test(user.email)
+);</pre>
+        </div>
+
+        <h3>5. When Not to Use</h3>
+        <ul>
+            <li><strong>Complex Filtering Logic:</strong> If you need OR conditions, ranges, or custom predicates</li>
+            <li><strong>Large Data Sets:</strong> When performance is critical and you need indexed operations...probably don't use JavaScript</li>
+            <li><strong>Dynamic Queries:</strong> When query conditions need to be built from different operators on the fly</li>
+            <li><strong>Partial Matches:</strong> When you need partial array matches or when a string contains operations</li>
+        </ul>
+
+        <h3>6. Performance Considerations</h3>
+        <div class="example">
+            <pre>
+// Avoid deeply nesting with large arrays
+const deeplyNested = where(largeArray, {
+    'level1.level2.level3.level4.property': value
+});
+
+// Each level of nesting increases complexity
+
+// Use direct access whenever possible:
+const result = largeArray.filter(item => 
+    item.level1?.level2?.level3?.level4?.property === value
+);</pre>
+        </div>
+    </section>
+
+    <h2>Test Results</h2>
+    <div class="console" id="output"></div>
+
+    <script>
+        // Capture console output
+        const output = document.getElementById('output');
+        const originalLog = console.log;
+        const originalError = console.error;
+
+        console.log = function(msg) {
+            output.innerHTML += msg + '<br>';
+            originalLog.apply(console, arguments);
+        };
+
+        console.error = function(msg) {
+            output.innerHTML += `<span style="color: red">${msg}</span><br>`;
+            originalError.apply(console, arguments);
+        };
+    </script>
+    <script src="where.js"></script>
+    <script src="where.test.js"></script>
+</body>
+</html> 
\ No newline at end of file