diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index a2a09b7..0000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,73 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ "main", "develop" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "main", "develop" ] - schedule: - - cron: '44 22 * * 5' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - pull-requests: write - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'javascript-typescript' ] - # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] - # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 - - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index bcaaaf7..9f5e289 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -17,8 +17,8 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/setup-node@v4 - - uses: actions/checkout@v4 + - uses: actions/setup-node@v5 + - uses: actions/checkout@v5 with: repository: Next2D/player ref: main @@ -31,8 +31,8 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/setup-node@v4 - - uses: actions/checkout@v4 + - uses: actions/setup-node@v5 + - uses: actions/checkout@v5 with: repository: Next2D/player ref: main diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f41fcb3..d4f9e53 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,8 +17,8 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v5 + - uses: actions/setup-node@v5 - run: npm install - run: npx eslint ./src/**/*.ts @@ -28,7 +28,7 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v5 + - uses: actions/setup-node@v5 - run: npm install - run: npx eslint ./src/**/*.ts \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index df25717..892042c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,8 +12,8 @@ jobs: contents: read pull-requests: write steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v5 + - uses: actions/setup-node@v5 with: node-version: "22.x" registry-url: "https://registry.npmjs.org" diff --git a/package.json b/package.json index f1cd5d1..b5d4752 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@next2d/framework", "description": "Next2D Framework is designed according to the principles of clean architecture, domain-driven development, test-driven development, and MVVM, with an emphasis on flexibility, scalability, and maintainability, and a design methodology that keeps each layer loosely coupled.", - "version": "3.0.12", + "version": "3.0.13", "homepage": "https://next2d.app", "bugs": "https://github.com/Next2D/Framework/issues/new", "author": "Toshiyuki Ienaga (https://github.com/ienaga/)", @@ -32,18 +32,18 @@ }, "devDependencies": { "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.36.0", - "@types/node": "^24.6.2", - "@typescript-eslint/eslint-plugin": "^8.45.0", - "@typescript-eslint/parser": "^8.45.0", - "@vitest/web-worker": "^3.2.4", - "eslint": "^9.36.0", - "eslint-plugin-unused-imports": "^4.2.0", + "@eslint/js": "^9.39.0", + "@types/node": "^24.9.2", + "@typescript-eslint/eslint-plugin": "^8.46.2", + "@typescript-eslint/parser": "^8.46.2", + "@vitest/web-worker": "^4.0.6", + "eslint": "^9.39.0", + "eslint-plugin-unused-imports": "^4.3.0", "globals": "^16.4.0", - "jsdom": "^27.0.0", + "jsdom": "^27.1.0", "typescript": "^5.9.3", - "vite": "^7.1.8", - "vitest": "^3.2.4", + "vite": "^7.1.12", + "vitest": "^4.0.6", "vitest-webgl-canvas-mock": "^1.1.0" }, "peerDependencies": { diff --git a/src/application/Application/service/ApplicationQueryStringParserService.ts b/src/application/Application/service/ApplicationQueryStringParserService.ts index 75923ba..265ae6e 100644 --- a/src/application/Application/service/ApplicationQueryStringParserService.ts +++ b/src/application/Application/service/ApplicationQueryStringParserService.ts @@ -1,4 +1,4 @@ -import type { IQueryObject } from "src/interface/IQueryObject"; +import type { IQueryObject } from "../../../interface/IQueryObject"; import { $getConfig } from "../../variable/Config"; import { query } from "../../variable/Query"; diff --git a/src/application/Application/usecase/ApplicationGotoViewUseCase.test.ts b/src/application/Application/usecase/ApplicationGotoViewUseCase.test.ts new file mode 100644 index 0000000..bab84bb --- /dev/null +++ b/src/application/Application/usecase/ApplicationGotoViewUseCase.test.ts @@ -0,0 +1,148 @@ +import { execute } from "./ApplicationGotoViewUseCase"; +import { describe, expect, it, vi, beforeEach } from "vitest"; +import { MovieClip } from "@next2d/display"; +import { Context } from "../../Context"; +import { $setConfig } from "../../variable/Config"; +import { $setContext } from "../../variable/Context"; +import { response } from "../../../infrastructure/Response/variable/Response"; + +vi.mock("../../../domain/screen/Capture/service/AddScreenCaptureService", () => ({ + execute: vi.fn().mockResolvedValue(undefined) +})); + +vi.mock("../../../domain/screen/Capture/service/DisposeCaptureService", () => ({ + execute: vi.fn() +})); + +vi.mock("../../../domain/loading/Loading/service/LoadingStartService", () => ({ + execute: vi.fn().mockResolvedValue(undefined) +})); + +vi.mock("../../../domain/loading/Loading/service/LoadingEndService", () => ({ + execute: vi.fn().mockResolvedValue(undefined) +})); + +vi.mock("../../../infrastructure/Response/usecase/ResponseRemoveVariableUseCase", () => ({ + execute: vi.fn() +})); + +vi.mock("../service/ApplicationQueryStringParserService", () => ({ + execute: vi.fn() +})); + +vi.mock("../../../infrastructure/Request/usecase/RequestUseCase", () => ({ + execute: vi.fn().mockResolvedValue([]) +})); + +vi.mock("../../../domain/callback/service/CallbackService", () => ({ + execute: vi.fn().mockResolvedValue(undefined) +})); + +describe("ApplicationGotoViewUseCase Test", () => +{ + let mockApplication: any; + let mockContext: Context; + let root: MovieClip; + + beforeEach(() => + { + response.clear(); + + mockApplication = { + currentName: "", + popstate: false + }; + + root = new MovieClip(); + mockContext = new Context(root); + mockContext.unbind = vi.fn().mockResolvedValue(undefined); + mockContext.bind = vi.fn().mockResolvedValue(null); + + $setContext(mockContext); + $setConfig({ + platform: "web", + spa: false, + stage: { + width: 800, + height: 600, + fps: 60 + } + }); + + global.history = { + pushState: vi.fn() + } as any; + + global.location = { + origin: "http://localhost" + } as any; + + vi.clearAllMocks(); + }); + + it("execute test case1: basic navigation without loading", async () => + { + const { execute: applicationQueryStringParserService } = await import("../service/ApplicationQueryStringParserService"); + const { execute: requestUseCase } = await import("../../../infrastructure/Request/usecase/RequestUseCase"); + + vi.mocked(applicationQueryStringParserService).mockReturnValue({ + name: "home", + queryString: "" + }); + + vi.mocked(requestUseCase).mockResolvedValue([]); + + await execute(mockApplication, "home"); + + expect(mockContext.unbind).toHaveBeenCalled(); + expect(mockApplication.currentName).toBe("home"); + expect(mockContext.bind).toHaveBeenCalledWith("home"); + }); + + it("execute test case2: navigation with response data", async () => + { + const { execute: applicationQueryStringParserService } = await import("../service/ApplicationQueryStringParserService"); + const { execute: requestUseCase } = await import("../../../infrastructure/Request/usecase/RequestUseCase"); + + vi.mocked(applicationQueryStringParserService).mockReturnValue({ + name: "dashboard", + queryString: "" + }); + + const mockResponses = [ + { name: "user", response: { id: 1, name: "Test User" } }, + { name: "settings", response: { theme: "dark" } } + ]; + + vi.mocked(requestUseCase).mockResolvedValue(mockResponses); + + await execute(mockApplication, "dashboard"); + + expect(response.get("user")).toEqual({ id: 1, name: "Test User" }); + expect(response.get("settings")).toEqual({ theme: "dark" }); + expect(mockApplication.currentName).toBe("dashboard"); + }); + + it("execute test case3: handle response without name", async () => + { + const { execute: applicationQueryStringParserService } = await import("../service/ApplicationQueryStringParserService"); + const { execute: requestUseCase } = await import("../../../infrastructure/Request/usecase/RequestUseCase"); + + vi.mocked(applicationQueryStringParserService).mockReturnValue({ + name: "test", + queryString: "" + }); + + const mockResponses = [ + { name: "", response: { data: "should be skipped" } }, + { name: "valid", response: { data: "should be set" } } + ]; + + vi.mocked(requestUseCase).mockResolvedValue(mockResponses); + + await execute(mockApplication, "test"); + + expect(response.has("")).toBe(false); + expect(response.get("valid")).toEqual({ data: "should be set" }); + }); +}); diff --git a/src/domain/loading/Loading.ts b/src/domain/loading/Loading.ts index aa7a071..a7bed1b 100644 --- a/src/domain/loading/Loading.ts +++ b/src/domain/loading/Loading.ts @@ -1,4 +1,4 @@ -import type { ILoading } from "src/interface/ILoading"; +import type { ILoading } from "../../interface/ILoading"; /** * @type {object} diff --git a/src/index.ts b/src/index.ts index 82a2b09..58a36e7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,7 @@ import { TextFieldContent } from "./application/content/TextFieldContent"; import { VideoContent } from "./application/content/VideoContent"; // output build version -console.log("%c Next2D Framework %c 3.0.12 %c https://next2d.app", +console.log("%c Next2D Framework %c 3.0.13 %c https://next2d.app", "color: #fff; background: #5f5f5f", "color: #fff; background: #4bc729", ""); diff --git a/src/infrastructure/Request/repository/RequestContentRepository.ts b/src/infrastructure/Request/repository/RequestContentRepository.ts index 3c98793..388e441 100644 --- a/src/infrastructure/Request/repository/RequestContentRepository.ts +++ b/src/infrastructure/Request/repository/RequestContentRepository.ts @@ -1,4 +1,4 @@ -import type { IRequest } from "src/interface/IRequest"; +import type { IRequest } from "../../../interface/IRequest"; import { Loader } from "@next2d/display"; import { URLRequest } from "@next2d/net"; import { cache } from "../../../application/variable/Cache"; diff --git a/src/infrastructure/Request/repository/RequestCustomRepository.ts b/src/infrastructure/Request/repository/RequestCustomRepository.ts index c13564d..9fb5544 100644 --- a/src/infrastructure/Request/repository/RequestCustomRepository.ts +++ b/src/infrastructure/Request/repository/RequestCustomRepository.ts @@ -1,4 +1,4 @@ -import type { IRequest } from "src/interface/IRequest"; +import type { IRequest } from "../../../interface/IRequest"; import { packages } from "../../../application/variable/Packages"; import { cache } from "../../../application/variable/Cache"; import { ResponseDTO } from "../../Response/dto/ResponseDTO"; diff --git a/tsconfig.json b/tsconfig.json index 36f1234..999270b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,10 +19,7 @@ "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - - "baseUrl": ".", "outDir": "./dist/src", - "types": [ "vitest/globals" ] @@ -37,6 +34,6 @@ "scripts", "dist", "src/**/*.test.ts", - ".github", + ".github" ] } \ No newline at end of file