Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7668fff294 | |||
| a8e6479193 | |||
| 40ad766d62 | |||
| 3ac291c693 |
@@ -76,10 +76,29 @@ jobs:
|
||||
echo "Version: $VERSION"
|
||||
echo "Commit: $COMMIT"
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install Frontend Dependencies & Build
|
||||
run: |
|
||||
cd src/frontend
|
||||
npm install
|
||||
npm run build
|
||||
cd ../..
|
||||
|
||||
- name: Copy Built Frontend to wwwroot
|
||||
run: |
|
||||
mkdir -p src/dotnet/QuantEngine.Web/wwwroot
|
||||
cp -r src/frontend/dist/* src/dotnet/QuantEngine.Web/wwwroot/
|
||||
echo "✓ Frontend assets copied to BFF wwwroot"
|
||||
|
||||
- name: Restore
|
||||
run: |
|
||||
dotnet restore src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj
|
||||
|
||||
|
||||
- name: Build (Release)
|
||||
run: |
|
||||
dotnet build src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj \
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace QuantEngine.Core.Tests
|
||||
{
|
||||
public class BffApiTests
|
||||
{
|
||||
[Fact]
|
||||
public void UpdateFactorThreshold_ValidJson_ParsesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var jsonString = "{\"momentum_lookback\": 20, \"volatility_cap\": 0.05}";
|
||||
|
||||
// Act
|
||||
using var doc = JsonDocument.Parse(jsonString);
|
||||
var root = doc.RootElement;
|
||||
var lookback = root.GetProperty("momentum_lookback").GetInt32();
|
||||
var cap = root.GetProperty("volatility_cap").GetDouble();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(20, lookback);
|
||||
Assert.Equal(0.05, cap);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExportStreamingFactorOlap_WriteCsvRow_MatchesExpectedFormat()
|
||||
{
|
||||
// Arrange
|
||||
var sb = new StringBuilder();
|
||||
var headers = new[] { "ticker", "as_of_date", "close_price", "nav_price" };
|
||||
sb.AppendLine(string.Join(",", headers));
|
||||
|
||||
var row = new object[] { "123456", "2026-07-25", 50000, 49800 };
|
||||
sb.AppendLine(string.Join(",", row));
|
||||
|
||||
// Act
|
||||
var output = sb.ToString();
|
||||
|
||||
// Assert
|
||||
Assert.Contains("ticker,as_of_date,close_price,nav_price", output);
|
||||
Assert.Contains("123456,2026-07-25,50000,49800", output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BulkInsertMarketExcel_EmptyCellValidation_DetectsNull()
|
||||
{
|
||||
// Arrange
|
||||
string? ticker = null;
|
||||
double? price = null;
|
||||
|
||||
|
||||
// Act
|
||||
bool isInvalid = string.IsNullOrEmpty(ticker) || !price.HasValue;
|
||||
|
||||
// Assert
|
||||
Assert.True(isInvalid);
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+2801
-1
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,8 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc -b && vite build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"test": "vitest run"
|
||||
},
|
||||
"dependencies": {
|
||||
"@primevue/themes": "^4.3.1",
|
||||
@@ -16,14 +17,20 @@
|
||||
"pinia": "^4.0.2",
|
||||
"primevue": "^4.3.1",
|
||||
"vue": "^3.5.39",
|
||||
"vue-router": "^4.6.4"
|
||||
"vue-router": "^4.6.4",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.13.2",
|
||||
"@vitejs/plugin-vue": "^6.0.7",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@vue/tsconfig": "^0.9.1",
|
||||
"jsdom": "^26.0.0",
|
||||
"typescript": "~6.0.2",
|
||||
"vite": "^8.1.1",
|
||||
"vitest": "^3.0.4",
|
||||
"vue-tsc": "^3.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ const columnDefs = ref<ColDef[]>([
|
||||
{
|
||||
headerName: '에러 건수', field: 'totalErrors',
|
||||
type: 'numericColumn',
|
||||
cellStyle: params => params.value > 0 ? { color: '#e74c3c', fontWeight: 'bold' } : { color: '#2ecc71' }
|
||||
cellStyle: params => params.value > 0 ? { color: '#e74c3c', fontWeight: 'bold' } : { color: '#2ecc71', fontWeight: 'normal' }
|
||||
|
||||
},
|
||||
{
|
||||
headerName: '실행 상태', field: 'status',
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { mount } from '@vue/test-utils';
|
||||
import TemplateGalleryView from '../TemplateGalleryView.vue';
|
||||
import RealOlapExportLayout from '../RealOlapExportLayout.vue';
|
||||
|
||||
describe('Prototype Template UI Rendering Tests', () => {
|
||||
it('TemplateGalleryView should render all 9 template options', () => {
|
||||
const wrapper = mount(TemplateGalleryView, {
|
||||
global: {
|
||||
stubs: {
|
||||
'router-link': true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 갤러리 타이틀 렌더링 검증
|
||||
expect(wrapper.text()).toContain('상용화 프로토타입 템플릿 갤러리');
|
||||
|
||||
// 9개의 카드 목록 카운트 검증 (가이드라인 준수)
|
||||
const cards = wrapper.findAll('router-link-stub');
|
||||
expect(cards.length).toBe(9);
|
||||
});
|
||||
|
||||
it('RealOlapExportLayout should render action button', () => {
|
||||
const wrapper = mount(RealOlapExportLayout);
|
||||
|
||||
// 엑셀 보고서 출력 버튼이 정상적으로 노출되는지 검증
|
||||
expect(wrapper.find('button').text()).toContain('엑셀 보고서 출력');
|
||||
expect(wrapper.text()).toContain('다차원 팩터 출력 리포트');
|
||||
});
|
||||
});
|
||||
@@ -1,9 +1,16 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
plugins: [vue() as any],
|
||||
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
globals: true
|
||||
},
|
||||
server: {
|
||||
port: 5173,
|
||||
proxy: {
|
||||
@@ -15,3 +22,4 @@ export default defineConfig({
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user