Add some tests
parent
54f777edec
commit
34ef41632f
|
@ -17,7 +17,9 @@ config :farmbot, :init, [
|
|||
]
|
||||
|
||||
# Transports.
|
||||
config :farmbot, :transport, []
|
||||
config :farmbot, :transport, [
|
||||
Farmbot.BotState.Transport.Test
|
||||
]
|
||||
|
||||
# Configure Farmbot Behaviours.
|
||||
# config :farmbot, :behaviour,
|
||||
|
|
|
@ -239,7 +239,6 @@ defmodule Farmbot.BotState do
|
|||
end
|
||||
|
||||
def handle_events(events, _from, state) do
|
||||
# Logger.busy 3, "begin handle bot state events"
|
||||
state = do_handle(events, state)
|
||||
# Logger.success 3, "Finish handle bot state events"
|
||||
{:noreply, [state], state}
|
||||
|
|
|
@ -37,6 +37,10 @@ defmodule Farmbot.CeleryScript.AST do
|
|||
end
|
||||
end
|
||||
|
||||
def encode(thing) do
|
||||
{:error, "#{inspect thing} is not an AST node for encoding."}
|
||||
end
|
||||
|
||||
@doc "Encode a list of asts."
|
||||
def encode_body(body, acc \\ [])
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ defmodule Farmbot.CeleryScript.AST.Node.MoveRelative do
|
|||
|
||||
def execute(%{x: x, y: y, z: z, speed: speed}, _, env) do
|
||||
env = mutate_env(env)
|
||||
%{location_data: %{position: %{x: cur_x, y: cur_y, z: cur_z}}} = Farmbot.BotState.force_state_push
|
||||
%{x: cur_x, y: cur_y, z: cur_z} = Farmbot.BotState.get_current_pos()
|
||||
location = new_vec3(cur_x, cur_y, cur_z)
|
||||
offset = new_vec3(x, y, z)
|
||||
Farmbot.CeleryScript.AST.Node.MoveAbsolute.execute(%{location: location, offset: offset, speed: speed}, [], env)
|
||||
|
|
|
@ -2,7 +2,7 @@ defmodule Farmbot.CeleryScript.Utils do
|
|||
@moduledoc false
|
||||
alias Farmbot.Firmware.Vec3
|
||||
alias Farmbot.CeleryScript.AST
|
||||
alias AST.Node.{Tool, Coordinate, Point}
|
||||
alias AST.Node.{Tool, Coordinate, Point, Nothing}
|
||||
alias Farmbot.Repo.Point, as: DBPoint
|
||||
import Ecto.Query
|
||||
|
||||
|
@ -33,6 +33,10 @@ defmodule Farmbot.CeleryScript.Utils do
|
|||
end
|
||||
end
|
||||
|
||||
def ast_to_vec3(%AST{kind: Nothing}) do
|
||||
{:ok, %Vec3{x: 0, y: 0, z: 0}}
|
||||
end
|
||||
|
||||
def ast_to_vec3(%Vec3{} = vec3), do: {:ok, vec3}
|
||||
|
||||
def ast_to_vec3(%AST{kind: kind}) do
|
||||
|
|
2
mix.exs
2
mix.exs
|
@ -120,7 +120,7 @@ defmodule Farmbot.Mixfile do
|
|||
defp deps(target) do
|
||||
system(target) ++
|
||||
[
|
||||
{:bootloader, "~> 0.1.3"},
|
||||
{:bootloader, "~> 0.1.3", except: :test},
|
||||
{:nerves_runtime, "~> 0.4"},
|
||||
{:nerves_firmware, "~> 0.4.0"},
|
||||
{:nerves_firmware_ssh, "~> 0.2", only: :dev},
|
||||
|
|
|
@ -66,13 +66,13 @@ defmodule Farmbot.BotStateTest do
|
|||
assert match?(:unknown, get_state(:informational_settings).sync_status)
|
||||
end
|
||||
|
||||
# test "sets user environment" do
|
||||
# key = "some_key"
|
||||
# val = "hey! this should be in the bot's state!"
|
||||
# :ok = BotState.set_user_env(key, val)
|
||||
# res = BotState.get_user_env
|
||||
# assert match?(%{^key => ^val}, res)
|
||||
# end
|
||||
test "sets user environment" do
|
||||
key = "some_key"
|
||||
val = "hey! this should be in the bot's state!"
|
||||
:ok = BotState.set_user_env(key, val)
|
||||
res = BotState.get_user_env
|
||||
assert match?(%{^key => ^val}, res)
|
||||
end
|
||||
|
||||
test "registers and unregisters farmware" do
|
||||
name = "Not real farmware"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
defmodule Farmbot.CeleryScript.AST.Arg.ElseTest do
|
||||
use FarmbotTestSupport.AST.ArgTestCase
|
||||
alias Farmbot.CeleryScript.AST
|
||||
alias AST.Arg.Else
|
||||
|
||||
arg_is_ast(Else)
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
defmodule Farmbot.CeleryScript.AST.Arg.ThenTest do
|
||||
use FarmbotTestSupport.AST.ArgTestCase
|
||||
alias Farmbot.CeleryScript.AST
|
||||
alias AST.Arg.Then
|
||||
|
||||
arg_is_ast(Then)
|
||||
end
|
|
@ -0,0 +1,40 @@
|
|||
defmodule Farmbot.CeleryScript.AST.Arg.LhsTest do
|
||||
use FarmbotTestSupport.AST.ArgTestCase
|
||||
alias Farmbot.CeleryScript.AST.Arg.Lhs
|
||||
|
||||
test "encodes x axis" do
|
||||
Lhs.encode(:x) |> assert_cs_arg_encode_ok("x")
|
||||
end
|
||||
|
||||
test "encodes y axis" do
|
||||
Lhs.encode(:y) |> assert_cs_arg_encode_ok("y")
|
||||
end
|
||||
|
||||
test "encodes z axis" do
|
||||
Lhs.encode(:z) |> assert_cs_arg_encode_ok("z")
|
||||
end
|
||||
|
||||
test "decodes x axis" do
|
||||
Lhs.decode("x") |> assert_cs_arg_decode_ok(:x)
|
||||
end
|
||||
|
||||
test "decodes y axis" do
|
||||
Lhs.decode("y") |> assert_cs_arg_decode_ok(:y)
|
||||
end
|
||||
|
||||
test "decodes z axis" do
|
||||
Lhs.decode("y") |> assert_cs_arg_decode_ok(:y)
|
||||
end
|
||||
|
||||
test "encodes pin number" do
|
||||
Lhs.encode({:pin, 13}) |> assert_cs_arg_encode_ok("pin13")
|
||||
end
|
||||
|
||||
test "decodes pin number" do
|
||||
Lhs.decode("pin13") |> assert_cs_arg_decode_ok({:pin, 13})
|
||||
end
|
||||
|
||||
test "can't decode unknown data" do
|
||||
Lhs.decode("some_other_lhs_arg") |> assert_cs_arg_decode_err
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
defmodule Farmbot.CeleryScript.AST.Arg.LocationTest do
|
||||
use FarmbotTestSupport.AST.ArgTestCase
|
||||
alias Farmbot.CeleryScript.AST
|
||||
alias AST.Arg.Location
|
||||
|
||||
arg_is_ast(Location)
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
defmodule Farmbot.CeleryScript.AST.Arg.OffsetTest do
|
||||
use FarmbotTestSupport.AST.ArgTestCase
|
||||
alias Farmbot.CeleryScript.AST
|
||||
alias AST.Arg.Offset
|
||||
|
||||
arg_is_ast(Offset)
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
defmodule Farmbot.CeleryScript.ASTTest do
|
||||
use ExUnit.Case, async: true
|
||||
alias Farmbot.CeleryScript.AST
|
||||
|
||||
@nothing_json "{\"kind\": \"nothing\", \"args\": {}}"
|
||||
@bad_json "{\"whoops\": "
|
||||
|
||||
test "decodes ast from json" do
|
||||
res = AST.decode(@nothing_json)
|
||||
assert match?({:ok, %AST{}}, res)
|
||||
end
|
||||
|
||||
test "won't decode ast from bad json" do
|
||||
res = AST.decode(@bad_json)
|
||||
assert match?({:error, :unknown_binary}, res)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
defmodule Farmbot.CeleryScript.AST.Inspect do
|
||||
use ExUnit.Case
|
||||
alias Farmbot.CeleryScript.AST
|
||||
|
||||
@nothing_json "{\"kind\": \"nothing\", \"args\": {}}"
|
||||
|
||||
test "Inspects ast node" do
|
||||
{:ok, %AST{} = ast} = AST.decode(@nothing_json)
|
||||
assert inspect(ast, []) == "#Nothing<[]>"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
defmodule Farmbot.CeleryScript.AST.Node.MoveAbsoluteTest do
|
||||
alias Farmbot.CeleryScript.AST.Node.{Coordinate, MoveAbsolute}
|
||||
|
||||
use FarmbotTestSupport.AST.NodeTestCase, async: false
|
||||
|
||||
test "mutates env", %{env: env} do
|
||||
args = %{
|
||||
location: nothing(),
|
||||
speed: 100,
|
||||
offset: nothing()
|
||||
}
|
||||
{:ok, env} = MoveAbsolute.execute(args, [], env)
|
||||
assert_cs_env_mutation(MoveAbsolute, env)
|
||||
end
|
||||
|
||||
test "moves to a location with no offset", %{env: env} do
|
||||
nothing = nothing()
|
||||
{:ok, coordinate, env} = Coordinate.execute(%{x: 100, y: 123, z: -123}, [], env)
|
||||
args = %{
|
||||
location: coordinate,
|
||||
speed: 100,
|
||||
offset: nothing
|
||||
}
|
||||
MoveAbsolute.execute(args, [], env) |> assert_cs_success()
|
||||
%{x: res_x, y: res_y, z: res_z} = Farmbot.BotState.get_current_pos()
|
||||
assert res_x == coordinate.args.x
|
||||
assert res_y == coordinate.args.y
|
||||
assert res_z == coordinate.args.z
|
||||
end
|
||||
|
||||
test "moves to a location with an offset", %{env: env} do
|
||||
{:ok, location, env} = Coordinate.execute(%{x: 0, y: 0, z: 0}, [], env)
|
||||
{:ok, offset, env} = Coordinate.execute(%{x: 100, y: 123, z: -123}, [], env)
|
||||
args = %{
|
||||
location: location,
|
||||
speed: 100,
|
||||
offset: offset
|
||||
}
|
||||
MoveAbsolute.execute(args, [], env) |> assert_cs_success()
|
||||
%{x: res_x, y: res_y, z: res_z} = Farmbot.BotState.get_current_pos()
|
||||
assert res_x == offset.args.x
|
||||
assert res_y == offset.args.y
|
||||
assert res_z == offset.args.z
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,67 @@
|
|||
defmodule FarmbotTestSupport.AST.ArgTestCase do
|
||||
use ExUnit.CaseTemplate
|
||||
|
||||
defmodule ArgFuns do
|
||||
def assert_cs_arg_decode_ok(res, val \\ nil) do
|
||||
if val do
|
||||
assert match?({:ok, ^val}, res)
|
||||
else
|
||||
assert match?({:ok, _}, res)
|
||||
end
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def assert_cs_arg_decode_err(res) do
|
||||
assert match?({:error, _}, res)
|
||||
res
|
||||
end
|
||||
|
||||
def assert_cs_arg_encode_ok(res, val \\ nil) do
|
||||
if val do
|
||||
assert match?({:ok, ^val}, res)
|
||||
else
|
||||
assert match?({:ok, _}, res)
|
||||
end
|
||||
res
|
||||
end
|
||||
|
||||
def assert_cs_encode_err(res) do
|
||||
assert match?({:error, _}, res)
|
||||
res
|
||||
end
|
||||
|
||||
defmacro arg_is_ast(mod) do
|
||||
quote do
|
||||
@nothing_json "{\"kind\": \"nothing\", \"args\": {}}"
|
||||
@mod unquote(mod)
|
||||
|
||||
alias Farmbot.CeleryScript.AST
|
||||
|
||||
test "decodes valid ast structure" do
|
||||
res = @mod.decode(@nothing_json) |> assert_cs_arg_decode_ok()
|
||||
assert match?({:ok, %AST{}}, res)
|
||||
end
|
||||
|
||||
test "Won't decode bad data" do
|
||||
@mod.decode("this isn't an ast node") |> assert_cs_arg_decode_err
|
||||
end
|
||||
|
||||
test "encodes valid ast" do
|
||||
{:ok, ast} = AST.decode(@nothing_json)
|
||||
@mod.encode(ast) |> assert_cs_arg_decode_ok
|
||||
end
|
||||
|
||||
test "wont encode bad data" do
|
||||
@mod.encode("this isn't an ast node") |> assert_cs_encode_err
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
using do
|
||||
quote do
|
||||
import ArgFuns
|
||||
end
|
||||
end
|
||||
end
|
|
@ -27,6 +27,11 @@ defmodule FarmbotTestSupport.AST.NodeTestCase do
|
|||
end
|
||||
end
|
||||
|
||||
def nothing(env \\ struct(Macro.Env, [])) do
|
||||
{:ok, res, _} = Farmbot.CeleryScript.AST.Node.Nothing.execute(%{}, [], env)
|
||||
res
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -61,13 +61,15 @@ defmodule FarmbotTestSupport do
|
|||
end
|
||||
end
|
||||
|
||||
defp ping_mqtt(tkn) do
|
||||
url = Farmbot.Jwt.decode!(tkn).mqtt
|
||||
Logger.info("Preflight check: mqtt: #{url}")
|
||||
# defp ping_mqtt(tkn) do
|
||||
# url = Farmbot.Jwt.decode!(tkn).mqtt
|
||||
# Logger.info("Preflight check: mqtt: #{url}")
|
||||
#
|
||||
# case :gen_tcp.connect(to_charlist(url), 1883, [:binary]) do
|
||||
# {:error, _} -> :mqtt
|
||||
# {:ok, port} -> :gen_tcp.close(port)
|
||||
# end
|
||||
# end
|
||||
|
||||
case :gen_tcp.connect(to_charlist(url), 1883, [:binary]) do
|
||||
{:error, _} -> :mqtt
|
||||
{:ok, port} -> :gen_tcp.close(port)
|
||||
end
|
||||
end
|
||||
defp ping_mqtt(_), do: :ok
|
||||
end
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
defmodule Farmbot.BotState.Transport.Test do
|
||||
use GenStage
|
||||
|
||||
def start_link do
|
||||
GenStage.start_link(__MODULE__, [], [name: __MODULE__])
|
||||
end
|
||||
|
||||
def init([]) do
|
||||
{:consumer, :no_state, subscribe_to: [Farmbot.BotState, Farmbot.Logger]}
|
||||
end
|
||||
|
||||
def handle_events(_, _, state) do
|
||||
{:noreply, [], state}
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue