339 lines
10 KiB
Dart
339 lines
10 KiB
Dart
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 = <String, ApiPath>{};
|
|
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<String, dynamic> json)'),);
|
|
});
|
|
});
|
|
});
|
|
}
|