Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a00d7ef1c9 | ||
|
|
382ee67868 |
8 changed files with 283 additions and 8587 deletions
66
.gitignore
vendored
66
.gitignore
vendored
|
|
@ -1,64 +1,44 @@
|
|||
# Dependencies
|
||||
/schneespur/vendor/
|
||||
# ── Dependencies ──
|
||||
/node_modules/
|
||||
/vendor/
|
||||
/schneespur/node_modules/
|
||||
/schneespur/vendor/
|
||||
|
||||
# Environment
|
||||
# ── Local env (keep .env.example tracked) ──
|
||||
.env
|
||||
.env.backup
|
||||
.env.production
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# IDE / Editor
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Laravel
|
||||
# ── Laravel runtime ──
|
||||
/schneespur/storage/logs/*.log
|
||||
/schneespur/storage/framework/cache/*
|
||||
/schneespur/storage/framework/sessions/*
|
||||
/schneespur/storage/framework/views/*
|
||||
/schneespur/storage/testing/
|
||||
|
||||
# Build artifacts
|
||||
# ── Build artifacts ──
|
||||
/schneespur/public/build/
|
||||
/schneespur/public/hot
|
||||
/release/
|
||||
|
||||
# Testing
|
||||
# ── Internal dev files (not part of distributable app) ──
|
||||
/build.sh
|
||||
/moduldoku.md
|
||||
/package-lock.json
|
||||
|
||||
# ── Test caches ──
|
||||
.phpunit.result.cache
|
||||
.phpunit.cache/
|
||||
|
||||
# Release builds
|
||||
/release/
|
||||
# ── IDE / OS ──
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Misc
|
||||
*.bak
|
||||
*.orig
|
||||
|
||||
# ── GSD baseline (auto-generated) ──
|
||||
# ── Local tooling ──
|
||||
.gsd
|
||||
.gsd-id
|
||||
.mcp.json
|
||||
.bg-shell/
|
||||
*~
|
||||
*.code-workspace
|
||||
.env.*
|
||||
!.env.example
|
||||
node_modules/
|
||||
.next/
|
||||
dist/
|
||||
build/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
venv/
|
||||
target/
|
||||
vendor/
|
||||
*.log
|
||||
coverage/
|
||||
.cache/
|
||||
tmp/
|
||||
|
|
|
|||
215
build.sh
215
build.sh
|
|
@ -1,215 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
VERSION="${1:-1.0.0}"
|
||||
PRODUCT="schneespur"
|
||||
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
SOURCE_DIR="${PROJECT_DIR}/${PRODUCT}"
|
||||
BUILD_DIR="${PROJECT_DIR}/release/${PRODUCT}-${VERSION}"
|
||||
ZIP_FILE="${PROJECT_DIR}/release/${PRODUCT}-${VERSION}.zip"
|
||||
|
||||
echo "════════════════════════════════════════════"
|
||||
echo " Building ${PRODUCT} v${VERSION}"
|
||||
echo "════════════════════════════════════════════"
|
||||
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
# ── Clean previous build ──
|
||||
rm -rf "$BUILD_DIR" "$ZIP_FILE"
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
# ── 1. Frontend build ──
|
||||
echo ""
|
||||
echo "▸ Installing npm dependencies..."
|
||||
(cd "$SOURCE_DIR" && (npm ci --silent 2>/dev/null || npm install --silent))
|
||||
|
||||
echo "▸ Building frontend assets..."
|
||||
(cd "$SOURCE_DIR" && npm run build)
|
||||
|
||||
# ── 2. Composer production install ──
|
||||
echo ""
|
||||
echo "▸ Installing composer dependencies (production)..."
|
||||
(cd "$SOURCE_DIR" && composer install --no-dev --optimize-autoloader --no-interaction --quiet)
|
||||
|
||||
# ── 3. Copy files ──
|
||||
echo ""
|
||||
echo "▸ Copying project files..."
|
||||
|
||||
# Core Laravel → build root (flat layout, like 1.0.0)
|
||||
cp "$SOURCE_DIR/artisan" "$BUILD_DIR/"
|
||||
cp "$SOURCE_DIR/composer.json" "$BUILD_DIR/"
|
||||
cp "$SOURCE_DIR/composer.lock" "$BUILD_DIR/"
|
||||
cp "$SOURCE_DIR/.env.example" "$BUILD_DIR/"
|
||||
cp "$SOURCE_DIR/.editorconfig" "$BUILD_DIR/" 2>/dev/null || true
|
||||
cp "$SOURCE_DIR/.htaccess" "$BUILD_DIR/" 2>/dev/null || true
|
||||
|
||||
# Application code → build root
|
||||
cp -r "$SOURCE_DIR/app" "$BUILD_DIR/"
|
||||
cp -r "$SOURCE_DIR/bootstrap" "$BUILD_DIR/"
|
||||
cp -r "$SOURCE_DIR/config" "$BUILD_DIR/"
|
||||
cp -r "$SOURCE_DIR/database" "$BUILD_DIR/"
|
||||
cp -r "$SOURCE_DIR/lang" "$BUILD_DIR/"
|
||||
cp -r "$SOURCE_DIR/public" "$BUILD_DIR/"
|
||||
cp -r "$SOURCE_DIR/resources" "$BUILD_DIR/"
|
||||
cp -r "$SOURCE_DIR/routes" "$BUILD_DIR/"
|
||||
cp -r "$SOURCE_DIR/vendor" "$BUILD_DIR/"
|
||||
|
||||
# Modules directory — example module is dev-only and excluded from releases
|
||||
if [ -d "$SOURCE_DIR/modules" ]; then
|
||||
cp -r "$SOURCE_DIR/modules" "$BUILD_DIR/"
|
||||
rm -rf "$BUILD_DIR/modules/example"
|
||||
fi
|
||||
|
||||
# Documentation and legal → build root (flat, alongside code)
|
||||
cp "$PROJECT_DIR/README.md" "$BUILD_DIR/" 2>/dev/null || true
|
||||
cp "$PROJECT_DIR/LICENSE" "$BUILD_DIR/" 2>/dev/null || true
|
||||
cp "$PROJECT_DIR/INSTALL.de.md" "$BUILD_DIR/" 2>/dev/null || true
|
||||
cp "$PROJECT_DIR/INSTALL.en.md" "$BUILD_DIR/" 2>/dev/null || true
|
||||
|
||||
# ── 4. Prepare storage structure (empty, writable) ──
|
||||
echo "▸ Preparing storage structure..."
|
||||
rm -rf "$BUILD_DIR/storage"
|
||||
mkdir -p "$BUILD_DIR/storage/app/private"
|
||||
mkdir -p "$BUILD_DIR/storage/app/public"
|
||||
mkdir -p "$BUILD_DIR/storage/framework/cache/data"
|
||||
mkdir -p "$BUILD_DIR/storage/framework/sessions"
|
||||
mkdir -p "$BUILD_DIR/storage/framework/testing"
|
||||
mkdir -p "$BUILD_DIR/storage/framework/views"
|
||||
mkdir -p "$BUILD_DIR/storage/logs"
|
||||
|
||||
for dir in "$BUILD_DIR/storage/app/private" \
|
||||
"$BUILD_DIR/storage/app/public" \
|
||||
"$BUILD_DIR/storage/framework/cache/data" \
|
||||
"$BUILD_DIR/storage/framework/sessions" \
|
||||
"$BUILD_DIR/storage/framework/testing" \
|
||||
"$BUILD_DIR/storage/framework/views" \
|
||||
"$BUILD_DIR/storage/logs"; do
|
||||
touch "$dir/.gitkeep"
|
||||
done
|
||||
|
||||
# ── 5. Remove dev/unnecessary files ──
|
||||
echo "▸ Cleaning up dev files..."
|
||||
|
||||
# Remove installed.lock (fresh install!)
|
||||
rm -f "$BUILD_DIR/storage/app/installed.lock"
|
||||
|
||||
# Remove public/storage symlink (installer creates it)
|
||||
rm -f "$BUILD_DIR/public/storage"
|
||||
|
||||
# Remove bootstrap cache (regenerated on first run)
|
||||
rm -f "$BUILD_DIR/bootstrap/cache/"*.php 2>/dev/null || true
|
||||
|
||||
# Remove test files
|
||||
rm -rf "$BUILD_DIR/tests"
|
||||
|
||||
# Remove dev config/tooling
|
||||
rm -f "$BUILD_DIR/phpunit.xml"
|
||||
rm -f "$BUILD_DIR/.styleci.yml"
|
||||
rm -f "$BUILD_DIR/.gitignore"
|
||||
rm -f "$BUILD_DIR/.gitattributes"
|
||||
rm -f "$BUILD_DIR/package.json"
|
||||
rm -f "$BUILD_DIR/package-lock.json"
|
||||
rm -f "$BUILD_DIR/vite.config.js"
|
||||
|
||||
# Remove GSD/AI/editor artifacts
|
||||
rm -rf "$BUILD_DIR/.gsd"
|
||||
rm -f "$BUILD_DIR/.gsd-id"
|
||||
rm -f "$BUILD_DIR/CLAUDE.md"
|
||||
rm -f "$BUILD_DIR/gpt.md"
|
||||
rm -f "$BUILD_DIR/module.md"
|
||||
rm -f "$BUILD_DIR/site.md"
|
||||
rm -f "$BUILD_DIR/.mcp.json"
|
||||
|
||||
# Remove test/scratch files
|
||||
rm -f "$BUILD_DIR/test.txt"
|
||||
rm -f "$BUILD_DIR/test-file.txt"
|
||||
rm -f "$BUILD_DIR/app/test.php"
|
||||
|
||||
# Remove database factories/seeders (not needed in production)
|
||||
rm -rf "$BUILD_DIR/database/factories"
|
||||
rm -rf "$BUILD_DIR/database/seeders"
|
||||
|
||||
# ── 6. Slim vendor directory ──
|
||||
echo "▸ Slimming vendor directory..."
|
||||
|
||||
# Remove .git directories from vendor packages (source installs)
|
||||
find "$BUILD_DIR/vendor" -type d -name ".git" -exec rm -rf {} + 2>/dev/null || true
|
||||
|
||||
# Remove tests, docs, and other non-runtime directories
|
||||
find "$BUILD_DIR/vendor" -type d \( \
|
||||
-name "tests" -o \
|
||||
-name "Tests" -o \
|
||||
-name "test" -o \
|
||||
-name "Test" -o \
|
||||
-name "test_files" -o \
|
||||
-name "docs" -o \
|
||||
-name "doc" -o \
|
||||
-name "examples" -o \
|
||||
-name "example" -o \
|
||||
-name ".github" \
|
||||
\) -exec rm -rf {} + 2>/dev/null || true
|
||||
|
||||
# Remove non-runtime files
|
||||
find "$BUILD_DIR/vendor" -type f \( \
|
||||
-name "*.md" -o \
|
||||
-name "*.markdown" -o \
|
||||
-name "CHANGELOG*" -o \
|
||||
-name "CHANGE_LOG*" -o \
|
||||
-name "CHANGES*" -o \
|
||||
-name "UPGRADING*" -o \
|
||||
-name "UPGRADE*" -o \
|
||||
-name "SECURITY*" -o \
|
||||
-name "CONTRIBUTING*" -o \
|
||||
-name "CODE_OF_CONDUCT*" -o \
|
||||
-name ".editorconfig" -o \
|
||||
-name ".gitignore" -o \
|
||||
-name ".gitattributes" -o \
|
||||
-name ".php-cs-fixer*" -o \
|
||||
-name ".php_cs*" -o \
|
||||
-name "phpunit.xml*" -o \
|
||||
-name "phpstan*" -o \
|
||||
-name ".styleci.yml" -o \
|
||||
-name ".travis.yml" -o \
|
||||
-name "Makefile" -o \
|
||||
-name "Dockerfile" -o \
|
||||
-name "docker-compose*" \
|
||||
\) -delete 2>/dev/null || true
|
||||
|
||||
# ── 7. Write version file ──
|
||||
echo "▸ Writing version file..."
|
||||
cat > "$BUILD_DIR/VERSION" << EOF
|
||||
${VERSION}
|
||||
EOF
|
||||
|
||||
# ── 8. Write initial update state (prevents self-update to same version) ──
|
||||
echo "▸ Writing initial update state..."
|
||||
cat > "$BUILD_DIR/storage/app/schneespur_update_state.json" << EOF
|
||||
{"current_version":"${VERSION}","last_counter":1}
|
||||
EOF
|
||||
|
||||
# ── 9. Create ZIP ──
|
||||
echo ""
|
||||
echo "▸ Creating ZIP archive..."
|
||||
rm -f "${ZIP_FILE}.filepart"
|
||||
(cd "${BUILD_DIR}" && zip -r -q "${ZIP_FILE}" .)
|
||||
|
||||
# ── 10. Summary ──
|
||||
ZIP_SIZE=$(du -h "$ZIP_FILE" | cut -f1)
|
||||
FILE_COUNT=$(find "$BUILD_DIR" -type f | wc -l)
|
||||
|
||||
echo ""
|
||||
echo "════════════════════════════════════════════"
|
||||
echo " ✓ Build complete!"
|
||||
echo ""
|
||||
echo " Version: ${VERSION}"
|
||||
echo " Files: ${FILE_COUNT}"
|
||||
echo " ZIP: ${ZIP_FILE} (${ZIP_SIZE})"
|
||||
echo "════════════════════════════════════════════"
|
||||
echo ""
|
||||
echo " The ZIP is ready for distribution."
|
||||
echo " Users: unzip → FTP upload → open in browser → installer starts"
|
||||
|
||||
# ── 11. Restore dev dependencies ──
|
||||
echo ""
|
||||
echo "▸ Restoring dev composer dependencies..."
|
||||
(cd "$SOURCE_DIR" && composer install --no-interaction --quiet)
|
||||
1046
moduldoku.md
1046
moduldoku.md
File diff suppressed because it is too large
Load diff
7283
package-lock.json
generated
7283
package-lock.json
generated
File diff suppressed because it is too large
Load diff
27
schneespur/phpunit.xml
Normal file
27
schneespur/phpunit.xml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
cacheDirectory=".phpunit.cache"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Feature">
|
||||
<directory>tests/Feature</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<source>
|
||||
<include>
|
||||
<directory>app</directory>
|
||||
</include>
|
||||
</source>
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
<env name="APP_KEY" value="base64:dGVzdGluZ2tleXRlc3RpbmdrZXl0ZXN0aW5na2V5cw=="/>
|
||||
<env name="DB_CONNECTION" value="sqlite"/>
|
||||
<env name="DB_DATABASE" value=":memory:"/>
|
||||
<env name="QUEUE_CONNECTION" value="sync"/>
|
||||
<env name="MAIL_MAILER" value="array"/>
|
||||
<env name="CACHE_STORE" value="array"/>
|
||||
</php>
|
||||
</phpunit>
|
||||
17
schneespur/tests/CreatesApplication.php
Normal file
17
schneespur/tests/CreatesApplication.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
|
||||
trait CreatesApplication
|
||||
{
|
||||
public function createApplication(): \Illuminate\Foundation\Application
|
||||
{
|
||||
$app = require __DIR__.'/../bootstrap/app.php';
|
||||
|
||||
$app->make(Kernel::class)->bootstrap();
|
||||
|
||||
return $app;
|
||||
}
|
||||
}
|
||||
202
schneespur/tests/Feature/FilterRegistryTest.php
Normal file
202
schneespur/tests/Feature/FilterRegistryTest.php
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Services\Extension\FilterRegistry;
|
||||
use App\Services\Extension\NavigationRegistry;
|
||||
use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Tests\TestCase;
|
||||
|
||||
class FilterRegistryTest extends TestCase
|
||||
{
|
||||
use LazilyRefreshDatabase;
|
||||
|
||||
private FilterRegistry $registry;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->registry = new FilterRegistry;
|
||||
}
|
||||
|
||||
public function test_apply_returns_original_value_when_no_filters_registered(): void
|
||||
{
|
||||
$result = $this->registry->apply('schneespur.nonexistent.hook', ['a', 'b']);
|
||||
|
||||
$this->assertSame(['a', 'b'], $result);
|
||||
}
|
||||
|
||||
public function test_filters_execute_in_priority_order(): void
|
||||
{
|
||||
$order = [];
|
||||
|
||||
$this->registry->register('test.hook', function ($value) use (&$order) {
|
||||
$order[] = 'priority-200';
|
||||
return $value;
|
||||
}, 200);
|
||||
|
||||
$this->registry->register('test.hook', function ($value) use (&$order) {
|
||||
$order[] = 'priority-50';
|
||||
return $value;
|
||||
}, 50);
|
||||
|
||||
$this->registry->register('test.hook', function ($value) use (&$order) {
|
||||
$order[] = 'priority-100';
|
||||
return $value;
|
||||
}, 100);
|
||||
|
||||
$this->registry->apply('test.hook', 'start');
|
||||
|
||||
$this->assertSame(['priority-50', 'priority-100', 'priority-200'], $order);
|
||||
}
|
||||
|
||||
public function test_equal_priority_preserves_registration_order(): void
|
||||
{
|
||||
$order = [];
|
||||
|
||||
$this->registry->register('test.hook', function ($value) use (&$order) {
|
||||
$order[] = 'first';
|
||||
return $value;
|
||||
}, 100);
|
||||
|
||||
$this->registry->register('test.hook', function ($value) use (&$order) {
|
||||
$order[] = 'second';
|
||||
return $value;
|
||||
}, 100);
|
||||
|
||||
$this->registry->register('test.hook', function ($value) use (&$order) {
|
||||
$order[] = 'third';
|
||||
return $value;
|
||||
}, 100);
|
||||
|
||||
$this->registry->apply('test.hook', 'start');
|
||||
|
||||
$this->assertSame(['first', 'second', 'third'], $order);
|
||||
}
|
||||
|
||||
public function test_apply_passes_context_to_callbacks(): void
|
||||
{
|
||||
$receivedContext = [];
|
||||
|
||||
$this->registry->register('test.hook', function ($value, $ctxA, $ctxB) use (&$receivedContext) {
|
||||
$receivedContext = [$ctxA, $ctxB];
|
||||
return $value;
|
||||
});
|
||||
|
||||
$this->registry->apply('test.hook', 'value', 'context-a', 'context-b');
|
||||
|
||||
$this->assertSame(['context-a', 'context-b'], $receivedContext);
|
||||
}
|
||||
|
||||
public function test_throwing_callback_logs_warning_and_preserves_previous_value(): void
|
||||
{
|
||||
Log::shouldReceive('warning')
|
||||
->once()
|
||||
->withArgs(function ($message, $context) {
|
||||
return $message === 'FilterRegistry: callback failed'
|
||||
&& $context['hook'] === 'test.hook'
|
||||
&& str_contains($context['error'], 'Intentional test exception');
|
||||
});
|
||||
|
||||
$this->registry->register('test.hook', function (array $value) {
|
||||
$value[] = 'before-error';
|
||||
return $value;
|
||||
}, 10);
|
||||
|
||||
$this->registry->register('test.hook', function ($value) {
|
||||
throw new \RuntimeException('Intentional test exception');
|
||||
}, 20);
|
||||
|
||||
$this->registry->register('test.hook', function (array $value) {
|
||||
$value[] = 'after-error';
|
||||
return $value;
|
||||
}, 30);
|
||||
|
||||
$result = $this->registry->apply('test.hook', []);
|
||||
|
||||
$this->assertSame(['before-error', 'after-error'], $result);
|
||||
}
|
||||
|
||||
public function test_callbacks_can_transform_value_through_chain(): void
|
||||
{
|
||||
$this->registry->register('test.hook', function (int $value) {
|
||||
return $value + 10;
|
||||
}, 10);
|
||||
|
||||
$this->registry->register('test.hook', function (int $value) {
|
||||
return $value * 2;
|
||||
}, 20);
|
||||
|
||||
$result = $this->registry->apply('test.hook', 5);
|
||||
|
||||
$this->assertSame(30, $result);
|
||||
}
|
||||
|
||||
public function test_single_callback_executes(): void
|
||||
{
|
||||
$this->registry->register('test.hook', function (array $items) {
|
||||
$items[] = 'added';
|
||||
return $items;
|
||||
});
|
||||
|
||||
$result = $this->registry->apply('test.hook', ['original']);
|
||||
|
||||
$this->assertSame(['original', 'added'], $result);
|
||||
}
|
||||
|
||||
public function test_navigation_items_hook_is_applied(): void
|
||||
{
|
||||
$this->bootExampleModule();
|
||||
|
||||
$nav = $this->app->make(NavigationRegistry::class);
|
||||
$nav->addGroup('modules', 'Modules', 100);
|
||||
|
||||
$items = $nav->getItems();
|
||||
|
||||
$allSlugs = [];
|
||||
foreach ($items as $groupItems) {
|
||||
foreach ($groupItems as $item) {
|
||||
$allSlugs[] = $item['slug'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->assertContains('example-filter', $allSlugs);
|
||||
}
|
||||
|
||||
public function test_dashboard_kpis_hook_is_applied(): void
|
||||
{
|
||||
$this->bootExampleModule();
|
||||
|
||||
$filterRegistry = $this->app->make(FilterRegistry::class);
|
||||
|
||||
$widgets = $filterRegistry->apply('schneespur.dashboard.kpis', [
|
||||
['key' => 'original-widget', 'label' => 'Original'],
|
||||
]);
|
||||
|
||||
$keys = array_column($widgets, 'key');
|
||||
|
||||
$this->assertContains('example-filter-widget', $keys);
|
||||
}
|
||||
|
||||
private function bootExampleModule(): void
|
||||
{
|
||||
$modulePath = base_path('modules/example/src');
|
||||
spl_autoload_register(function (string $class) use ($modulePath) {
|
||||
$prefix = 'Schneespur\\Module\\Example\\';
|
||||
if (! str_starts_with($class, $prefix)) {
|
||||
return;
|
||||
}
|
||||
$relative = substr($class, strlen($prefix));
|
||||
$file = $modulePath . '/' . str_replace('\\', '/', $relative) . '.php';
|
||||
if (file_exists($file)) {
|
||||
require_once $file;
|
||||
}
|
||||
});
|
||||
|
||||
putenv('EXAMPLE_MODULE_ENABLED=true');
|
||||
$_ENV['EXAMPLE_MODULE_ENABLED'] = true;
|
||||
|
||||
$this->app->register(\Schneespur\Module\Example\ExampleServiceProvider::class);
|
||||
}
|
||||
}
|
||||
14
schneespur/tests/TestCase.php
Normal file
14
schneespur/tests/TestCase.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||
|
||||
abstract class TestCase extends BaseTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->withoutVite();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue