import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/generators/model_code_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 = const SwaggerDocument( title: 'Simple Test API', version: '1.0.0', description: 'A simple test API', servers: [ ApiServer( url: 'https://api.example.com', description: 'Test server', ), ], 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: {}, ); }); 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(splitByTags: false); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('import')); expect(result, contains('dio')); expect(result, contains('retrofit')); }); test('generates path annotations', () { final generator = RetrofitApiGenerator(splitByTags: false); 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(splitByTags: false); final result = generator.generateFromDocument(simpleDocument); expect(result, contains('@Path')); expect(result, contains('id')); }); test('handles split by tags', () { final generator = RetrofitApiGenerator( ); final result = generator.generateFromDocument(simpleDocument); expect(result, isNotEmpty); // Should generate modular structure when split by tags }); }); group('Code Quality Tests', () { test('generated code has proper structure', () { final generator = RetrofitApiGenerator(splitByTags: false); 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', () { const emptyDocument = SwaggerDocument( title: 'Empty API', version: '1.0.0', description: 'Empty API', paths: {}, models: {}, controllers: {}, ); final generator = RetrofitApiGenerator(splitByTags: false); final result = generator.generateFromDocument(emptyDocument); expect(result, isNotEmpty); }); test('handles special characters in API names', () { const specialDocument = SwaggerDocument( title: 'API-with_Special.Characters', version: '1.0.0', description: 'Test', 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: {}, ); final generator = RetrofitApiGenerator(splitByTags: false); expect(() => generator.generateFromDocument(specialDocument), returnsNormally,); }); test('handles nullable parameters correctly', () { const documentWithOptionalParams = SwaggerDocument( title: 'Test API', version: '1.0.0', description: 'Test', 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: {}, ); final generator = RetrofitApiGenerator(splitByTags: false); 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 (var 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': const ApiResponse( code: '200', description: 'Success', ), }, ); } final largeDocument = SwaggerDocument( title: 'Large API', version: '1.0.0', description: 'Large API', servers: [], paths: paths, models: {}, controllers: {}, security: [], ); final generator = RetrofitApiGenerator(splitByTags: false); 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 }); }); group('ModelCodeGenerator Tests', () { test('generates Freezed model structure', () { final generator = ModelCodeGenerator(simpleDocument); final result = generator.generateSingleModelFile(simpleDocument.models['User']!); expect(result, contains('@freezed')); expect(result, contains("part 'user.freezed.dart';")); expect(result, contains("part 'user.g.dart';")); expect(result, contains('const factory User({')); expect(result, contains('factory User.fromJson(Map json)'),); }); }); }); }