Skip to content

Instantly share code, notes, and snippets.

@Herve07h22
Last active March 10, 2023 15:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Herve07h22/5ed126f24cb9c68457a3fc737152ecfb to your computer and use it in GitHub Desktop.
Save Herve07h22/5ed126f24cb9c68457a3fc737152ecfb to your computer and use it in GitHub Desktop.
Sample question/answer kata
import { makeAutoObservable } from "mobx";
type Choice = {
id: number;
text: string;
};
type Question = {
id: number;
text: string;
choices: Choice[];
};
interface EvaluationApi {
submitAnswer: (
questionId: number,
answer: Choice["id"]
) => Promise<"Good answer" | "Wrong answer">;
getNextQuestion: (previousQuestionId?: number) => Promise<Question>;
}
enum EvaluationStatus {
WAITING_FOR_NEXT_QUESTION = "Waiting for the next question",
WAITING_FOR_ANSWER = "Answer this question !",
SUBMIT_ERROR = "Cannot answer a question before it was asked !",
WRONG_ANSWER = "❌ Wrong answer, try again",
GOOD_ANSWER = "✅ Good answer",
}
export class Evaluation {
// Reactive states
currentQuestion?: Question;
statusMessage: string = EvaluationStatus.WAITING_FOR_NEXT_QUESTION;
private goodAnswers = new Set<number>();
constructor(private api: EvaluationApi) {
makeAutoObservable(this); // Make it reactive with this single line
this.getNextQuestion();
}
// Action
async submitAnswer(choiceId: Choice["id"]) {
if (
!this.currentQuestion ||
!this.currentQuestion.choices.find((choice) => choice.id === choiceId)
) {
this.setStatusMessage(EvaluationStatus.SUBMIT_ERROR);
return;
}
await this.api
.submitAnswer(this.currentQuestion.id, choiceId)
.then(this.checkAnswer(this.currentQuestion.id));
}
// Derived
get nbOfGoodAnswers() {
return this.goodAnswers.size;
}
// Internal actions
private async getNextQuestion() {
this.currentQuestion = await this.api.getNextQuestion(
this.currentQuestion?.id
);
this.setStatusMessage(EvaluationStatus.WAITING_FOR_ANSWER);
}
private checkAnswer =
(questionId: number) => (result: "Good answer" | "Wrong answer") => {
if (result === "Wrong answer") {
this.setStatusMessage(EvaluationStatus.WRONG_ANSWER);
return;
}
this.setStatusMessage(EvaluationStatus.GOOD_ANSWER);
this.goodAnswers.add(questionId);
this.getNextQuestion();
};
private setStatusMessage(status: EvaluationStatus) {
// TODO : Manage i18n here ?
this.statusMessage = String(status);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment