Skip to content

Commit

Permalink
Solution with unit tests (gophercises#51)
Browse files Browse the repository at this point in the history
  • Loading branch information
abdul-manaan authored and joncalhoun committed Jul 22, 2019
1 parent 617e1ce commit 2a121d4
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 0 deletions.
13 changes: 13 additions & 0 deletions students/abdul/problem.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
5+5,10
7+3,10
1+1,2
8+3,11
1+2,3
8+6,14
3+1,4
1+4,5
5+1,6
2+3,5
3+3,6
2+4,6
5+2,7
131 changes: 131 additions & 0 deletions students/abdul/quiz.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package quiz

import (
"bufio"
"encoding/csv"
"flag"
"fmt"
"io"
"log"
"os"
"strings"
"time"
)

//Number of Questions to ask
const totalQuestions = 5

//Question struct that stores question with answer
type Question struct {
question string
answer string
}

func main() {
filename, timeLimit := readArguments()
f, err := openFile(filename)
if err != nil {
return
}
questions, err := readCSV(f)

if err != nil {
// err := fmt.Errorf("Error in Reading Questions")
fmt.Println(err.Error())
return
}

if questions == nil {
return
}
score, err := askQuestion(questions, timeLimit)
if err != nil {
fmt.Println(err)
return
}

fmt.Printf("Your Score %d/%d\n", score, totalQuestions)
}

func readArguments() (string, int) {
filename := flag.String("filename", "problem.csv", "CSV File that conatins quiz questions")
timeLimit := flag.Int("limit", 30, "Time Limit for each question")
flag.Parse()
return *filename, *timeLimit
}

func readCSV(f io.Reader) ([]Question, error) {
// defer f.Close() // this needs to be after the err check
allQuestions, err := csv.NewReader(f).ReadAll()
if err != nil {
return nil, err
}

numOfQues := len(allQuestions)
if numOfQues == 0 {
return nil, fmt.Errorf("No Question in file")
}

var data []Question
for _, line := range allQuestions {
ques := Question{}
ques.question = line[0]
ques.answer = line[1]
data = append(data, ques)
}

return data, nil
}

func openFile(filename string) (io.Reader, error) {
return os.Open(filename)
}
func getInput(input chan string) {
for {
in := bufio.NewReader(os.Stdin)
result, err := in.ReadString('\n')
if err != nil {
log.Fatal(err)
}

input <- result
}
}

func askQuestion(questions []Question, timeLimit int) (int, error) {
totalScore := 0
timer := time.NewTimer(time.Duration(timeLimit) * time.Second)
done := make(chan string)

go getInput(done)

for i := range [totalQuestions]int{} {
ans, err := eachQuestion(questions[i].question, questions[i].answer, timer.C, done)
if err != nil && ans == -1 {
return totalScore, nil
}
totalScore += ans

}
return totalScore, nil
}

func eachQuestion(Quest string, answer string, timer <-chan time.Time, done <-chan string) (int, error) {
fmt.Printf("%s: ", Quest)

for {
select {
case <-timer:
return -1, fmt.Errorf("Time out")
case ans := <-done:
score := 0
if strings.Compare(strings.Trim(strings.ToLower(ans), "\n"), answer) == 0 {
score = 1
} else {
return 0, fmt.Errorf("Wrong Answer")
}

return score, nil
}
}
}
59 changes: 59 additions & 0 deletions students/abdul/quiz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package quiz

import (
"strings"
"testing"
"time"

"gotest.tools/assert"
)

func testEachQuestion(t *testing.T) {
timer := time.NewTimer(time.Duration(2) * time.Second).C
done := make(chan string)
var quest Question
quest.question = "1+1"
quest.answer = "2"
var ans int
var err error
allDone := make(chan bool)
go func() {
ans, err = eachQuestion(quest.question, quest.answer, timer, done)
allDone <- true
}()
done <- "2"

<-allDone
if err != nil {
t.Error(err)
}
assert.Equal(t, ans, 1)
}

func testReadCSV(t *testing.T) {
str := "1+1,2\n2+1,3\n9+9,18\n"
quest, err := readCSV(strings.NewReader(str))
if err != nil {
t.Error(err)
}
var que [3]Question
que[0].answer = "2"
que[1].answer = "3"
que[2].answer = "18"
que[0].question = "1+1"
que[1].question = "2+1"
que[2].question = "9+9"

assert.Equal(t, que[0], quest[0])
assert.Equal(t, que[1], quest[1])
assert.Equal(t, que[2], quest[2])

}

func TestEachQuestion(t *testing.T) {
t.Run("test eachQuestion", testEachQuestion)
}

func TestReadCSV(t *testing.T) {
t.Run("test ReadCSV", testReadCSV)
}

0 comments on commit 2a121d4

Please sign in to comment.