engine: realistic config bounds, enforced and served
ConfigBounds (students 10-500, edgesPerNode 1-8, forwardProb 0-0.9,
triangleProb 0-1) caps what RunScenario accepts: a student does not
keep 150 close friendships and a guaranteed forward is not a real
base rate. numEducated gains its missing upper limit (numStudents).
Bounds-side validation also protects the public server from absurd
numStudents values. GET /api/config/default now returns
{config, bounds} so the frontend can drive its controls from the
same numbers; the frontend does not call it yet, so this commit
changes no UI behaviour.
This commit is contained in:
parent
232faf892e
commit
bd890384e5
7 changed files with 194 additions and 15 deletions
|
|
@ -11,6 +11,14 @@ import (
|
|||
"github.com/JustinZeus/spreadlab/internal/engine"
|
||||
)
|
||||
|
||||
// DefaultConfigResponse is the body of GET /api/config/default: the
|
||||
// default world plus the engine's field bounds, so the frontend drives
|
||||
// its controls and clamping from the same numbers the engine enforces.
|
||||
type DefaultConfigResponse struct {
|
||||
Config engine.Config `json:"config"`
|
||||
Bounds engine.Bounds `json:"bounds"`
|
||||
}
|
||||
|
||||
// ComparisonResponse bundles what the dashboard needs to render one
|
||||
// comparison: the config that was run, echoed back so frontend state stays
|
||||
// honest, and one result per strategy.
|
||||
|
|
@ -53,7 +61,10 @@ func NewServer() http.Handler {
|
|||
}
|
||||
|
||||
func handleDefaultConfig(w http.ResponseWriter, _ *http.Request) {
|
||||
writeJSON(w, http.StatusOK, engine.DefaultConfig())
|
||||
writeJSON(w, http.StatusOK, DefaultConfigResponse{
|
||||
Config: engine.DefaultConfig(),
|
||||
Bounds: engine.ConfigBounds(),
|
||||
})
|
||||
}
|
||||
|
||||
func handleComparison(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
|||
|
|
@ -51,12 +51,15 @@ func TestDefaultConfigEndpoint(t *testing.T) {
|
|||
if recorder.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want %d", recorder.Code, http.StatusOK)
|
||||
}
|
||||
var config engine.Config
|
||||
if err := json.Unmarshal(recorder.Body.Bytes(), &config); err != nil {
|
||||
var response DefaultConfigResponse
|
||||
if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if config != engine.DefaultConfig() {
|
||||
t.Errorf("served config %+v, want %+v", config, engine.DefaultConfig())
|
||||
if response.Config != engine.DefaultConfig() {
|
||||
t.Errorf("served config %+v, want %+v", response.Config, engine.DefaultConfig())
|
||||
}
|
||||
if response.Bounds != engine.ConfigBounds() {
|
||||
t.Errorf("served bounds %+v, want %+v", response.Bounds, engine.ConfigBounds())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue