fallout_test.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/stretchr/testify/assert"
  5. "testing"
  6. )
  7. func Test_scoreWordsByCommonLetterLocations(t *testing.T) {
  8. type args struct {
  9. words []string
  10. }
  11. tests := []struct {
  12. name string
  13. args args
  14. want map[string]int
  15. }{
  16. {
  17. name: "no letters in common",
  18. args: args{words: []string{"aaa", "bbb"}},
  19. want: map[string]int{"aaa": 3, "bbb": 3},
  20. },
  21. {
  22. name: "one letter in common",
  23. args: args{words: []string{"aaa", "abb"}},
  24. want: map[string]int{"aaa": 4, "abb": 4},
  25. },
  26. {
  27. name: "three Words with some letters in common",
  28. args: args{words: []string{"aaa", "abb", "aab"}},
  29. want: map[string]int{"aaa": 6, "abb": 6, "aab": 7},
  30. },
  31. }
  32. for _, tt := range tests {
  33. t.Run(tt.name, func(t *testing.T) {
  34. game := NewGame()
  35. for _, word := range tt.args.words {
  36. game.Words[word] = &Word{Word: word}
  37. }
  38. err := game.scoreWordsByCommonLetterLocations()
  39. if err != nil {
  40. t.Errorf("Error scoring Words: %s\n", err)
  41. t.FailNow()
  42. }
  43. for word, score := range tt.want {
  44. if game.Words[word].Score != score {
  45. t.Errorf("Word %s has score %d, expected %d", word, game.Words[word].Score, score)
  46. }
  47. }
  48. })
  49. }
  50. }
  51. func TestWord_MatchesGuess(t *testing.T) {
  52. type fields struct {
  53. Word string
  54. Score int
  55. }
  56. type args struct {
  57. guess string
  58. numMatchingChars int
  59. }
  60. tests := []struct {
  61. name string
  62. fields fields
  63. args args
  64. want bool
  65. }{
  66. {
  67. name: "no letters in common",
  68. fields: fields{Word: "aaa"},
  69. args: args{guess: "bbb", numMatchingChars: 0},
  70. want: true,
  71. },
  72. {
  73. name: "one letter in common",
  74. fields: fields{Word: "aaa"},
  75. args: args{guess: "abb", numMatchingChars: 1},
  76. want: true,
  77. },
  78. {
  79. name: "one letter in common where expecting 2",
  80. fields: fields{Word: "aaa"},
  81. args: args{guess: "aba", numMatchingChars: 1},
  82. want: false,
  83. },
  84. }
  85. for _, tt := range tests {
  86. t.Run(tt.name, func(t *testing.T) {
  87. w := Word{
  88. Word: tt.fields.Word,
  89. Score: tt.fields.Score,
  90. }
  91. if got := w.MatchesGuess(tt.args.guess, tt.args.numMatchingChars); got != tt.want {
  92. t.Errorf("MatchesGuess() = %v, want %v", got, tt.want)
  93. }
  94. })
  95. }
  96. }
  97. func TestGame_FilterWords(t *testing.T) {
  98. type fields struct {
  99. Words map[string]*Word
  100. Length int
  101. }
  102. type args struct {
  103. guess string
  104. score int
  105. }
  106. tests := []struct {
  107. name string
  108. fields fields
  109. args args
  110. want map[string]*Word
  111. }{
  112. {
  113. name: "no words filtered with score = 0",
  114. fields: fields{
  115. Words: map[string]*Word{
  116. "aaa": {Word: "aaa"},
  117. "bbb": {Word: "bbb"},
  118. },
  119. },
  120. args: args{guess: "ccc", score: 0},
  121. want: map[string]*Word{
  122. "aaa": {Word: "aaa"},
  123. "bbb": {Word: "bbb"},
  124. },
  125. },
  126. {
  127. name: "no words filtered with score = 1",
  128. fields: fields{
  129. Words: map[string]*Word{
  130. "aac": {Word: "aac"},
  131. "bbc": {Word: "bbc"},
  132. },
  133. },
  134. args: args{guess: "ccc", score: 1},
  135. want: map[string]*Word{
  136. "aac": {Word: "aac"},
  137. "bbc": {Word: "bbc"},
  138. },
  139. },
  140. {
  141. name: "some words filtered",
  142. fields: fields{
  143. Words: map[string]*Word{
  144. "aac": {Word: "aac"},
  145. "bbc": {Word: "bbc"},
  146. "ccc": {Word: "ccc"},
  147. },
  148. },
  149. args: args{guess: "ccc", score: 1},
  150. want: map[string]*Word{
  151. "aac": {Word: "aac"},
  152. "bbc": {Word: "bbc"},
  153. },
  154. },
  155. {
  156. name: "real world case",
  157. fields: fields{
  158. Words: map[string]*Word{
  159. "pleads": {Word: "pleads", Score: 13},
  160. "crimes": {Word: "crimes", Score: 16},
  161. "fierce": {Word: "fierce", Score: 12},
  162. "wagons": {Word: "wagons", Score: 14},
  163. "shiner": {Word: "shiner", Score: 14},
  164. "wastes": {Word: "wastes", Score: 20},
  165. "tables": {Word: "tables", Score: 17},
  166. "ripped": {Word: "ripped", Score: 14},
  167. "silver": {Word: "silver", Score: 16},
  168. "insane": {Word: "insane", Score: 13},
  169. "visage": {Word: "visage", Score: 15},
  170. },
  171. },
  172. args: args{guess: "wastes", score: 1},
  173. want: map[string]*Word{
  174. "pleads": {Word: "pleads", Score: 13},
  175. "insane": {Word: "insane", Score: 13},
  176. "shiner": {Word: "shiner", Score: 14},
  177. "visage": {Word: "visage", Score: 15},
  178. "silver": {Word: "silver", Score: 16},
  179. "ripped": {Word: "ripped", Score: 14},
  180. },
  181. },
  182. }
  183. for _, tt := range tests {
  184. t.Run(tt.name, func(t *testing.T) {
  185. g := Game{
  186. Words: tt.fields.Words,
  187. Length: tt.fields.Length,
  188. }
  189. g.FilterWords(tt.args.guess, tt.args.score)
  190. fmt.Printf("Want: %v\n", tt.want)
  191. fmt.Printf("Got: %v\n", g.Words)
  192. for word := range tt.want {
  193. if _, ok := g.Words[word]; !ok {
  194. t.Errorf("Word %s was removed, expected it to remain", word)
  195. }
  196. }
  197. assert.Equal(t, len(tt.want), len(g.Words), "Wrong number of matches")
  198. })
  199. }
  200. }
  201. func TestGame_getBestGuess(t *testing.T) {
  202. type fields struct {
  203. Words map[string]*Word
  204. Length int
  205. }
  206. tests := []struct {
  207. name string
  208. fields fields
  209. want string
  210. wantErr bool
  211. }{
  212. {
  213. name: "simple case",
  214. fields: fields{
  215. Words: map[string]*Word{
  216. "aaa": {Word: "aaa", Score: 3},
  217. "aab": {Word: "aab", Score: 2},
  218. "caa": {Word: "caa", Score: 2},
  219. },
  220. },
  221. want: "aaa",
  222. },
  223. {
  224. name: "real-world case",
  225. fields: fields{
  226. Words: map[string]*Word{
  227. "pleads": {Word: "pleads", Score: 13},
  228. "crimes": {Word: "crimes", Score: 16},
  229. "fierce": {Word: "fierce", Score: 12},
  230. "wagons": {Word: "wagons", Score: 14},
  231. "shiner": {Word: "shiner", Score: 14},
  232. "wastes": {Word: "wastes", Score: 20},
  233. "tables": {Word: "tables", Score: 17},
  234. "ripped": {Word: "ripped", Score: 14},
  235. "silver": {Word: "silver", Score: 16},
  236. "visage": {Word: "visage", Score: 15},
  237. "insane": {Word: "insane", Score: 13},
  238. },
  239. },
  240. want: "wastes",
  241. },
  242. }
  243. for _, tt := range tests {
  244. t.Run(tt.name, func(t *testing.T) {
  245. g := Game{
  246. Words: tt.fields.Words,
  247. Length: tt.fields.Length,
  248. }
  249. got, err := g.getBestGuess()
  250. if (err != nil) != tt.wantErr {
  251. t.Errorf("getBestGuess() error = %v, wantErr %v", err, tt.wantErr)
  252. return
  253. }
  254. if got != tt.want {
  255. t.Errorf("getBestGuess() got = %v, want %v", got, tt.want)
  256. }
  257. })
  258. }
  259. }
  260. func TestGame_getSortedScores(t *testing.T) {
  261. type fields struct {
  262. Words map[string]*Word
  263. }
  264. tests := []struct {
  265. name string
  266. fields fields
  267. want []string
  268. }{
  269. {
  270. name: "sort words by scores",
  271. fields: fields{
  272. Words: map[string]*Word{
  273. "pleads": {Word: "pleads", Score: 13},
  274. "crimes": {Word: "crimes", Score: 16},
  275. "fierce": {Word: "fierce", Score: 12},
  276. "shiner": {Word: "shiner", Score: 14},
  277. "wastes": {Word: "wastes", Score: 20},
  278. "tables": {Word: "tables", Score: 17},
  279. "visage": {Word: "visage", Score: 15},
  280. },
  281. },
  282. want: []string{"wastes", "tables", "crimes", "visage", "shiner", "pleads", "fierce"},
  283. },
  284. }
  285. for _, tt := range tests {
  286. t.Run(tt.name, func(t *testing.T) {
  287. g := Game{
  288. Words: tt.fields.Words,
  289. }
  290. assert.Equalf(t, tt.want, g.getSortedScores(), "getSortedScores()")
  291. })
  292. }
  293. }