import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/generators/optimized_retrofit_generator.dart'; import 'package:swagger_generator_flutter/generators/retrofit_api_generator.dart'; import 'package:test/test.dart'; void main() { group('Simple Generator Tests', () { late SwaggerDocument simpleDocument; setUp(() { simpleDocument = SwaggerDocument( title: 'Simple Test API', version: '1.0.0', description: 'A simple test API', servers: [ ApiServer( url: 'https://api.example.com', description: 'Test server', ), ], components: ApiComponents( schemas: {}, securitySchemes: {}, ), paths: { '/users': ApiPath( path: '/users', method: HttpMethod.get, summary: 'Get users', description: 'Get all users', operationId: 'getUsers', tags: ['users'], parameters: [], responses: { '200': ApiResponse( code: '200', description: 'Success', content: { 'application/json': ApiMediaType( schema: {'type': 'array'}, ), }, ), }, ), '/users/{id}': ApiPath( path: '/users/{id}', method: HttpMethod.get, summary: 'Get user by ID', description: 'Get a specific user', operationId: 'getUserById', tags: ['users'], parameters: [ ApiParameter( name: 'id', location: ParameterLocation.path, required: true, type: PropertyType.integer, description: 'User ID', ), ], responses: { '200': ApiResponse( code: '200', description: 'User found', content: { 'application/json': ApiMediaType( schema: {'type': 'object'}, ), }, ), }, ), }, models: { 'User': ApiModel( name: 'User', description: 'User model', properties: { 'id': ApiProperty( name: 'id', type: PropertyType.integer, description: 'User ID', required: true, ), 'name': ApiProperty( name: 'name', type: PropertyType.string, description: 'User name', required: true, ), }, required: ['id', 'name'], ), }, controllers: {}, security: [], ); }); group('RetrofitApiGenerator Basic Tests', () { test('generates basic API structure', () { final generator = RetrofitApiGenerator( className: 'TestApi', splitByTags: false, ); final result = generator.generateFromDocument(simpleDocument); expect(result, isNotEmpty); expect(result, contains('Simple Test API')); expect(result, contains('TestApi')); }); test('generates imports correctly', () { final generator = RetrofitApiGenerator(); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('import')); expect(result, contains('dio')); expect(result, contains('retrofit')); }); test('generates path annotations', () { final generator = RetrofitApiGenerator(); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('@GET')); expect(result, contains('/users')); expect(result, contains('/users/{id}')); }); test('generates parameter annotations', () { final generator = RetrofitApiGenerator(); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('@Path')); expect(result, contains('id')); }); test('handles split by tags', () { final generator = RetrofitApiGenerator( splitByTags: true, ); final result = generator.generateFromDocument(simpleDocument); expect(result, isNotEmpty); // Should generate modular structure when split by tags }); }); group('OptimizedRetrofitGenerator Tests', () { test('generates optimized code structure', () { final generator = OptimizedRetrofitGenerator( className: 'OptimizedApi', generateModularApis: false, generateBaseResult: true, ); final result = generator.generateFromDocument(simpleDocument); expect(result, isNotEmpty); expect(result, contains('Simple Test API')); expect(result, contains('BaseResult')); }); test('generates base result types', () { final generator = OptimizedRetrofitGenerator( generateBaseResult: true, ); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('class BaseResult')); expect(result, contains('final int code')); expect(result, contains('final String message')); expect(result, contains('bool get isSuccess')); }); test('generates pagination types', () { final generator = OptimizedRetrofitGenerator( generatePagination: true, ); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('BasePageParameter')); expect(result, contains('BasePageResult')); expect(result, contains('final int page')); expect(result, contains('final int size')); }); test('generates file upload types', () { final generator = OptimizedRetrofitGenerator( generateFileUpload: true, ); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('FileUploadRequest')); expect(result, contains('FileUploadResult')); expect(result, contains('MultipartFile')); }); test('generates utility classes', () { final generator = OptimizedRetrofitGenerator( generateFileUpload: true, generatePagination: true, ); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('class ApiUtils')); expect(result, contains('createFileUpload')); expect(result, contains('createPageParam')); }); test('generates modular APIs when enabled', () { final generator = OptimizedRetrofitGenerator( generateModularApis: true, ); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('UsersApi')); expect(result, contains('class ApiService')); expect(result, contains('late final UsersApi')); }); test('generates single API when modular disabled', () { final generator = OptimizedRetrofitGenerator( generateModularApis: false, className: 'SingleApi', ); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('abstract class SingleApi')); expect(result, isNot(contains('UsersApi'))); }); }); group('Code Quality Tests', () { test('generated code has proper structure', () { final generator = RetrofitApiGenerator(); final result = generator.generateFromDocument(simpleDocument); // Check for basic Dart syntax expect(result, isNot(contains(';;'))); // No double semicolons expect(result, isNot(contains(',,'))); // No double commas // Check for proper class declarations final classCount = 'class '.allMatches(result).length; final abstractClassCount = 'abstract class '.allMatches(result).length; expect(classCount + abstractClassCount, greaterThan(0)); }); test('handles empty paths gracefully', () { final emptyDocument = SwaggerDocument( title: 'Empty API', version: '1.0.0', description: 'Empty API', servers: [], components: ApiComponents(schemas: {}, securitySchemes: {}), paths: {}, models: {}, controllers: {}, security: [], ); final generator = RetrofitApiGenerator(); final result = generator.generateFromDocument(emptyDocument); expect(result, isNotEmpty); expect(result, contains('Empty API')); }); test('handles special characters in API names', () { final specialDocument = SwaggerDocument( title: 'API-with_Special.Characters', version: '1.0.0', description: 'Test', servers: [], components: ApiComponents(schemas: {}, securitySchemes: {}), paths: { '/special-endpoint': ApiPath( path: '/special-endpoint', method: HttpMethod.get, summary: 'Special endpoint', description: 'Test', operationId: 'getSpecial', tags: ['special'], parameters: [], responses: { '200': ApiResponse( code: '200', description: 'Success', ), }, ), }, models: {}, controllers: {}, security: [], ); final generator = RetrofitApiGenerator(); expect(() => generator.generateFromDocument(specialDocument), returnsNormally); }); test('generates valid JSON annotations', () { final generator = OptimizedRetrofitGenerator( generateBaseResult: true, ); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('@JsonSerializable')); expect(result, contains('fromJson')); expect(result, contains('toJson')); }); test('handles nullable parameters correctly', () { final documentWithOptionalParams = SwaggerDocument( title: 'Test API', version: '1.0.0', description: 'Test', servers: [], components: ApiComponents(schemas: {}, securitySchemes: {}), paths: { '/search': ApiPath( path: '/search', method: HttpMethod.get, summary: 'Search', description: 'Search endpoint', operationId: 'search', tags: ['search'], parameters: [ ApiParameter( name: 'query', location: ParameterLocation.query, required: true, type: PropertyType.string, description: 'Search query', ), ApiParameter( name: 'page', location: ParameterLocation.query, required: false, type: PropertyType.integer, description: 'Page number', ), ], responses: { '200': ApiResponse( code: '200', description: 'Success', ), }, ), }, models: {}, controllers: {}, security: [], ); final generator = RetrofitApiGenerator(); final result = generator.generateFromDocument(documentWithOptionalParams); // Required parameters should not be nullable expect(result, contains('String query')); // Optional parameters should be nullable expect(result, contains('int? page')); }); }); group('Performance Tests', () { test('handles medium-sized documents efficiently', () { // Create a document with multiple paths final paths = {}; for (int i = 0; i < 50; i++) { paths['/resource$i'] = ApiPath( path: '/resource$i', method: HttpMethod.get, summary: 'Get resource $i', description: 'Get resource $i', operationId: 'getResource$i', tags: ['resources'], parameters: [], responses: { '200': ApiResponse( code: '200', description: 'Success', ), }, ); } final largeDocument = SwaggerDocument( title: 'Large API', version: '1.0.0', description: 'Large API', servers: [], components: ApiComponents(schemas: {}, securitySchemes: {}), paths: paths, models: {}, controllers: {}, security: [], ); final generator = RetrofitApiGenerator(); final stopwatch = Stopwatch()..start(); final result = generator.generateFromDocument(largeDocument); stopwatch.stop(); expect(result, isNotEmpty); expect(stopwatch.elapsedMilliseconds, lessThan(5000)); // Should complete within 5 seconds expect(result.length, greaterThan(1000)); // Should generate substantial code }); test('memory usage is reasonable', () { final generator = RetrofitApiGenerator(); final result = generator.generateFromDocument(simpleDocument); // Basic memory usage check - result should not be excessively large expect(result.length, lessThan(100000)); // Less than 100KB for simple document }); }); }); }