498 lines
11 KiB
Elixir
498 lines
11 KiB
Elixir
defmodule FarmbotCore.Asset.CriteriaRetrieverTest do
|
|
use ExUnit.Case, async: true
|
|
use Mimic
|
|
|
|
alias FarmbotCore.Asset.{
|
|
CriteriaRetriever,
|
|
Point,
|
|
PointGroup,
|
|
Repo
|
|
}
|
|
|
|
setup :verify_on_exit!
|
|
|
|
@fake_point_group %PointGroup{
|
|
criteria: %{
|
|
"day" => %{"op" => "<", "days_ago" => 4},
|
|
"string_eq" => %{
|
|
"openfarm_slug" => ["five", "nine"],
|
|
"meta.created_by" => ["plant-detection"]
|
|
},
|
|
"number_eq" => %{"radius" => [6, 10, 11]},
|
|
"number_lt" => %{"x" => 7},
|
|
"number_gt" => %{"z" => 8}
|
|
}
|
|
}
|
|
|
|
@simple_point_group %PointGroup{
|
|
point_ids: [],
|
|
sort_type: "xy_ascending",
|
|
criteria: %{
|
|
"day" => %{
|
|
"op" => "<",
|
|
"days_ago" => 0
|
|
},
|
|
"string_eq" => %{
|
|
"pointer_type" => ["Plant"]
|
|
},
|
|
"number_eq" => %{},
|
|
"number_lt" => %{},
|
|
"number_gt" => %{}
|
|
}
|
|
}
|
|
|
|
# Use this is a fake "Timex.now()" value when mocking.
|
|
@now ~U[2222-12-10 02:22:22.222222Z]
|
|
@five_days_ago ~U[2222-12-05 01:11:11.111111Z]
|
|
|
|
@n 1000
|
|
def rand, do: Enum.random(0..@n) / 1
|
|
|
|
def point!(%{id: id} = params) do
|
|
point =
|
|
Map.merge(
|
|
%Point{
|
|
id: id,
|
|
name: "point #{id}",
|
|
meta: %{},
|
|
plant_stage: "planted",
|
|
created_at: @now,
|
|
pointer_type: "Plant",
|
|
radius: 10.0,
|
|
tool_id: nil,
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
x: 0.0,
|
|
y: 0.0,
|
|
z: 0.0
|
|
},
|
|
params
|
|
)
|
|
|
|
Repo.insert!(point)
|
|
point
|
|
end
|
|
|
|
def point_group_with_fake_points do
|
|
Repo.delete_all(PointGroup)
|
|
Repo.delete_all(Point)
|
|
|
|
whitelist = [
|
|
%Point{id: 1, x: rand(), y: rand(), z: rand()},
|
|
%Point{id: 2, x: rand(), y: rand(), z: rand()},
|
|
%Point{id: 3, x: rand(), y: rand(), z: rand()}
|
|
]
|
|
|
|
exclusion = [
|
|
%Point{created_at: @now},
|
|
%Point{openfarm_slug: "not five"},
|
|
%Point{radius: 10.0},
|
|
%Point{x: 10.0},
|
|
%Point{z: 6.0}
|
|
]
|
|
|
|
incusion = [
|
|
# INCLUSION POINTS
|
|
%Point{created_at: ~U[2222-12-04 02:22:22.222222Z]},
|
|
%Point{openfarm_slug: "five"},
|
|
%Point{radius: 6.0},
|
|
%Point{x: 7.0},
|
|
%Point{z: 8.0}
|
|
]
|
|
|
|
points = whitelist ++ exclusion ++ incusion
|
|
Enum.map(points, fn p -> Repo.insert!(p) end)
|
|
pg = %PointGroup{@fake_point_group | point_ids: [1, 2, 3]}
|
|
Repo.insert!(pg)
|
|
pg
|
|
end
|
|
|
|
test "direct match on `pointer_type` via `string_eq`" do
|
|
Repo.delete_all(PointGroup)
|
|
Repo.delete_all(Point)
|
|
|
|
point!(%{id: 1, pointer_type: "Plant"})
|
|
point!(%{id: 2, pointer_type: "Weed"})
|
|
point!(%{id: 3, pointer_type: "ToolSlot"})
|
|
point!(%{id: 4, pointer_type: "GenericPointer"})
|
|
|
|
result = CriteriaRetriever.run(@simple_point_group)
|
|
assert Enum.count(result) == 1
|
|
end
|
|
|
|
test "run/1" do
|
|
expect(Timex, :now, fn -> @now end)
|
|
pg = point_group_with_fake_points()
|
|
|
|
# This one is _almost_ a perfect match,
|
|
# but the meta field is a miss.
|
|
point!(%{
|
|
id: 888,
|
|
created_at: @five_days_ago,
|
|
openfarm_slug: "five",
|
|
meta: %{"created_by" => "not-plant-detection"},
|
|
radius: 10.0,
|
|
x: 6.0,
|
|
z: 9.0
|
|
})
|
|
|
|
perfect_match =
|
|
point!(%{
|
|
id: 999,
|
|
created_at: @five_days_ago,
|
|
openfarm_slug: "five",
|
|
meta: %{"created_by" => "plant-detection"},
|
|
radius: 10.0,
|
|
x: 6.0,
|
|
z: 9.0
|
|
})
|
|
|
|
expected = [perfect_match.id, 1, 2, 3]
|
|
results = Enum.map(CriteriaRetriever.run(pg), fn p -> p.id end)
|
|
assert Enum.count(expected) == Enum.count(results)
|
|
Enum.map(expected, fn id -> assert Enum.member?(results, id) end)
|
|
end
|
|
|
|
@tag :capture_log
|
|
test "point group that does not define criteria" do
|
|
Repo.delete_all(PointGroup)
|
|
Repo.delete_all(Point)
|
|
|
|
whitelist = [88457, 88455]
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-01-09 19:09:39.176321Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88455,
|
|
meta: %{},
|
|
name: "Spinach",
|
|
openfarm_slug: nil,
|
|
plant_stage: "planned",
|
|
planted_at: nil,
|
|
pointer_type: "Plant",
|
|
radius: 25.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 400.0,
|
|
y: 100.0,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-01-09 19:09:39.413318Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88456,
|
|
meta: %{},
|
|
name: "Spinach",
|
|
openfarm_slug: nil,
|
|
plant_stage: "planned",
|
|
planted_at: nil,
|
|
pointer_type: "Plant",
|
|
radius: 25.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 400.0,
|
|
y: 300.0,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-01-09 19:09:39.610901Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88457,
|
|
meta: %{},
|
|
name: "Spinach",
|
|
openfarm_slug: nil,
|
|
plant_stage: "planned",
|
|
planted_at: nil,
|
|
pointer_type: "Plant",
|
|
radius: 25.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 600.0,
|
|
y: 100.0,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-01-09 19:09:39.824048Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88458,
|
|
meta: %{},
|
|
name: "Spinach",
|
|
openfarm_slug: nil,
|
|
plant_stage: "planned",
|
|
planted_at: nil,
|
|
pointer_type: "Plant",
|
|
radius: 25.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 600.0,
|
|
y: 300.0,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-01-09 19:09:40.012075Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88459,
|
|
meta: %{},
|
|
name: "Spinach",
|
|
openfarm_slug: nil,
|
|
plant_stage: "planned",
|
|
planted_at: nil,
|
|
pointer_type: "Plant",
|
|
radius: 25.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 800.0,
|
|
y: 300.0,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-01-09 19:09:40.202385Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88460,
|
|
meta: %{},
|
|
name: "Spinach",
|
|
openfarm_slug: nil,
|
|
plant_stage: "planned",
|
|
planted_at: nil,
|
|
pointer_type: "Plant",
|
|
radius: 25.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 800.0,
|
|
y: 100.0,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-01-09 19:09:40.402777Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88461,
|
|
meta: %{},
|
|
name: "Broccoli",
|
|
openfarm_slug: nil,
|
|
plant_stage: "planned",
|
|
planted_at: nil,
|
|
pointer_type: "Plant",
|
|
radius: 25.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 600.0,
|
|
y: 700.0,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-01-09 19:09:40.776337Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88462,
|
|
meta: %{},
|
|
name: "Beets",
|
|
openfarm_slug: nil,
|
|
plant_stage: "planned",
|
|
planted_at: nil,
|
|
pointer_type: "Plant",
|
|
radius: 25.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 800.0,
|
|
y: 1.1e3,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-01-09 19:09:40.960424Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88463,
|
|
meta: %{},
|
|
name: "Beets",
|
|
openfarm_slug: nil,
|
|
plant_stage: "planned",
|
|
planted_at: nil,
|
|
pointer_type: "Plant",
|
|
radius: 25.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 600.0,
|
|
y: 1.1e3,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-01-09 19:09:41.171967Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88464,
|
|
meta: %{},
|
|
name: "Beets",
|
|
openfarm_slug: nil,
|
|
plant_stage: "planned",
|
|
planted_at: nil,
|
|
pointer_type: "Plant",
|
|
radius: 25.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 400.0,
|
|
y: 1.1e3,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-01-09 19:09:41.393021Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88465,
|
|
meta: %{},
|
|
name: "Beets",
|
|
openfarm_slug: nil,
|
|
plant_stage: "planned",
|
|
planted_at: nil,
|
|
pointer_type: "Plant",
|
|
radius: 25.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 200.0,
|
|
y: 1.1e3,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-02-21 01:41:07.714000Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: true,
|
|
id: 88798,
|
|
meta: %{},
|
|
name: "Tool Slot",
|
|
openfarm_slug: nil,
|
|
plant_stage: nil,
|
|
planted_at: nil,
|
|
pointer_type: "ToolSlot",
|
|
radius: nil,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 0.0,
|
|
y: 0.0,
|
|
z: -20.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-02-21 18:30:56.301000Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88805,
|
|
meta: %{},
|
|
name: "Slot",
|
|
openfarm_slug: nil,
|
|
plant_stage: nil,
|
|
planted_at: nil,
|
|
pointer_type: "ToolSlot",
|
|
radius: nil,
|
|
tool_id: 12143,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 200.0,
|
|
y: 200.0,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-02-21 18:47:45.170000Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88806,
|
|
meta: %{},
|
|
name: "Slot",
|
|
openfarm_slug: nil,
|
|
plant_stage: nil,
|
|
planted_at: nil,
|
|
pointer_type: "ToolSlot",
|
|
radius: nil,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 0.0,
|
|
y: 0.0,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-02-21 20:01:59.960000Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88828,
|
|
meta: %{
|
|
"color" => "green",
|
|
"created_by" => "farm-designer",
|
|
"type" => "point"
|
|
},
|
|
name: "Created Point",
|
|
openfarm_slug: nil,
|
|
plant_stage: nil,
|
|
planted_at: nil,
|
|
pointer_type: "GenericPointer",
|
|
radius: 15.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[1970-11-07 16:52:31.618000Z],
|
|
x: 1.0,
|
|
y: 1.0,
|
|
z: 0.0
|
|
})
|
|
|
|
point!(%{
|
|
created_at: ~U[2020-02-29 21:08:40.934000Z],
|
|
discarded_at: nil,
|
|
gantry_mounted: false,
|
|
id: 88887,
|
|
meta: %{
|
|
"color" => "red",
|
|
"created_by" => "farm-designer",
|
|
"type" => "weed"
|
|
},
|
|
name: "Created Weed",
|
|
openfarm_slug: nil,
|
|
plant_stage: nil,
|
|
planted_at: nil,
|
|
pointer_type: "GenericPointer",
|
|
radius: 15.0,
|
|
tool_id: nil,
|
|
updated_at: ~U[2020-02-29 21:08:40.934000Z],
|
|
x: 100.0,
|
|
y: 100.0,
|
|
z: 0.0
|
|
})
|
|
|
|
pg = %PointGroup{
|
|
created_at: ~U[2020-02-29 21:14:33.337000Z],
|
|
criteria: %{
|
|
"day" => %{"days_ago" => 0, "op" => "<"},
|
|
"number_eq" => %{},
|
|
"number_gt" => %{},
|
|
"number_lt" => %{},
|
|
"string_eq" => %{}
|
|
},
|
|
id: 201,
|
|
local_id: "30856f5e-1f97-4e18-b5e0-84dc7cd9bbf0",
|
|
name: "Test (Broke?)",
|
|
point_ids: whitelist,
|
|
sort_type: "xy_ascending",
|
|
updated_at: ~U[2020-03-02 21:55:26.973000Z]
|
|
}
|
|
|
|
Repo.insert!(pg)
|
|
results = Enum.map(CriteriaRetriever.run(pg), fn p -> p.id end)
|
|
assert Enum.count(whitelist) == Enum.count(results)
|
|
Enum.map(whitelist, fn id -> assert Enum.member?(results, id) end)
|
|
end
|
|
end
|