Compare commits
7 Commits
2ce35a396e
...
be0e15178f
| Author | SHA1 | Date |
|---|---|---|
|
|
be0e15178f | |
|
|
6a4a31b39b | |
|
|
cae78c5fe7 | |
|
|
1231af9f0b | |
|
|
0b20ad6ab5 | |
|
|
ceb91a0ea3 | |
|
|
a4e7a7453e |
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [3.2.0] - 2026-01-12
|
||||||
|
|
||||||
|
### 🎉 新特性
|
||||||
|
|
||||||
|
#### 模型类名前缀支持
|
||||||
|
- ✅ **支持配置文件配置**:在 `generator_config.yaml` 中配置 `models.class_prefix`,自动为生成的模型类添加前缀。
|
||||||
|
- ✅ **性能优化**:为 `ConfigRepository` 添加缓存机制,减少磁盘 I/O。
|
||||||
## [3.1.0] - 2025-11-24
|
## [3.1.0] - 2025-11-24
|
||||||
|
|
||||||
### 🎉 新特性
|
### 🎉 新特性
|
||||||
|
|
|
||||||
|
|
@ -558,7 +558,7 @@ packages:
|
||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "3.1.0"
|
version: "3.1.4"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,14 @@ class SwaggerConfig {
|
||||||
static Map<String, Map<dynamic, EnumKeyMapping>>? get enumKeyMappings =>
|
static Map<String, Map<dynamic, EnumKeyMapping>>? get enumKeyMappings =>
|
||||||
ConfigRepository.loadSync().enumKeyMappings;
|
ConfigRepository.loadSync().enumKeyMappings;
|
||||||
|
|
||||||
|
/// 获取 JsonSerializable 配置(从配置文件读取)
|
||||||
|
static JsonSerializableConfig? get jsonSerializableConfig =>
|
||||||
|
ConfigRepository.loadSync().jsonSerializableConfig;
|
||||||
|
|
||||||
|
/// 获取模型类名前缀(从配置文件读取)
|
||||||
|
static String? get modelClassPrefix =>
|
||||||
|
ConfigRepository.loadSync().modelClassPrefix;
|
||||||
|
|
||||||
/// 默认文档文件名
|
/// 默认文档文件名
|
||||||
static const String defaultDocumentationFile =
|
static const String defaultDocumentationFile =
|
||||||
'generated_api_documentation.md';
|
'generated_api_documentation.md';
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,28 @@ class EnumKeyMapping {
|
||||||
final String? description;
|
final String? description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// JSON Serializable 配置
|
||||||
|
class JsonSerializableConfig {
|
||||||
|
const JsonSerializableConfig({
|
||||||
|
this.checked = false,
|
||||||
|
this.explicitToJson = false,
|
||||||
|
this.includeIfNull = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool checked;
|
||||||
|
final bool explicitToJson;
|
||||||
|
final bool includeIfNull;
|
||||||
|
|
||||||
|
static JsonSerializableConfig? fromMap(Map<String, dynamic>? map) {
|
||||||
|
if (map == null) return null;
|
||||||
|
return JsonSerializableConfig(
|
||||||
|
checked: map['checked'] as bool? ?? false,
|
||||||
|
explicitToJson: map['explicit_to_json'] as bool? ?? false,
|
||||||
|
includeIfNull: map['include_if_null'] as bool? ?? true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 配置仓库
|
/// 配置仓库
|
||||||
/// 负责加载和提供配置信息
|
/// 负责加载和提供配置信息
|
||||||
class ConfigRepository {
|
class ConfigRepository {
|
||||||
|
|
@ -42,8 +64,16 @@ class ConfigRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ConfigRepository? _cachedConfig;
|
||||||
|
|
||||||
/// 同步加载配置(用于向后兼容或必须同步的场景)
|
/// 同步加载配置(用于向后兼容或必须同步的场景)
|
||||||
|
/// 为默认配置路径启用缓存
|
||||||
static ConfigRepository loadSync([String? configPath]) {
|
static ConfigRepository loadSync([String? configPath]) {
|
||||||
|
// 仅在使用默认路径时使用缓存
|
||||||
|
if (configPath == null && _cachedConfig != null) {
|
||||||
|
return _cachedConfig!;
|
||||||
|
}
|
||||||
|
|
||||||
final file = File(configPath ?? PathResolver.findConfigFile() ?? '');
|
final file = File(configPath ?? PathResolver.findConfigFile() ?? '');
|
||||||
if (!file.existsSync()) {
|
if (!file.existsSync()) {
|
||||||
return ConfigRepository({});
|
return ConfigRepository({});
|
||||||
|
|
@ -53,7 +83,12 @@ class ConfigRepository {
|
||||||
final content = file.readAsStringSync();
|
final content = file.readAsStringSync();
|
||||||
final yaml = loadYaml(content);
|
final yaml = loadYaml(content);
|
||||||
final map = _yamlToMap(yaml);
|
final map = _yamlToMap(yaml);
|
||||||
return ConfigRepository(map);
|
final config = ConfigRepository(map);
|
||||||
|
|
||||||
|
if (configPath == null) {
|
||||||
|
_cachedConfig = config;
|
||||||
|
}
|
||||||
|
return config;
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
appLogger.warning('⚠️ 配置文件解析失败: $e');
|
appLogger.warning('⚠️ 配置文件解析失败: $e');
|
||||||
return ConfigRepository({});
|
return ConfigRepository({});
|
||||||
|
|
@ -292,6 +327,22 @@ class ConfigRepository {
|
||||||
return api?['base_page_result_import'] as String? ?? '';
|
return api?['base_page_result_import'] as String? ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 获取 JsonSerializable 配置
|
||||||
|
JsonSerializableConfig? get jsonSerializableConfig {
|
||||||
|
final generation = _config['generation'] as Map<String, dynamic>?;
|
||||||
|
final models = generation?['models'] as Map<String, dynamic>?;
|
||||||
|
final jsonSerializable =
|
||||||
|
models?['json_serializable'] as Map<String, dynamic>?;
|
||||||
|
return JsonSerializableConfig.fromMap(jsonSerializable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取模型类名前缀
|
||||||
|
String? get modelClassPrefix {
|
||||||
|
final generation = _config['generation'] as Map<String, dynamic>?;
|
||||||
|
final models = generation?['models'] as Map<String, dynamic>?;
|
||||||
|
return models?['class_prefix'] as String?;
|
||||||
|
}
|
||||||
|
|
||||||
/// 获取枚举键名映射配置
|
/// 获取枚举键名映射配置
|
||||||
/// 返回格式: { "EnumName": { value: { "name": "KEY_NAME", "description": "描述" } } }
|
/// 返回格式: { "EnumName": { value: { "name": "KEY_NAME", "description": "描述" } } }
|
||||||
Map<String, Map<dynamic, EnumKeyMapping>>? get enumKeyMappings {
|
Map<String, Map<dynamic, EnumKeyMapping>>? get enumKeyMappings {
|
||||||
|
|
|
||||||
|
|
@ -127,10 +127,29 @@ String _generateAnnotatedModelCodeWithoutImports(
|
||||||
buffer.writeln(StringHelper.generateComment(model.description));
|
buffer.writeln(StringHelper.generateComment(model.description));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build @JsonSerializable annotation string for factory constructor
|
||||||
|
String? jsonSerializableAnnotation;
|
||||||
|
final jsonConfig = SwaggerConfig.jsonSerializableConfig;
|
||||||
|
if (jsonConfig != null) {
|
||||||
|
final params = <String>[];
|
||||||
|
if (jsonConfig.checked) params.add('checked: true');
|
||||||
|
if (jsonConfig.explicitToJson) params.add('explicitToJson: true');
|
||||||
|
if (!jsonConfig.includeIfNull) params.add('includeIfNull: false');
|
||||||
|
|
||||||
|
if (params.isNotEmpty) {
|
||||||
|
jsonSerializableAnnotation = '@JsonSerializable(${params.join(', ')})';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buffer
|
buffer
|
||||||
..writeln('@freezed')
|
..writeln('@freezed')
|
||||||
..writeln('abstract class $className with _\$$className {')
|
..writeln('abstract class $className with _\$$className {');
|
||||||
..writeln(' const factory $className({');
|
|
||||||
|
// Add @JsonSerializable annotation on factory constructor if configured
|
||||||
|
if (jsonSerializableAnnotation != null) {
|
||||||
|
buffer.writeln(' $jsonSerializableAnnotation');
|
||||||
|
}
|
||||||
|
buffer.writeln(' const factory $className({');
|
||||||
|
|
||||||
model.properties.forEach((propName, property) {
|
model.properties.forEach((propName, property) {
|
||||||
final dartType = generator.getDartPropertyType(property);
|
final dartType = generator.getDartPropertyType(property);
|
||||||
|
|
|
||||||
|
|
@ -44,18 +44,16 @@ String buildSingleModelFile(
|
||||||
..writeln();
|
..writeln();
|
||||||
|
|
||||||
if (!model.isEnum) {
|
if (!model.isEnum) {
|
||||||
buffer
|
buffer.writeln(
|
||||||
..writeln(
|
|
||||||
"import 'package:freezed_annotation/freezed_annotation.dart';",
|
"import 'package:freezed_annotation/freezed_annotation.dart';",
|
||||||
)
|
);
|
||||||
..writeln();
|
}
|
||||||
} else {
|
|
||||||
buffer
|
buffer
|
||||||
..writeln(
|
..writeln(
|
||||||
"import 'package:json_annotation/json_annotation.dart';",
|
"import 'package:json_annotation/json_annotation.dart';",
|
||||||
)
|
)
|
||||||
..writeln();
|
..writeln();
|
||||||
}
|
|
||||||
|
|
||||||
final importedTypes = generator.getImportedTypes(model);
|
final importedTypes = generator.getImportedTypes(model);
|
||||||
if (importedTypes.isNotEmpty) {
|
if (importedTypes.isNotEmpty) {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ mixin RetrofitApiParameters {
|
||||||
parameters.add(
|
parameters.add(
|
||||||
ApiMethodParameter(
|
ApiMethodParameter(
|
||||||
name: StringHelper.toDartPropertyName(param.name),
|
name: StringHelper.toDartPropertyName(param.name),
|
||||||
type: _getDartType(param.type),
|
type: _getDartTypeForParameter(param),
|
||||||
annotation: _g.useRetrofit ? "@Path('${param.name}')" : '',
|
annotation: _g.useRetrofit ? "@Path('${param.name}')" : '',
|
||||||
required: param.required,
|
required: param.required,
|
||||||
description: param.description,
|
description: param.description,
|
||||||
|
|
@ -47,7 +47,7 @@ mixin RetrofitApiParameters {
|
||||||
parameters.add(
|
parameters.add(
|
||||||
ApiMethodParameter(
|
ApiMethodParameter(
|
||||||
name: StringHelper.toDartPropertyName(param.name),
|
name: StringHelper.toDartPropertyName(param.name),
|
||||||
type: '${_getDartType(param.type)}$nullable',
|
type: '${_getDartTypeForParameter(param)}$nullable',
|
||||||
annotation: _g.useRetrofit ? "@Query('${param.name}')" : '',
|
annotation: _g.useRetrofit ? "@Query('${param.name}')" : '',
|
||||||
required: param.required,
|
required: param.required,
|
||||||
description: param.description,
|
description: param.description,
|
||||||
|
|
|
||||||
|
|
@ -87,9 +87,27 @@ class TemplateLoader {
|
||||||
final dirs = <String>[];
|
final dirs = <String>[];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 尝试从 .dart_tool/package_config.json 解析包路径
|
// 递归向上查找 .dart_tool/package_config.json
|
||||||
final packageConfigFile = File('.dart_tool/package_config.json');
|
File? packageConfigFile;
|
||||||
if (!packageConfigFile.existsSync()) {
|
var currentDir = Directory.current;
|
||||||
|
const maxDepth = 6; // 增加搜索深度以支持 monorepo
|
||||||
|
var depth = 0;
|
||||||
|
|
||||||
|
while (depth < maxDepth) {
|
||||||
|
final checkFile =
|
||||||
|
File(p.join(currentDir.path, '.dart_tool', 'package_config.json'));
|
||||||
|
if (checkFile.existsSync()) {
|
||||||
|
packageConfigFile = checkFile;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
final parent = currentDir.parent;
|
||||||
|
if (parent.path == currentDir.path) break;
|
||||||
|
currentDir = parent;
|
||||||
|
depth++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packageConfigFile == null) {
|
||||||
return dirs;
|
return dirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +121,7 @@ class TemplateLoader {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (package != null) {
|
if (package != null) {
|
||||||
final rootUri = package['rootUri'] as String;
|
var rootUri = package['rootUri'] as String;
|
||||||
String packagePath;
|
String packagePath;
|
||||||
|
|
||||||
// 处理 file:// 协议
|
// 处理 file:// 协议
|
||||||
|
|
@ -117,18 +135,27 @@ class TemplateLoader {
|
||||||
|
|
||||||
// 如果不是绝对路径,需要相对于 .dart_tool/package_config.json 所在目录解析
|
// 如果不是绝对路径,需要相对于 .dart_tool/package_config.json 所在目录解析
|
||||||
if (!p.isAbsolute(packagePath)) {
|
if (!p.isAbsolute(packagePath)) {
|
||||||
// package_config.json 在 .dart_tool 目录下
|
// package_config.json 在 packageConfigFile.parent 目录下 (.dart_tool)
|
||||||
packagePath = p.normalize(p.join('.dart_tool', packagePath));
|
packagePath =
|
||||||
|
p.normalize(p.join(packageConfigFile.parent.path, packagePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加模板目录路径
|
// 添加模板目录路径
|
||||||
final templateDir = p.join(packagePath, 'lib', 'templates');
|
// 1. 尝试 lib/templates (标准包结构)
|
||||||
|
var templateDir = p.join(packagePath, 'lib', 'templates');
|
||||||
|
if (Directory(templateDir).existsSync()) {
|
||||||
|
dirs.add(templateDir);
|
||||||
|
} else {
|
||||||
|
// 2. 尝试 templates (本地调试或非标准结构)
|
||||||
|
templateDir = p.join(packagePath, 'templates');
|
||||||
if (Directory(templateDir).existsSync()) {
|
if (Directory(templateDir).existsSync()) {
|
||||||
dirs.add(templateDir);
|
dirs.add(templateDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (_) {
|
}
|
||||||
|
} catch (e) {
|
||||||
// 忽略错误,返回空列表
|
// 忽略错误,返回空列表
|
||||||
|
print('Warning: Failed to load package templates: $e');
|
||||||
}
|
}
|
||||||
|
|
||||||
return dirs;
|
return dirs;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
///
|
///
|
||||||
library;
|
library;
|
||||||
|
|
||||||
|
import 'package:swagger_generator_flutter/core/config.dart';
|
||||||
import 'package:swagger_generator_flutter/core/models.dart';
|
import 'package:swagger_generator_flutter/core/models.dart';
|
||||||
import 'package:swagger_generator_flutter/utils/string_utils/formatting_utils.dart';
|
import 'package:swagger_generator_flutter/utils/string_utils/formatting_utils.dart';
|
||||||
import 'package:swagger_generator_flutter/utils/string_utils/naming_converter.dart';
|
import 'package:swagger_generator_flutter/utils/string_utils/naming_converter.dart';
|
||||||
|
|
@ -47,8 +48,16 @@ class StringHelper {
|
||||||
NamingConverter.toDartPropertyName(propName);
|
NamingConverter.toDartPropertyName(propName);
|
||||||
|
|
||||||
/// 生成 Dart 类名
|
/// 生成 Dart 类名
|
||||||
static String generateClassName(String name) =>
|
static String generateClassName(String name) {
|
||||||
NamingConverter.generateClassName(name);
|
var className = NamingConverter.generateClassName(name);
|
||||||
|
final prefix = SwaggerConfig.modelClassPrefix;
|
||||||
|
if (prefix != null && prefix.isNotEmpty) {
|
||||||
|
if (!className.startsWith(prefix)) {
|
||||||
|
className = prefix + className;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
|
||||||
/// 生成常量名称 (UPPER_SNAKE_CASE)
|
/// 生成常量名称 (UPPER_SNAKE_CASE)
|
||||||
static String generateConstantName(String name) =>
|
static String generateConstantName(String name) =>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
name: swagger_generator_flutter
|
name: swagger_generator_flutter
|
||||||
description: A powerful Swagger/OpenAPI code generator for Flutter projects with Dio + Retrofit support
|
description: A powerful Swagger/OpenAPI code generator for Flutter projects with Dio + Retrofit support
|
||||||
|
|
||||||
version: 3.1.4
|
version: 3.2.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.0.0 <4.0.0'
|
sdk: '>=3.0.0 <4.0.0'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:swagger_generator_flutter/core/config.dart';
|
||||||
|
import 'package:swagger_generator_flutter/core/config_repository.dart';
|
||||||
|
import 'package:swagger_generator_flutter/utils/string_helper.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('Model Class Prefix Support', () {
|
||||||
|
late Directory tempDir;
|
||||||
|
late File configFile;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
tempDir = Directory.systemTemp.createTempSync('swagger_gen_test_');
|
||||||
|
configFile = File('${tempDir.path}/generator_config.yaml');
|
||||||
|
});
|
||||||
|
|
||||||
|
tearDown(() {
|
||||||
|
tempDir.deleteSync(recursive: true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should parse class_prefix from config', () {
|
||||||
|
configFile.writeAsStringSync('''
|
||||||
|
generator:
|
||||||
|
name: test
|
||||||
|
|
||||||
|
output:
|
||||||
|
models:
|
||||||
|
class_prefix: "MyPrefix"
|
||||||
|
|
||||||
|
generation:
|
||||||
|
models:
|
||||||
|
class_prefix: "MyPrefix"
|
||||||
|
''');
|
||||||
|
|
||||||
|
final config = ConfigRepository.loadSync(configFile.path);
|
||||||
|
expect(config.modelClassPrefix, equals('MyPrefix'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return null when class_prefix is missing', () {
|
||||||
|
configFile.writeAsStringSync('''
|
||||||
|
generator:
|
||||||
|
name: test
|
||||||
|
''');
|
||||||
|
|
||||||
|
final config = ConfigRepository.loadSync(configFile.path);
|
||||||
|
expect(config.modelClassPrefix, isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
// NOTE: Testing StringHelper.generateClassName directly implies checking if it reads from the GLOBAL config.
|
||||||
|
// However, ConfigRepository.loadSync() creates an instance, but SwaggerConfig accessors call ConfigRepository.loadSync() individually.
|
||||||
|
// Since ConfigRepository.loadSync() without args looks for default file, we need a way to inject the config or point it to our file.
|
||||||
|
// The current implementation of SwaggerConfig calls ConfigRepository.loadSync() which defaults to finding a config file.
|
||||||
|
|
||||||
|
// Changing the implementation of StringHelper to depend on a reloadable config or global state would be better,
|
||||||
|
// but without changing that, we rely on how ConfigRepository finds the file.
|
||||||
|
// Ideally we should test ConfigRepository logic separately from StringHelper if StringHelper uses a static/global config lookup.
|
||||||
|
|
||||||
|
// BUT, wait. ConfigRepository.loadSync() does THIS:
|
||||||
|
// final file = File(configPath ?? PathResolver.findConfigFile() ?? '');
|
||||||
|
|
||||||
|
// If we want SwaggerConfig (static) to pick up our test config, we might need to trick PathResolver
|
||||||
|
// OR we can explicitly pass the config path if the code supported it, but StringHelper uses static SwaggerConfig.modelClassPrefix.
|
||||||
|
|
||||||
|
// The current implementation of `SwaggerConfig.modelClassPrefix` is:
|
||||||
|
// static String? get modelClassPrefix => ConfigRepository.loadSync().modelClassPrefix;
|
||||||
|
|
||||||
|
// So every time we call `StringHelper.generateClassName`, it calls `ConfigRepository.loadSync()`.
|
||||||
|
// `ConfigRepository.loadSync()` calls `PathResolver.findConfigFile()`.
|
||||||
|
|
||||||
|
// Since we cannot easily mock `PathResolver`'s static method or filesystem search path in a unit test without dependency injection,
|
||||||
|
// we might face issues testing `StringHelper` integration end-to-end here unless we run this test in a context where `findConfigFile` returns our temp file.
|
||||||
|
|
||||||
|
// However, for verify purposes, verifying `ConfigRepository` parses it is the most critical part we added.
|
||||||
|
// The `StringHelper` logic is simple string concatenation.
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:swagger_generator_flutter/core/config.dart';
|
||||||
|
import 'package:swagger_generator_flutter/core/config_repository.dart';
|
||||||
|
import 'package:swagger_generator_flutter/utils/string_helper.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
final configFile = File('generator_config.yaml');
|
||||||
|
final resultFile = File('test_result.txt');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. Setup config file
|
||||||
|
configFile.writeAsStringSync('''
|
||||||
|
generator:
|
||||||
|
name: test
|
||||||
|
output:
|
||||||
|
models:
|
||||||
|
class_prefix: "MyPrefix"
|
||||||
|
generation:
|
||||||
|
models:
|
||||||
|
class_prefix: "MyPrefix"
|
||||||
|
''');
|
||||||
|
|
||||||
|
// 2. Test direct ConfigRepository load
|
||||||
|
final config = ConfigRepository.loadSync('generator_config.yaml');
|
||||||
|
if (config.modelClassPrefix != 'MyPrefix') {
|
||||||
|
throw 'ConfigRepository failed to PARSE prefix. Got: ${config.modelClassPrefix}';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Test SwaggerConfig (static access)
|
||||||
|
// Note: ConfigRepository.loadSync() tries to find config file.
|
||||||
|
// Since we created generator_config.yaml in CWD, and PathResolver likely checks CWD, this matches.
|
||||||
|
if (SwaggerConfig.modelClassPrefix != 'MyPrefix') {
|
||||||
|
throw 'SwaggerConfig failed to READ prefix. Got: ${SwaggerConfig.modelClassPrefix}';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Test StringHelper
|
||||||
|
final className = StringHelper.generateClassName('User');
|
||||||
|
if (className != 'MyPrefixUser') {
|
||||||
|
throw 'StringHelper failed to APPLY prefix. Got: $className';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Test Prefix Avoidance (Idempotency)
|
||||||
|
final className2 = StringHelper.generateClassName('MyPrefixUser');
|
||||||
|
if (className2 != 'MyPrefixUser') {
|
||||||
|
throw 'StringHelper double-prefixed. Got: $className2';
|
||||||
|
}
|
||||||
|
|
||||||
|
resultFile.writeAsStringSync('PASS');
|
||||||
|
print('Verification Passed');
|
||||||
|
} catch (e, stack) {
|
||||||
|
resultFile.writeAsStringSync('FAIL: $e\n$stack');
|
||||||
|
print('Verification Failed: $e');
|
||||||
|
} finally {
|
||||||
|
// Cleanup
|
||||||
|
if (configFile.existsSync()) configFile.deleteSync();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue