1
0
Эх сурвалжийг харах

:bug: Fixes proxy stack setters bug (#3807)

* :bug: Fixes proxy stack setters bug

* :test_tube: Adds additional test for stack direction

* :white_check_mark: Fixes test
Eric Kwoka 1 жил өмнө
parent
commit
0913cdb1ec

+ 7 - 7
packages/alpinejs/src/scope.js

@@ -64,14 +64,14 @@ let mergeProxyTrap = {
         )
     },
 
-    set({ objects }, name, value) {
-        return Reflect.set(
-            objects.find((obj) =>
+    set({ objects }, name, value, thisProxy) {
+        const target = objects.find((obj) =>
                 Object.prototype.hasOwnProperty.call(obj, name)
-            ) || objects[objects.length-1],
-            name,
-            value
-        )
+            ) || objects[objects.length - 1];
+        const descriptor = Object.getOwnPropertyDescriptor(target, name);
+        if (descriptor?.set && descriptor?.get)
+            return Reflect.set(target, name, value, thisProxy);
+        return Reflect.set(target, name, value);
     },
 }
 

+ 58 - 0
tests/cypress/integration/scope.spec.js

@@ -0,0 +1,58 @@
+import { haveText, html, test } from "../utils";
+
+test(
+    "properly merges the datastack",
+    [
+        html`
+            <div x-data="{ foo: 'fizz' }">
+                <div x-data="{ bar: 'buzz' }">
+                    <span x-text="foo + bar"></span>
+                </div>
+            </div>
+        `,
+    ],
+    ({ get }) => {
+        get("span").should(haveText("fizzbuzz"));
+    }
+);
+
+test(
+    "merges stack from bottom up",
+    [
+        html`
+            <div x-data="{ foo: 'fizz' }">
+                <div x-data="{ foo: 'buzz', get bar() { return this.foo } }">
+                    <span id="one" x-text="bar + foo"></span>
+                </div>
+                <span id="two" x-text="foo"></span>
+            </div>
+        `,
+    ],
+    ({ get }) => {
+        get("span#one").should(haveText("buzzbuzz"));
+        get("span#two").should(haveText("fizz"));
+    }
+);
+
+test(
+    "handles getter setter pairs",
+    [
+        html`
+            <div x-data="{ foo: 'fizzbuzz' }">
+                <div
+                    x-data="{ get bar() { return this.foo }, set bar(value) { this.foo = value } }"
+                >
+                    <span id="one" x-text="bar" @click="bar = 'foobar'"></span>
+                </div>
+                <span id="two" x-text="foo"></span>
+            </div>
+        `,
+    ],
+    ({ get }) => {
+        get("span#one").should(haveText("fizzbuzz"));
+        get("span#two").should(haveText("fizzbuzz"));
+        get("span#one").click();
+        get("span#one").should(haveText("foobar"));
+        get("span#two").should(haveText("foobar"));
+    }
+);