resolver = new PrefixResolver; } // ───────────────────────────────────────────────── // 가이드레일 벽면형(Wall) Prefix // ───────────────────────────────────────────────── /** * @dataProvider wallFinishProvider */ public function test_wall_finish_prefix(string $productCode, string $expected): void { $this->assertEquals( $expected, $this->resolver->resolveGuideRailPrefix('finish', 'wall', $productCode) ); } public static function wallFinishProvider(): array { return [ 'KSS01 → RS' => ['KSS01', 'RS'], 'KQTS01 → RS' => ['KQTS01', 'RS'], 'KSE01 → RE' => ['KSE01', 'RE'], 'KWE01 → RE' => ['KWE01', 'RE'], 'KTE01 → RS' => ['KTE01', 'RS'], ]; } public function test_wall_body_prefix(): void { $this->assertEquals('RM', $this->resolver->resolveGuideRailPrefix('body', 'wall', 'KSS01')); $this->assertEquals('RM', $this->resolver->resolveGuideRailPrefix('body', 'wall', 'KSE01')); $this->assertEquals('RM', $this->resolver->resolveGuideRailPrefix('body', 'wall', 'KWE01')); } public function test_wall_body_steel_override(): void { $this->assertEquals('RT', $this->resolver->resolveGuideRailPrefix('body', 'wall', 'KTE01')); } public function test_wall_fixed_prefixes(): void { foreach (['KSS01', 'KSE01', 'KWE01', 'KTE01', 'KQTS01'] as $code) { $this->assertEquals('RC', $this->resolver->resolveGuideRailPrefix('c_type', 'wall', $code)); $this->assertEquals('RD', $this->resolver->resolveGuideRailPrefix('d_type', 'wall', $code)); $this->assertEquals('YY', $this->resolver->resolveGuideRailPrefix('extra_finish', 'wall', $code)); $this->assertEquals('XX', $this->resolver->resolveGuideRailPrefix('base', 'wall', $code)); } } // ───────────────────────────────────────────────── // 가이드레일 측면형(Side) Prefix // ───────────────────────────────────────────────── /** * @dataProvider sideFinishProvider */ public function test_side_finish_prefix(string $productCode, string $expected): void { $this->assertEquals( $expected, $this->resolver->resolveGuideRailPrefix('finish', 'side', $productCode) ); } public static function sideFinishProvider(): array { return [ 'KSS01 → SS' => ['KSS01', 'SS'], 'KQTS01 → SS' => ['KQTS01', 'SS'], 'KSE01 → SE' => ['KSE01', 'SE'], 'KWE01 → SE' => ['KWE01', 'SE'], 'KTE01 → SS' => ['KTE01', 'SS'], ]; } public function test_side_body_prefix(): void { $this->assertEquals('SM', $this->resolver->resolveGuideRailPrefix('body', 'side', 'KSS01')); $this->assertEquals('SM', $this->resolver->resolveGuideRailPrefix('body', 'side', 'KSE01')); } public function test_side_body_steel_override(): void { $this->assertEquals('ST', $this->resolver->resolveGuideRailPrefix('body', 'side', 'KTE01')); } public function test_side_fixed_prefixes(): void { foreach (['KSS01', 'KSE01', 'KWE01', 'KTE01', 'KQTS01'] as $code) { $this->assertEquals('SC', $this->resolver->resolveGuideRailPrefix('c_type', 'side', $code)); $this->assertEquals('SD', $this->resolver->resolveGuideRailPrefix('d_type', 'side', $code)); $this->assertEquals('YY', $this->resolver->resolveGuideRailPrefix('extra_finish', 'side', $code)); $this->assertEquals('XX', $this->resolver->resolveGuideRailPrefix('base', 'side', $code)); } } // ───────────────────────────────────────────────── // 하단마감재 Prefix // ───────────────────────────────────────────────── public function test_bottom_bar_main_prefix(): void { // EGI 제품 $this->assertEquals('BE', $this->resolver->resolveBottomBarPrefix('main', 'KSE01', 'EGI마감')); $this->assertEquals('BE', $this->resolver->resolveBottomBarPrefix('main', 'KWE01', 'EGI마감')); // SUS 제품 $this->assertEquals('BS', $this->resolver->resolveBottomBarPrefix('main', 'KSS01', 'SUS마감')); $this->assertEquals('BS', $this->resolver->resolveBottomBarPrefix('main', 'KQTS01', 'SUS마감')); // 철재 $this->assertEquals('TS', $this->resolver->resolveBottomBarPrefix('main', 'KTE01', 'EGI마감')); } public function test_bottom_bar_fixed_prefixes(): void { foreach (['KSS01', 'KSE01', 'KWE01', 'KTE01'] as $code) { $this->assertEquals('LA', $this->resolver->resolveBottomBarPrefix('lbar', $code, 'EGI마감')); $this->assertEquals('HH', $this->resolver->resolveBottomBarPrefix('reinforce', $code, 'EGI마감')); $this->assertEquals('YY', $this->resolver->resolveBottomBarPrefix('extra', $code, 'SUS마감')); } } // ───────────────────────────────────────────────── // 셔터박스 Prefix // ───────────────────────────────────────────────── public function test_shutter_box_standard_prefixes(): void { $this->assertEquals('CF', $this->resolver->resolveShutterBoxPrefix('front', true)); $this->assertEquals('CL', $this->resolver->resolveShutterBoxPrefix('lintel', true)); $this->assertEquals('CP', $this->resolver->resolveShutterBoxPrefix('inspection', true)); $this->assertEquals('CB', $this->resolver->resolveShutterBoxPrefix('rear_corner', true)); $this->assertEquals('XX', $this->resolver->resolveShutterBoxPrefix('top_cover', true)); $this->assertEquals('XX', $this->resolver->resolveShutterBoxPrefix('fin_cover', true)); } public function test_shutter_box_nonstandard_all_xx(): void { foreach (['front', 'lintel', 'inspection', 'rear_corner', 'top_cover', 'fin_cover'] as $part) { $this->assertEquals('XX', $this->resolver->resolveShutterBoxPrefix($part, false)); } } // ───────────────────────────────────────────────── // 연기차단재 Prefix // ───────────────────────────────────────────────── public function test_smoke_barrier_always_gi(): void { $this->assertEquals('GI', $this->resolver->resolveSmokeBarrierPrefix()); } // ───────────────────────────────────────────────── // lengthToCode 변환 // ───────────────────────────────────────────────── /** * @dataProvider lengthCodeProvider */ public function test_length_to_code(int $lengthMm, ?string $smokeCategory, ?string $expected): void { $this->assertSame($expected, PrefixResolver::lengthToCode($lengthMm, $smokeCategory)); } public static function lengthCodeProvider(): array { return [ '1219 → 12' => [1219, null, '12'], '2438 → 24' => [2438, null, '24'], '3000 → 30' => [3000, null, '30'], '3500 → 35' => [3500, null, '35'], '4000 → 40' => [4000, null, '40'], '4150 → 41' => [4150, null, '41'], '4200 → 42' => [4200, null, '42'], '4300 → 43' => [4300, null, '43'], 'smoke w50 3000 → 53' => [3000, 'w50', '53'], 'smoke w50 4000 → 54' => [4000, 'w50', '54'], 'smoke w80 3000 → 83' => [3000, 'w80', '83'], 'smoke w80 4000 → 84' => [4000, 'w80', '84'], 'unknown length → null' => [9999, null, null], ]; } // ───────────────────────────────────────────────── // buildItemCode // ───────────────────────────────────────────────── public function test_build_item_code(): void { $this->assertEquals('BD-RS-43', $this->resolver->buildItemCode('RS', 4300)); $this->assertEquals('BD-RM-30', $this->resolver->buildItemCode('RM', 3000)); $this->assertEquals('BD-GI-53', $this->resolver->buildItemCode('GI', 3000, 'w50')); $this->assertEquals('BD-GI-84', $this->resolver->buildItemCode('GI', 4000, 'w80')); } public function test_build_item_code_invalid_length_returns_null(): void { $this->assertNull($this->resolver->buildItemCode('RS', 9999)); } // ───────────────────────────────────────────────── // partTypeName // ───────────────────────────────────────────────── public function test_part_type_name(): void { $this->assertEquals('마감재', PrefixResolver::partTypeName('finish')); $this->assertEquals('본체', PrefixResolver::partTypeName('body')); $this->assertEquals('C형', PrefixResolver::partTypeName('c_type')); $this->assertEquals('D형', PrefixResolver::partTypeName('d_type')); $this->assertEquals('별도마감', PrefixResolver::partTypeName('extra_finish')); $this->assertEquals('하부BASE', PrefixResolver::partTypeName('base')); $this->assertEquals('L-Bar', PrefixResolver::partTypeName('lbar')); $this->assertEquals('보강평철', PrefixResolver::partTypeName('reinforce')); $this->assertEquals('전면부', PrefixResolver::partTypeName('front')); $this->assertEquals('unknown_type', PrefixResolver::partTypeName('unknown_type')); } // ───────────────────────────────────────────────── // 전체 조합 커버리지 (productCode × guideType × partType) // ───────────────────────────────────────────────── public function test_all_product_code_guide_type_combinations_produce_non_empty_prefix(): void { $productCodes = ['KSS01', 'KSE01', 'KWE01', 'KTE01', 'KQTS01']; $guideTypes = ['wall', 'side']; $partTypes = ['finish', 'body', 'c_type', 'd_type', 'base']; foreach ($productCodes as $code) { foreach ($guideTypes as $guide) { foreach ($partTypes as $part) { $prefix = $this->resolver->resolveGuideRailPrefix($part, $guide, $code); $this->assertNotEmpty( $prefix, "Empty prefix for {$code}/{$guide}/{$part}" ); $this->assertMatchesRegularExpression( '/^[A-Z]{2}$/', $prefix, "Invalid prefix '{$prefix}' for {$code}/{$guide}/{$part}" ); } } } } }