Skip to content

Commit

Permalink
feature: created the domain layer with test driven development (news …
Browse files Browse the repository at this point in the history
…details feature)
  • Loading branch information
BasakK6 committed Sep 29, 2023
1 parent afe80ce commit 4bdbfec
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 0 deletions.
44 changes: 44 additions & 0 deletions lib/features/news_details/domain/entities/gpt_result_entity.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'package:equatable/equatable.dart';

class GptResultEntity extends Equatable {
final String? id;
final String? object;
final int? created;
final String? model;
final List<ChoicesEntity>? choices;
final UsageEntity? usage;

const GptResultEntity(
{this.id,
this.object,
this.created,
this.model,
this.choices,
this.usage});

@override
List<Object?> get props => [id, object, created, model, choices, usage];
}

class ChoicesEntity extends Equatable {
final String? text;
final int? index;
final String? finishReason;

const ChoicesEntity({this.text, this.index, this.finishReason});

@override
List<Object?> get props => [text, index, finishReason];
}

class UsageEntity extends Equatable {
final int? promptTokens;
final int? completionTokens;
final int? totalTokens;

const UsageEntity(
{this.promptTokens, this.completionTokens, this.totalTokens});

@override
List<Object?> get props => [promptTokens, completionTokens, totalTokens];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'package:dartz/dartz.dart';
import 'package:news_app/core/error/failures.dart';
import 'package:news_app/features/news_details/domain/entities/gpt_result_entity.dart';

abstract class GptResultRepository {
Future<Either<Failure, GptResultEntity>> getGptResult(String articleContent);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'package:dartz/dartz.dart';
import 'package:news_app/core/error/failures.dart';
import 'package:news_app/core/use_cases/use_case.dart';
import 'package:news_app/features/news_details/domain/entities/gpt_result_entity.dart';
import 'package:news_app/features/news_details/domain/repositories/gpt_result_repository.dart';

class GetGptResultForAnArticleContent
implements UseCase<GptResultEntity, Params> {
final GptResultRepository repository;

GetGptResultForAnArticleContent(this.repository);

@override
Future<Either<Failure, GptResultEntity>> call(Params params) {
return repository.getGptResult(params.articleContent);
}
}

class Params {
final String articleContent;

const Params({required this.articleContent});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import 'package:dartz/dartz.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:news_app/features/news_details/domain/entities/gpt_result_entity.dart';
import 'package:news_app/features/news_details/domain/repositories/gpt_result_repository.dart';
import 'package:news_app/features/news_details/domain/use_cases/get_gpt_result_for_an_article_content.dart';

import '../../../../core/fixtures/gpt_api_test_data.dart';
import 'get_gpt_result_for_an_article_content_test.mocks.dart';

@GenerateNiceMocks([MockSpec<GptResultRepository>()])
void main() {
late MockGptResultRepository mockGptResultRepository;
late GetGptResultForAnArticleContent useCase;

setUp(() {
mockGptResultRepository = MockGptResultRepository();
useCase = GetGptResultForAnArticleContent(mockGptResultRepository);
});

const testArticleContent = kTestArticleContent;
const testGptResultEntity = GptResultEntity(
id: "cmpl-844MC2OPs6EFL5kI1FVWcUITzyCJn",
object: "text_completion",
created: 1695980752,
model: "gpt-3.5-turbo-instruct",
choices: [
ChoicesEntity(
text:
"\n\nThe PlayStation Store currently has multiple promotional sales offering discounts on over 2,000 PS4",
index: 0,
finishReason: "length",
),
],
usage: UsageEntity(
promptTokens: 46,
completionTokens: 20,
totalTokens: 66,
),
);

test("should get the gpt result for an article content", () async {
//arrange
when(mockGptResultRepository.getGptResult(any))
.thenAnswer((_) async => const Right(testGptResultEntity));
//act
final result = await useCase.call(
const Params(articleContent: testArticleContent),
);

//assert

// UseCase should simply return whatever was returned from the Repository
expect(result, const Right(testGptResultEntity));
// Verify that the method has been called on the Repository with the given parameter
verify(mockGptResultRepository.getGptResult(testArticleContent));
// Only the above method should be called and nothing more.
verifyNoMoreInteractions(mockGptResultRepository);
});
}

/*
test("should", () {
//arrange
//act
//assert
});
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Mocks generated by Mockito 5.4.2 from annotations
// in news_app/test/features/news_details/domain/use_cases/get_gpt_result_for_an_article_content_test.dart.
// Do not manually edit this file.

// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i4;

import 'package:dartz/dartz.dart' as _i2;
import 'package:mockito/mockito.dart' as _i1;
import 'package:news_app/core/error/failures.dart' as _i5;
import 'package:news_app/features/news_details/domain/entities/gpt_result_entity.dart'
as _i6;
import 'package:news_app/features/news_details/domain/repositories/gpt_result_repository.dart'
as _i3;

// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class

class _FakeEither_0<L, R> extends _i1.SmartFake implements _i2.Either<L, R> {
_FakeEither_0(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}

/// A class which mocks [GptResultRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockGptResultRepository extends _i1.Mock
implements _i3.GptResultRepository {
@override
_i4.Future<_i2.Either<_i5.Failure, _i6.GptResultEntity>> getGptResult(
String? articleContent) =>
(super.noSuchMethod(
Invocation.method(
#getGptResult,
[articleContent],
),
returnValue:
_i4.Future<_i2.Either<_i5.Failure, _i6.GptResultEntity>>.value(
_FakeEither_0<_i5.Failure, _i6.GptResultEntity>(
this,
Invocation.method(
#getGptResult,
[articleContent],
),
)),
returnValueForMissingStub:
_i4.Future<_i2.Either<_i5.Failure, _i6.GptResultEntity>>.value(
_FakeEither_0<_i5.Failure, _i6.GptResultEntity>(
this,
Invocation.method(
#getGptResult,
[articleContent],
),
)),
) as _i4.Future<_i2.Either<_i5.Failure, _i6.GptResultEntity>>);
}

0 comments on commit 4bdbfec

Please sign in to comment.