chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:55:23 +08:00
commit bc7eac8151
1701 changed files with 376767 additions and 0 deletions
@@ -0,0 +1,55 @@
# Dify Workflow Harness Test Documentation
## Test Inventory Plan
- `test_core.py`: backend discovery, command construction, packaging fixture checks
- `test_full_e2e.py`: wrapper subprocess smoke tests and workflow lifecycle forwarding
## Unit Test Plan
### utils/dify_workflow_backend.py
- resolve the upstream `dify-workflow` executable from PATH
- fall back to `python -m dify_workflow.cli` when only the Python package exists
- raise clear install guidance when neither exists
- build the final subprocess command correctly
### Packaging fixtures
- README documents two-step installation
- SKILL.md documents wrapper semantics and installation
- wrapper CLI exposes the expected top-level commands
## E2E Test Plan
- verify `--help` on the wrapper command
- create a minimal workflow through the wrapper when the upstream CLI is installed
- validate the created workflow through the wrapper
- inspect the workflow as JSON through the wrapper
## Notes
This harness wraps an external open-source CLI rather than shipping the workflow
engine itself. Full E2E tests therefore require the upstream Dify workflow CLI
to be installed locally before the suite is run. If the upstream CLI is missing
or broken, the E2E suite now fails explicitly instead of being skipped.
## Test Results
Verified on 2026-04-07 in the local CLI-Anything worktree.
### Commands Run
```bash
uv run --with pytest --with click --with prompt-toolkit --with-editable "c:\Users\lishun\py_ws\提交pr\dify-workflow-cli" python -m pytest cli_anything/dify_workflow/tests -vv -s
```
### Results
- total collected: 11
- passed: 11
### Notes
- Full forwarding tests were rerun with the upstream `dify-workflow` package installed editable from the local `dify-workflow-cli` repository.
- The wrapper suite now exercises `help`, `create`, `validate`, and `inspect -j` end-to-end against the real upstream CLI.
@@ -0,0 +1 @@
"""Tests for the Dify Workflow harness."""
@@ -0,0 +1,67 @@
import importlib.util
from pathlib import Path
from unittest.mock import patch
import pytest
from click.testing import CliRunner
from cli_anything.dify_workflow.dify_workflow_cli import cli
from cli_anything.dify_workflow.utils.dify_workflow_backend import (
build_command,
has_upstream_cli,
require_dify_workflow_command,
)
class TestBackendDiscovery:
def test_require_command_returns_binary_path(self):
with patch("cli_anything.dify_workflow.utils.dify_workflow_backend.shutil.which", return_value="/usr/bin/dify-workflow"):
assert require_dify_workflow_command() == ["/usr/bin/dify-workflow"]
def test_require_command_falls_back_to_python_module(self):
with patch("cli_anything.dify_workflow.utils.dify_workflow_backend.shutil.which", return_value=None), patch(
"cli_anything.dify_workflow.utils.dify_workflow_backend.importlib.util.find_spec",
return_value=object(),
), patch("cli_anything.dify_workflow.utils.dify_workflow_backend.sys.executable", "python"):
assert require_dify_workflow_command() == ["python", "-m", "dify_workflow.cli"]
def test_require_command_raises_install_guidance(self):
with patch("cli_anything.dify_workflow.utils.dify_workflow_backend.shutil.which", return_value=None), patch(
"cli_anything.dify_workflow.utils.dify_workflow_backend.importlib.util.find_spec",
return_value=None,
):
with pytest.raises(RuntimeError, match="dify-workflow command not found"):
require_dify_workflow_command()
def test_build_command_appends_args(self):
with patch("cli_anything.dify_workflow.utils.dify_workflow_backend.require_dify_workflow_command", return_value=["dify-workflow"]):
assert build_command(["guide", "-j"]) == ["dify-workflow", "guide", "-j"]
def test_has_upstream_cli_false_when_resolution_fails(self):
with patch("cli_anything.dify_workflow.utils.dify_workflow_backend.require_dify_workflow_command", side_effect=RuntimeError("missing")):
assert has_upstream_cli() is False
class TestWrapperCLI:
def test_help_renders(self):
runner = CliRunner()
result = runner.invoke(cli, ["--help"])
assert result.exit_code == 0
assert "CLI-Anything wrapper for the Dify workflow DSL editor" in result.output
assert "edit" in result.output
assert "config" in result.output
class TestPackagingFixtures:
def test_readme_documents_two_step_install(self):
package_root = Path(__file__).resolve().parents[1]
readme = (package_root / "README.md").read_text(encoding="utf-8")
assert "Install the upstream Dify workflow CLI first" in readme
assert "git+https://github.com/Akabane71/dify-workflow-cli.git@main" in readme
def test_skill_file_documents_wrapper_behavior(self):
package_root = Path(__file__).resolve().parents[1]
skill = (package_root / "skills" / "SKILL.md").read_text(encoding="utf-8")
assert "wrapper" in skill.lower()
assert "cli-anything-dify-workflow" in skill
assert "dify-workflow" in skill
@@ -0,0 +1,84 @@
import json
import os
import shutil
import subprocess
import sys
from cli_anything.dify_workflow.utils.dify_workflow_backend import require_dify_workflow_command
def _decode_output(data: bytes | None) -> str:
if not data:
return ""
return data.decode("utf-8", errors="replace")
def _require_working_upstream() -> None:
command = require_dify_workflow_command()
result = subprocess.run(
command + ["--help"],
capture_output=True,
check=False,
)
if result.returncode != 0:
stderr = _decode_output(result.stderr)
stdout = _decode_output(result.stdout)
raise RuntimeError(
"upstream dify-workflow CLI is required for wrapper E2E tests and must respond to --help.\n"
f"stdout: {stdout}\n"
f"stderr: {stderr}"
)
def _resolve_cli(name: str, module: str) -> list[str]:
force = os.environ.get("CLI_ANYTHING_FORCE_INSTALLED", "").strip() == "1"
path = shutil.which(name)
if path:
return [path]
if force:
raise RuntimeError(f"{name} not found in PATH. Install with: pip install -e .")
return [sys.executable, "-m", module]
class TestWrapperE2E:
CLI_BASE = _resolve_cli("cli-anything-dify-workflow", "cli_anything.dify_workflow")
@classmethod
def setup_class(cls):
_require_working_upstream()
def _run(self, args, check=True):
result = subprocess.run(self.CLI_BASE + args, capture_output=True, check=False)
stdout = _decode_output(result.stdout)
stderr = _decode_output(result.stderr)
if check and result.returncode != 0:
raise subprocess.CalledProcessError(result.returncode, result.args, output=stdout, stderr=stderr)
result.stdout = stdout
result.stderr = stderr
return result
def test_help(self):
result = self._run(["--help"])
assert result.returncode == 0
assert "create" in result.stdout
def test_create_and_validate_workflow(self, tmp_path):
workflow_path = tmp_path / "workflow.yaml"
result = self._run(["create", "-o", str(workflow_path), "--template", "llm", "-j"])
assert result.returncode == 0, result.stderr
data = json.loads(result.stdout)
assert data["status"] == "created"
result = self._run(["validate", str(workflow_path), "-j"])
assert result.returncode == 0, result.stderr
report = json.loads(result.stdout)
assert report["valid"] is True
def test_inspect_json(self, tmp_path):
workflow_path = tmp_path / "workflow.yaml"
self._run(["create", "-o", str(workflow_path)], check=True)
result = self._run(["inspect", str(workflow_path), "-j"])
assert result.returncode == 0, result.stderr
assert result.stdout.strip().startswith("{")