func assertMove(t *testing.T, j *state.State, src, dst dip.Province, success bool) { if success { unit, _, ok := j.Unit(src) if !ok { t.Errorf("Should be a unit at %v", src) } j.SetOrder(src, orders.Move(src, dst)) j.Next() if err, ok := j.Resolutions()[src]; ok && err != nil { t.Errorf("Move from %v to %v should have worked, got %v", src, dst, err) } if now, _, ok := j.Unit(src); ok && reflect.DeepEqual(now, unit) { t.Errorf("%v should have moved from %v", now, src) } if now, _, _ := j.Unit(dst); !reflect.DeepEqual(now, unit) { t.Errorf("%v should be at %v now", unit, dst) } } else { unit, _, _ := j.Unit(src) j.SetOrder(src, orders.Move(src, dst)) j.Next() if err, ok := j.Resolutions()[src]; !ok || err == nil { t.Errorf("Move from %v to %v should not have worked", src, dst) } if now, _, _ := j.Unit(src); !reflect.DeepEqual(now, unit) { t.Errorf("%v should not have moved from %v", now, src) } } }
func TestMoveValidation(t *testing.T) { judge := startState(t) // Happy path fleet assertOrderValidity(t, judge, orders.Move("bre", "mid"), nil) // Happy path army assertOrderValidity(t, judge, orders.Move("mun", "ruh"), nil) // Too far assertOrderValidity(t, judge, orders.Move("bre", "wes"), cla.ErrIllegalMove) // Fleet on land assertOrderValidity(t, judge, orders.Move("bre", "par"), cla.ErrIllegalDestination) // Army at sea assertOrderValidity(t, judge, orders.Move("smy", "eas"), cla.ErrIllegalDestination) // Unknown source assertOrderValidity(t, judge, orders.Move("a", "mid"), cla.ErrInvalidSource) // Unknown destination assertOrderValidity(t, judge, orders.Move("bre", "a"), cla.ErrInvalidDestination) // Missing sea path assertOrderValidity(t, judge, orders.Move("par", "mos"), cla.ErrMissingConvoyPath) // No unit assertOrderValidity(t, judge, orders.Move("spa", "por"), cla.ErrMissingUnit) // Working convoy judge.SetUnit("eng", dip.Unit{cla.Fleet, cla.England}) judge.SetUnit("wal", dip.Unit{cla.Army, cla.England}) assertOrderValidity(t, judge, orders.Move("wal", "bre"), nil) // Missing convoy assertOrderValidity(t, judge, orders.Move("wal", "gas"), cla.ErrMissingConvoyPath) }
return } return } var datcOrderTypes = map[*regexp.Regexp]func([]string) (dip.Province, dip.Adjudicator, error){ regexp.MustCompile("(?i)^(A|F)\\s+(\\S+)\\s*-\\s*(\\S+)(\\s+via\\s+convoy)?$"): func(m []string) (prov dip.Province, order dip.Adjudicator, err error) { if prov, err = DATCProvince(m[2]); err != nil { return } dst, err := DATCProvince(m[3]) if err != nil { return } if m[4] == "" { order = orders.Move(prov, dst) } else { order = orders.Move(prov, dst).ViaConvoy() } return }, regexp.MustCompile("^(?i)remove\\s+((A|F)\\s+)?(\\S+)$"): func(m []string) (prov dip.Province, order dip.Adjudicator, err error) { if prov, err = DATCProvince(m[3]); err != nil { return } order = orders.Disband(prov, time.Now()) return }, regexp.MustCompile("^(?i)(A|F)\\s+(\\S+)\\s+disband$"): func(m []string) (prov dip.Province, order dip.Adjudicator, err error) { if prov, err = DATCProvince(m[2]); err != nil { return
func assertGame(t *testing.T, name string) (phases, ords, positions, fails int, s *state.State) { file, err := os.Open(fmt.Sprintf("games/%v", name)) if err != nil { t.Fatalf("%v", err) } if s, err = classical.Start(); err != nil { t.Fatalf("%v", err) } lines := bufio.NewReader(file) var match []string state := inNothing scCollector, unitCollector, dislodgedCollector := make(map[dip.Province]dip.Nation), make(map[dip.Province]dip.Unit), make(map[dip.Province]dip.Unit) for line, err := lines.ReadString('\n'); err == nil; line, err = lines.ReadString('\n') { line = strings.TrimSpace(line) switch state { case inNothing: if match = phaseReg.FindStringSubmatch(line); match != nil { phases += 1 setPhase(t, &s, match) } else if line == positionsTag { state = inPositions } else { t.Fatalf("Unknown line for state inNothing: %v", line) } case inPositions: if match = posReg.FindStringSubmatch(line); match != nil { positions += 1 verifyPosition(t, s, match, scCollector, unitCollector, dislodgedCollector, &fails) } else if line == ordersTag { verifyReversePositions(t, s, scCollector, unitCollector, dislodgedCollector, &fails) if fails > 0 { return } dip.ClearLog() scCollector, unitCollector, dislodgedCollector = make(map[dip.Province]dip.Nation), make(map[dip.Province]dip.Unit), make(map[dip.Province]dip.Unit) state = inOrders } else { t.Fatalf("Unknown line for state inPositions: %v", line) } case inOrders: ords += 1 if match = moveReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Move(dip.Province(match[1]), dip.Province(match[2]))) } else if match = moveViaConvoyReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Move(dip.Province(match[1]), dip.Province(match[2])).ViaConvoy()) } else if match = supportMoveReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.SupportMove(dip.Province(match[1]), dip.Province(match[2]), dip.Province(match[3]))) } else if match = supportHoldReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.SupportHold(dip.Province(match[1]), dip.Province(match[2]))) } else if match = holdReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Hold(dip.Province(match[1]))) } else if match = convoyReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Convoy(dip.Province(match[1]), dip.Province(match[2]), dip.Province(match[3]))) } else if match = buildReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[2]), orders.Build(dip.Province(match[2]), dip.UnitType(match[1]), time.Now())) } else if match = removeReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Disband(dip.Province(match[1]), time.Now())) } else if match = disbandReg.FindStringSubmatch(line); match != nil { s.SetOrder(dip.Province(match[1]), orders.Disband(dip.Province(match[1]), time.Now())) } else if match = phaseReg.FindStringSubmatch(line); match != nil { ords -= 1 phases += 1 setPhase(t, &s, match) state = inNothing } else { t.Fatalf("Unknown line for state inOrders: %v", line) } default: t.Fatalf("Unknown state %v", state) } } return }