create-outsystems-astro 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,17 +11,29 @@ import { Operation, setCounterCount } from "../../lib/setCounterCount";
11
11
  standalone: true,
12
12
  template: `
13
13
  <div class="counter-title" slot="header">Counter</div>
14
-
15
- <div class="counter-controls">
16
- <button (click)="subtract()">-</button>
17
- <pre>{{ count() }}</pre>
18
- <button (click)="add()">+</button>
19
- </div>
20
-
21
- <div class="counter-message">
22
- <button (click)="showParentMessage()">Send value</button>
14
+ <div class="card-grid">
15
+ <div class="card">
16
+ Internal counter controls. It keeps state within the component.
17
+ <div class="card-content">
18
+ <div class="counter-controls">
19
+ <button (click)="subtract()">-</button>
20
+ <pre>{{ count() }}</pre>
21
+ <button (click)="add()">+</button>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <div class="card">
26
+ The button sends the current count value to a function in the parent
27
+ component.
28
+ <div class="card-content">
29
+ <div>
30
+ <button class="card-btn" (click)="showParentMessage()">
31
+ Send value
32
+ </button>
33
+ </div>
34
+ </div>
35
+ </div>
23
36
  </div>
24
-
25
37
  <div class="counter-logos">
26
38
  <img [src]="outSystemsLogo" alt="OutSystems logo" />
27
39
  <img [src]="astroLogo" alt="Astro logo" />
@@ -48,11 +60,11 @@ export default class CounterComponent implements OnInit {
48
60
  showParentMessage() {
49
61
  const fnName = this.messageFunctionName();
50
62
 
51
- // Safety check to ensure the function exists on window/document
63
+ // Safety check to ensure the function exists on window.
52
64
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
53
- if (typeof (document as any)[fnName] === "function") {
65
+ if (typeof (window as any)[fnName] === "function") {
54
66
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
- (document as any)[fnName](this.count());
67
+ (window as any)[fnName](this.count());
56
68
  }
57
69
  }
58
70
 
@@ -1,3 +1,4 @@
1
+ import { useStore } from "@nanostores/react";
1
2
  import { useState } from "react";
2
3
 
3
4
  import AstroLogo from "../../images/astro.png?url";
@@ -20,19 +21,50 @@ export default function Counter({
20
21
  const subtract = () =>
21
22
  setCount((i) => setCounterCount(i, Operation.Subtract));
22
23
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
- const showParentMessage = () => (document as any)[showMessage](count);
24
+ const showParentMessage = () => (window as any)[showMessage](count);
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ const nanoStoreValue = useStore((window as any).Stores["reactStore"]);
24
27
 
25
28
  return (
26
29
  <>
27
30
  {header}
28
- <div className="counter-controls">
29
- <button onClick={subtract}>-</button>
30
- <pre>{count}</pre>
31
- <button onClick={add}>+</button>
32
- </div>
33
- <div>{children}</div>
34
- <div className="counter-message">
35
- <button onClick={showParentMessage}>Send value</button>
31
+ <div className="card-grid">
32
+ <div className="card">
33
+ Internal counter controls. It keeps state within the component.
34
+ <div className="card-content">
35
+ <div className="counter-controls">
36
+ <button onClick={subtract}>-</button>
37
+ <pre>{count}</pre>
38
+ <button onClick={add}>+</button>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ <div className="card">
43
+ The button sends the current count value to a function in the parent
44
+ component.
45
+ <div className="card-content">
46
+ <div>
47
+ <button className="card-btn" onClick={showParentMessage}>
48
+ Send value
49
+ </button>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ <div className="card">
54
+ Slot content coming in to the component
55
+ <div className="card-content">
56
+ <div>{children}</div>
57
+ </div>
58
+ </div>
59
+ <div className="card">
60
+ Nano Store content
61
+ <div className="card-content">
62
+ <div>
63
+ <strong>Nano Store value:</strong>
64
+ <div id="nanostore">{nanoStoreValue}</div>
65
+ </div>
66
+ </div>
67
+ </div>
36
68
  </div>
37
69
  <div className="counter-logos">
38
70
  <img alt="OutSystems logo" src={OutSystemsLogo} />
@@ -1,8 +1,9 @@
1
1
  <script setup lang="ts">
2
2
  import { ref } from "vue";
3
+ import { useStore } from "@nanostores/vue";
3
4
 
4
- import OutSystemsLogo from "../../images/outsystems.png?url";
5
5
  import AstroLogo from "../../images/astro.png?url";
6
+ import OutSystemsLogo from "../../images/outsystems.png?url";
6
7
  import { Operation, setCounterCount } from "../../lib/setCounterCount";
7
8
 
8
9
  const props = defineProps<{
@@ -21,29 +22,63 @@ const subtract = () => {
21
22
  };
22
23
 
23
24
  const showParentMessage = () => {
24
- (document as Document)[props.showMessage]?.(count.value);
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ (window as any)[props.showMessage](count.value);
25
27
  };
28
+
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ const nanoStoreValue = useStore((window as any).Stores["vueStore"]);
26
31
  </script>
27
32
 
28
33
  <template>
29
- <div>
30
- <slot name="header" />
34
+ <slot name="header" />
31
35
 
32
- <div class="counter-controls">
33
- <button @click="subtract">-</button>
34
- <pre>{{ count }}</pre>
35
- <button @click="add">+</button>
36
+ <div class="card-grid">
37
+ <div class="card">
38
+ Internal counter controls. It keeps state within the component.
39
+ <div class="card-content">
40
+ <div class="counter-controls">
41
+ <button @click="subtract">-</button>
42
+ <pre>{{ count }}</pre>
43
+ <button @click="add">+</button>
44
+ </div>
45
+ </div>
36
46
  </div>
37
47
 
38
- <slot />
48
+ <div class="card">
49
+ The button sends the current count value to a function in the parent
50
+ component.
51
+ <div class="card-content">
52
+ <div>
53
+ <button class="card-btn" @click="showParentMessage">
54
+ Send value
55
+ </button>
56
+ </div>
57
+ </div>
58
+ </div>
39
59
 
40
- <div class="counter-message">
41
- <button @click="showParentMessage">Send value</button>
60
+ <div class="card">
61
+ Slot content coming in to the component
62
+ <div class="card-content">
63
+ <div>
64
+ <slot />
65
+ </div>
66
+ </div>
42
67
  </div>
43
68
 
44
- <div class="counter-logos">
45
- <img :src="OutSystemsLogo" alt="OutSystems logo" />
46
- <img :src="AstroLogo" alt="Astro logo" />
69
+ <div class="card">
70
+ Nano Store content
71
+ <div class="card-content">
72
+ <div>
73
+ <strong>Nano Store value:</strong>
74
+ <div id="nanostore">{{ nanoStoreValue }}</div>
75
+ </div>
76
+ </div>
47
77
  </div>
48
78
  </div>
79
+
80
+ <div class="counter-logos">
81
+ <img alt="OutSystems logo" :src="OutSystemsLogo" />
82
+ <img alt="Astro logo" :src="AstroLogo" />
83
+ </div>
49
84
  </template>
@@ -1,15 +1,31 @@
1
1
  ---
2
- import CounterComponent from '../../framework/angular/Counter.component';
2
+ import CounterComponent from "../../framework/angular/Counter.component";
3
3
  import styles from "../../styles/index.css?url";
4
4
  const initialCount = 5;
5
5
  const showMessage = "showMessage";
6
6
  ---
7
+
7
8
  <link href={styles} rel="stylesheet" />
8
9
  <script is:inline>
9
- document.showMessage = (count) => {
10
+ window.showMessage = (count) => {
10
11
  document.getElementById("counter").textContent = count;
11
12
  };
12
13
  </script>
13
- <CounterComponent client:visible initialCount={initialCount} showMessage={showMessage}>
14
- </CounterComponent>
15
- <div style="text-align: center; margin-top: 20px;">Counter value: <span id="counter"></span></div>
14
+ <div class="counter-title">HTML Content</div>
15
+ <div class="card-grid">
16
+ <div class="card">
17
+ Value sent back from component.
18
+ <div class="card-content">
19
+ <div style="text-align: center; margin-top: 30px;">
20
+ Counter value sent back: <br /><span id="counter"></span>
21
+ </div>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <hr />
26
+ <CounterComponent
27
+ client:visible
28
+ initialCount={initialCount}
29
+ showMessage={showMessage}
30
+ />
31
+
@@ -1,21 +1,58 @@
1
1
  ---
2
- import CounterComponent from '../../framework/react/Counter';
2
+ import CounterComponent from "../../framework/react/Counter";
3
3
  import styles from "../../styles/index.css?url";
4
4
  const initialCount = 5;
5
5
  const showMessage = "showMessage";
6
6
  ---
7
+
7
8
  <link href={styles} rel="stylesheet" />
8
- <script is:inline>
9
- document.showMessage = (count) => {
9
+ <script>
10
+ import { atom } from "nanostores";
11
+ window["showMessage"] = (count) => {
10
12
  document.getElementById("counter").textContent = count;
11
13
  };
14
+ window.Stores = [];
15
+ window.Stores["reactStore"] = atom("Test Value");
16
+ document.addEventListener("DOMContentLoaded", function () {
17
+ const input = document.getElementById("store");
18
+ input.value = window.Stores["reactStore"].get();
19
+ });
12
20
  </script>
13
- <CounterComponent client:only="react" initialCount={initialCount} showMessage={showMessage}>
14
- <div class="counter-title" slot="header">
15
- Counter
21
+ <div class="counter-title">HTML Content</div>
22
+ <div class="card-grid">
23
+ <div class="card">
24
+ Value sent back from component.
25
+ <div class="card-content">
26
+ <div style="text-align: center; margin-top: 30px;">
27
+ Counter value sent back: <br /><span id="counter"></span>
28
+ </div>
29
+ </div>
16
30
  </div>
31
+ <div class="card">
32
+ Update Nano Store value
33
+ <div class="card-content">
34
+ <div style="text-align: center; margin-top: 30px;">
35
+ <input
36
+ id="store"
37
+ placeholder="Type something..."
38
+ type="text"
39
+ /><button
40
+ class="card-btn"
41
+ onclick="window.Stores['reactStore'].set(document.getElementById('store').value)"
42
+ >Update Store</button
43
+ >
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ <hr />
49
+ <CounterComponent
50
+ client:only="react"
51
+ initialCount={initialCount}
52
+ showMessage={showMessage}
53
+ >
54
+ <div class="counter-title" slot="header">Counter Component</div>
17
55
  <div style="text-align: center;">
18
- <p>Slot content!</p>
56
+ <p><strong>This is content passed into the component.</strong></p>
19
57
  </div>
20
58
  </CounterComponent>
21
- <div style="text-align: center; margin-top: 20px;">Counter value: <span id="counter"></span></div>
@@ -4,18 +4,59 @@ import styles from "../../styles/index.css?url";
4
4
  const initialCount = 5;
5
5
  const showMessage = "showMessage";
6
6
  ---
7
+
8
+ <link href={styles} rel="stylesheet" />
9
+ <script>
10
+ import { atom } from "nanostores";
11
+ window["showMessage"] = (count) => {
12
+ document.getElementById("counter").textContent = count;
13
+ };
14
+ window.Stores = [];
15
+ window.Stores["vueStore"] = atom("Test Value");
16
+ document.addEventListener("DOMContentLoaded", function () {
17
+ const input = document.getElementById("store");
18
+ input.value = window.Stores["vueStore"].get();
19
+ });
20
+ </script>
21
+ <div class="counter-title">HTML Content</div>
22
+ <div class="card-grid">
23
+ <div class="card">
24
+ Value sent back from component.
25
+ <div class="card-content">
26
+ <div style="text-align: center; margin-top: 30px;">
27
+ Counter value sent back: <br /><span id="counter"></span>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ <div class="card">
32
+ Update Nano Store value
33
+ <div class="card-content">
34
+ <div style="text-align: center; margin-top: 30px;">
35
+ <input
36
+ id="store"
37
+ placeholder="Type something..."
38
+ type="text"
39
+ /><button
40
+ class="card-btn"
41
+ onclick="window.Stores['vueStore'].set(document.getElementById('store').value)"
42
+ >Update Store</button
43
+ >
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ <hr />
7
49
  <link href={styles} rel="stylesheet" />
8
50
  <script is:inline>
9
- document.showMessage = (count) => {
51
+ window.showMessage = (count) => {
10
52
  document.getElementById("counter").textContent = count;
11
53
  };
12
54
  </script>
13
55
  <CounterComponent client:only="vue" initialCount={initialCount} showMessage={showMessage}>
14
56
  <div class="counter-title" slot="header">
15
- Counter
57
+ Counter Component
16
58
  </div>
17
59
  <div style="text-align: center;">
18
- <p>Slot content!</p>
60
+ <p>This is content passed into the component.</p>
19
61
  </div>
20
62
  </CounterComponent>
21
- <div style="text-align: center; margin-top: 20px;">Counter value: <span id="counter"></span></div>
File without changes
@@ -11,10 +11,12 @@
11
11
  grid-template-columns: repeat(3, minmax(0, 1fr));
12
12
  margin-top: 0.5em;
13
13
  place-items: center;
14
+ border: 1;
14
15
  }
15
16
 
16
17
  .counter-message,
17
18
  .logos {
19
+ font-size: 1.2em;
18
20
  text-align: center;
19
21
  }
20
22
 
@@ -28,3 +30,66 @@
28
30
  .counter-logos img {
29
31
  width: 150px;
30
32
  }
33
+
34
+ .card {
35
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); /* Add shadows to create the "card" effect */
36
+ transition: 0.3s; /* Smooth transition for hover effects */
37
+ border-radius: 5px; /* Rounded corners */
38
+ overflow: hidden; /* Ensures content stays within the rounded corners */
39
+ background-color: #fff;
40
+ padding: 10px;
41
+ }
42
+
43
+ /* On mouse-over, add a deeper shadow */
44
+ .card:hover {
45
+ box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
46
+ }
47
+
48
+ .card-image {
49
+ width: 100%; /* Image takes full width of the card */
50
+ height: 200px; /* Fixed height for consistency */
51
+ object-fit: cover; /* Ensures image covers the area without distortion */
52
+ }
53
+
54
+ .card-content {
55
+ padding: 16px; /* Add some padding inside the card container */
56
+ }
57
+
58
+ .card-title {
59
+ margin-top: 0;
60
+ font-size: 1.25rem;
61
+ }
62
+
63
+ .card-description {
64
+ color: #555;
65
+ }
66
+
67
+ .card-link {
68
+ display: inline-block;
69
+ margin-top: 10px;
70
+ color: dodgerblue;
71
+ text-decoration: none;
72
+ }
73
+
74
+ .card-grid {
75
+ display: grid;
76
+ /* Automatically fill columns with a minimum width of 250px and maximum of 1fr */
77
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
78
+ gap: 24px; /* Space between cards */
79
+ padding: 24px;
80
+ }
81
+
82
+ .card-btn {
83
+ margin-top: 20px;
84
+ padding: 10px 15px;
85
+ background-color: #007bff;
86
+ color: white;
87
+ border: none;
88
+ border-radius: 5px;
89
+ cursor: pointer;
90
+ align-self: flex-start; /* Button size */
91
+ }
92
+
93
+ .card-btn:hover {
94
+ background-color: #0056b3;
95
+ }
@@ -6,11 +6,13 @@ test.beforeEach(async ({ page }) => {
6
6
 
7
7
  test.describe("Has values", () => {
8
8
  test("Should have header", async ({ page }) => {
9
- await expect(page.getByText("Counter")).toBeVisible();
9
+ await expect(page.getByText("Counter Component")).toBeVisible();
10
10
  });
11
11
 
12
12
  test("Should have slot content", async ({ page }) => {
13
- await expect(page.getByText("Slot content")).toBeVisible();
13
+ await expect(
14
+ page.getByText("This is content passed into the component"),
15
+ ).toBeVisible();
14
16
  });
15
17
  });
16
18
 
@@ -30,3 +32,11 @@ test.describe("Change counter", () => {
30
32
  await expect(page.locator("span#counter")).toContainText("5");
31
33
  });
32
34
  });
35
+
36
+ test.describe("Update Nano Store", () => {
37
+ test("Should update Nano Store", async ({ page }) => {
38
+ await page.locator("#store").fill("Updated Value");
39
+ await page.getByRole("button", { name: "Update Store" }).click();
40
+ await expect(page.locator("#nanostore")).toHaveText("Updated Value");
41
+ });
42
+ });
@@ -6,11 +6,13 @@ test.beforeEach(async ({ page }) => {
6
6
 
7
7
  test.describe("Has values", () => {
8
8
  test("Should have header", async ({ page }) => {
9
- await expect(page.getByText("Counter")).toBeVisible();
9
+ await expect(page.getByText("Counter Component")).toBeVisible();
10
10
  });
11
11
 
12
12
  test("Should have slot content", async ({ page }) => {
13
- await expect(page.getByText("Slot content")).toBeVisible();
13
+ await expect(
14
+ page.getByText("This is content passed into the component"),
15
+ ).toBeVisible();
14
16
  });
15
17
  });
16
18
 
@@ -30,3 +32,11 @@ test.describe("Change counter", () => {
30
32
  await expect(page.locator("span#counter")).toContainText("5");
31
33
  });
32
34
  });
35
+
36
+ test.describe("Update Nano Store", () => {
37
+ test("Should update Nano Store", async ({ page }) => {
38
+ await page.locator("#store").fill("Updated Value");
39
+ await page.getByRole("button", { name: "Update Store" }).click();
40
+ await expect(page.locator("#nanostore")).toHaveText("Updated Value");
41
+ });
42
+ });
@@ -1,5 +1,5 @@
1
1
  import { fireEvent, render, screen } from "@testing-library/angular";
2
- import { vi } from "vitest";
2
+ import { it, vi } from "vitest";
3
3
  import CounterComponent from "../../../src/framework/angular/Counter.component";
4
4
 
5
5
  describe("CounterComponent (Testing Library)", () => {
@@ -1,4 +1,6 @@
1
- import { fireEvent, render, screen } from "@testing-library/react";
1
+ import { act, fireEvent, render, screen } from "@testing-library/react";
2
+ import { it, vi } from "vitest";
3
+
2
4
  import Counter from "../../../src/framework/react/Counter";
3
5
 
4
6
  describe("Counter", () => {
@@ -9,14 +11,30 @@ describe("Counter", () => {
9
11
  showMessage: "mockFunction",
10
12
  };
11
13
 
14
+ let capturedListener: ((val: string) => void) | undefined;
15
+ let storeValue = "Mocked Nano Value";
16
+
12
17
  beforeEach(() => {
13
- // Mock the document function
14
18
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
- (document as any).mockFunction = vi.fn();
19
+ (window as any).mockFunction = vi.fn();
20
+
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ (window as any).Stores = {
23
+ reactStore: {
24
+ get: vi.fn(() => storeValue),
25
+ listen: vi.fn((callback) => {
26
+ capturedListener = callback;
27
+ callback(storeValue);
28
+ return () => {};
29
+ }),
30
+ },
31
+ };
16
32
  });
17
33
 
18
34
  afterEach(() => {
19
35
  vi.clearAllMocks();
36
+ capturedListener = undefined;
37
+ storeValue = "Mocked Nano Value";
20
38
  });
21
39
 
22
40
  it("renders the initial count", () => {
@@ -36,23 +54,30 @@ describe("Counter", () => {
36
54
 
37
55
  it("increments count when add button is clicked", () => {
38
56
  render(<Counter {...defaultProps} />);
39
- const addButton = screen.getByRole("button", { name: "+" });
40
- fireEvent.click(addButton);
57
+ fireEvent.click(screen.getByRole("button", { name: "+" }));
41
58
  expect(screen.getByText("6")).toBeInTheDocument();
42
59
  });
43
60
 
44
61
  it("decrements count when subtract button is clicked", () => {
45
62
  render(<Counter {...defaultProps} />);
46
- const subtractButton = screen.getByRole("button", { name: "-" });
47
- fireEvent.click(subtractButton);
63
+ fireEvent.click(screen.getByRole("button", { name: "-" }));
48
64
  expect(screen.getByText("4")).toBeInTheDocument();
49
65
  });
50
66
 
51
67
  it("calls the show message function", () => {
52
68
  render(<Counter {...defaultProps} />);
53
- const sendButton = screen.getByRole("button", { name: "Send value" });
54
- fireEvent.click(sendButton);
69
+ fireEvent.click(screen.getByRole("button", { name: "Send value" }));
55
70
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
- expect((document as any).mockFunction).toHaveBeenCalledWith(5);
71
+ expect((window as any).mockFunction).toHaveBeenCalledWith(5);
72
+ });
73
+
74
+ it("updates the component when the nanostore value changes", async () => {
75
+ render(<Counter {...defaultProps} />);
76
+ expect(screen.getByText(/Mocked Nano Value/i)).toBeInTheDocument();
77
+ await act(async () => {
78
+ storeValue = "Updated Nano Value";
79
+ capturedListener?.("Updated Nano Value");
80
+ });
81
+ expect(await screen.findByText(/Updated Nano Value/i)).toBeInTheDocument();
57
82
  });
58
83
  });
@@ -1,4 +1,6 @@
1
- import { fireEvent, render, screen } from "@testing-library/vue";
1
+ import { fireEvent, render, screen, waitFor } from "@testing-library/vue";
2
+ import { it, vi } from "vitest";
3
+
2
4
  import Counter from "../../../src/framework/vue/Counter.vue";
3
5
 
4
6
  describe("Counter", () => {
@@ -7,15 +9,34 @@ describe("Counter", () => {
7
9
  showMessage: "mockFunction",
8
10
  };
9
11
 
12
+ let capturedListener: ((val: string) => void) | undefined;
13
+ let storeValue = "Mocked Nano Value";
14
+
10
15
  beforeEach(() => {
11
16
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
- (document as any).mockFunction = vi.fn();
17
+ (window as any).mockFunction = vi.fn();
18
+
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ (window as any).Stores = {
21
+ vueStore: {
22
+ get: vi.fn(() => storeValue),
23
+ subscribe: vi.fn((callback) => {
24
+ capturedListener = callback;
25
+ callback(storeValue);
26
+ return () => {};
27
+ }),
28
+ },
29
+ };
13
30
  });
14
31
 
15
32
  afterEach(() => {
16
33
  vi.clearAllMocks();
17
34
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
- delete (document as any).mockFunction;
35
+ delete (window as any).mockFunction;
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ delete (window as any).Stores;
38
+ capturedListener = undefined;
39
+ storeValue = "Mocked Nano Value";
19
40
  });
20
41
 
21
42
  it("renders the initial count", () => {
@@ -88,6 +109,23 @@ describe("Counter", () => {
88
109
 
89
110
  await fireEvent.click(screen.getByRole("button", { name: "Send value" }));
90
111
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
91
- expect((document as any).mockFunction).toHaveBeenCalledWith(5);
112
+ expect((window as any).mockFunction).toHaveBeenCalledWith(5);
113
+ });
114
+
115
+ it("updates the component when the nanostore value changes", async () => {
116
+ render(Counter, {
117
+ props: defaultProps,
118
+ slots: {
119
+ default: "<div><p>Test Children</p></div>",
120
+ header: "<div>Test Header</div>",
121
+ },
122
+ });
123
+
124
+ expect(screen.getByText(/Mocked Nano Value/i)).toBeInTheDocument();
125
+ await waitFor(async () => {
126
+ storeValue = "Updated Nano Value";
127
+ capturedListener?.("Updated Nano Value");
128
+ });
129
+ expect(await screen.findByText(/Updated Nano Value/i)).toBeInTheDocument();
92
130
  });
93
131
  });