Skip to content

Instantly share code, notes, and snippets.

View bmelnychuk's full-sized avatar

Bogdan Melnychuk bmelnychuk

  • Hamburg, Germany
View GitHub Profile
const questionGenerationPolicy = new RandomNextQuestionPolicy();
const answerValidationPolicy = new TextEqualityAnswerValidationPolicy();
const questionRepository = new QuestionStoreRepository();
const getNextQuestionUseCase = new GetNextQuestion(
questionRepository, questionGenerationPolicy
);
const answerQuestionUseCase = new AnswerQuestion(
questionRepository, answerValidationPolicy
import { getQuestions, getQuestion } from '../../../question-store';
export default class QuestionStoreRepository implements QuestionRepository {
async getAvailableQuestions(categoryId: string): Promise<Question[]> {
const rawQuestions = await getQuestions(categoryId);
return rawQuestions.map(rawQuestion => new Question(
rawQuestion.id,
rawQuestion.question,
rawQuestion.answer
));
...
export function getQuestions(categoryId: string): Promise<{ id: string, question: string, answer: string}[]>
export function getQuestion(questionId: string): Promise<{ id: string, question: string, answer: string}>
...
class TextEqualityAnswerValidationPolicy implements AnswerValidationPolicy {
isAnswerValid(userAnswer: string, correctAnswer: string): Promise<boolean> {
return Promise.resolve(
userAnswer.trim().toLowerCase() === correctAnswer.toLowerCase()
);
}
}
class RandomNextQuestionPolicy implements NextQuestionPolicy {
async getNextQuestion(availableQuestions: Question[]): Promise<Question> {
if (availableQuestions.length === 0)
throw new Error('Next question is not available');
const nextRandomIndex = RandomNextQuestionPolicy.getRandomInt(
0, availableQuestions.length - 1
);
return Promise.resolve(availableQuestions[nextRandomIndex]);
}
class AnswerResult {
userAnswer: string;
isValid: boolean;
correctAnswer: string;
}
class AnswerQuestion {
questionRepository: QuestionRepository;
answerValidationPolicy: AnswerValidationPolicy;
class GetNextQuestion {
questionRepository: QuestionRepository;
nextQuestionPolicy: NextQuestionPolicy;
async invoke(categoryId: string): Promise<Question> {
const availableQuestions = await this.questionRepository.getAvailableQuestions(
categoryId
);
return this.nextQuestionPolicy.getNextQuestion(availableQuestions);
}
interface QuestionRepository {
getAvailableQuestions(categoryId: string): Promise<Question[]>;
getById(questionId: string): Promise<Question>;
}
interface NextQuestionPolicy {
getNextQuestion(availableQuestions: Question[]): Promise<Question>;
}
interface AnswerValidationPolicy {
isAnswerValid(userAnswer: string, correctAnswer: string): Promise<boolean>;
}