[STABLE] Looks like if_statements are done?
parent
4f0cf24097
commit
074cec8676
|
@ -12,7 +12,8 @@ module SequenceMigration
|
|||
[
|
||||
AddVersionInfo,
|
||||
UpdateChannelNames,
|
||||
AddToolsToMoveAbs
|
||||
AddToolsToMoveAbs,
|
||||
UpdateIfStatement
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ module SequenceMigration
|
|||
# When this migration was created, the move_absolute block could only move to
|
||||
# a fixed point on the map.
|
||||
# After this migration, the user could move to a dynamically set tool location
|
||||
# -OR- a fixed point on the map.
|
||||
# -OR- a fixed point on the map. It also added an "offset" property for tools
|
||||
# with funny sizes.
|
||||
class AddToolsToMoveAbs < Base
|
||||
VERSION = 2
|
||||
CREATED_ON = "DECEMBER 19 2016"
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
module SequenceMigration
|
||||
# Background:
|
||||
# This is a refactor of what once was called the `if_statement` block:
|
||||
# * Added a `nothing` node type (sorry, we actually need it now).
|
||||
# * if_statement becomes _if
|
||||
# * sub_sequence_id becomes _then
|
||||
# * Add _else arg to _if.
|
||||
# * _then/_else expect a execute or nothing node instead of a number.
|
||||
class UpdateIfStatement < Base
|
||||
VERSION = 3
|
||||
CREATED_ON = "DECEMBER 20 2016"
|
||||
|
||||
def up
|
||||
sequence
|
||||
.body
|
||||
.select { |x| x["kind"] == "if_statement" }
|
||||
.each do |x|
|
||||
binding.pry
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8,7 +8,7 @@ module CeleryScriptSettingsBag
|
|||
ALLOWED_DATA_TYPES = %w(string integer)
|
||||
ALLOWED_OPS = %w(< > is not)
|
||||
STEPS = %w(move_absolute move_relative write_pin read_pin wait
|
||||
send_message execute if_statement)
|
||||
send_message execute _if)
|
||||
ALLOWED_LHS = %w(busy pin0 pin1 pin2 pin3 pin4 pin5 pin6 pin7 pin8
|
||||
pin9 pin10 pin11 pin12 pin13 x y z)
|
||||
BAD_ALLOWED_PIN_MODES = 'Can not put "%s" into a left hand side (LHS) '\
|
||||
|
@ -69,6 +69,9 @@ module CeleryScriptSettingsBag
|
|||
.defineArg(:message, [String])
|
||||
.defineArg(:location, [:tool, :coordinate])
|
||||
.defineArg(:offset, [:coordinate])
|
||||
.defineArg(:_then, [:execute, :nothing])
|
||||
.defineArg(:_else, [:execute, :nothing])
|
||||
.defineNode(:nothing, [])
|
||||
.defineNode(:tool, [:tool_id])
|
||||
.defineNode(:coordinate, [:x, :y, :z])
|
||||
.defineNode(:move_absolute, [:location, :speed, :offset])
|
||||
|
@ -79,7 +82,7 @@ module CeleryScriptSettingsBag
|
|||
.defineNode(:wait, [:milliseconds])
|
||||
.defineNode(:send_message, [:message, :message_type], [:channel])
|
||||
.defineNode(:execute, [:sub_sequence_id])
|
||||
.defineNode(:if_statement, [:lhs, :op, :rhs, :sub_sequence_id])
|
||||
.defineNode(:_if, [:lhs, :op, :rhs, :_then, :_else])
|
||||
.defineNode(:sequence, [:version], STEPS)
|
||||
|
||||
def self.within(array, node)
|
||||
|
|
|
@ -42,6 +42,7 @@ module Sequences
|
|||
@checker = CeleryScript::Checker.new(tree, corpus)
|
||||
end
|
||||
|
||||
# TODO: This is too specific to corpus stuff. Does not belong in this class.
|
||||
def sub_sequences
|
||||
all = []
|
||||
return all unless checker.valid?
|
||||
|
|
|
@ -2,6 +2,6 @@ FactoryGirl.define do
|
|||
factory :tool do
|
||||
tool_slot
|
||||
device
|
||||
name "MyString"
|
||||
name { Faker::Pokemon.name }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,62 +1,71 @@
|
|||
[
|
||||
{
|
||||
"kind":"move_absolute",
|
||||
"args":{
|
||||
"x":1,
|
||||
"y":2,
|
||||
"z":3,
|
||||
"speed":4
|
||||
"kind": "move_absolute",
|
||||
"args": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"z": 3,
|
||||
"speed": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind":"move_relative",
|
||||
"args":{
|
||||
"x":1,
|
||||
"y":2,
|
||||
"z":3,
|
||||
"speed":4
|
||||
"kind": "move_relative",
|
||||
"args": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"z": 3,
|
||||
"speed": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind":"write_pin",
|
||||
"args":{
|
||||
"pin_number":1,
|
||||
"pin_value":0,
|
||||
"pin_mode":1
|
||||
"kind": "write_pin",
|
||||
"args": {
|
||||
"pin_number": 1,
|
||||
"pin_value": 0,
|
||||
"pin_mode": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind":"read_pin",
|
||||
"args":{
|
||||
"pin_number":1,
|
||||
"data_label":"probably_a_variable"
|
||||
"kind": "read_pin",
|
||||
"args": {
|
||||
"pin_number": 1,
|
||||
"data_label": "probably_a_variable"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind":"wait",
|
||||
"args":{
|
||||
"milliseconds":5000
|
||||
"kind": "wait",
|
||||
"args": {
|
||||
"milliseconds": 5000
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind":"send_message",
|
||||
"args":{
|
||||
"message":"Value is {{ probably_a_variable }}"
|
||||
"kind": "send_message",
|
||||
"args": {
|
||||
"message": "Value is {{ probably_a_variable }}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind":"execute",
|
||||
"args":{
|
||||
"sub_sequence_id":123
|
||||
"kind": "execute",
|
||||
"args": {
|
||||
"sub_sequence_id": 123
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind":"if_statement",
|
||||
"args":{
|
||||
"lhs":"x",
|
||||
"op":">",
|
||||
"rhs":5,
|
||||
"sub_sequence_id":123
|
||||
"kind": "_if",
|
||||
"args": {
|
||||
"lhs": "x",
|
||||
"op": ">",
|
||||
"rhs": 5,
|
||||
"_then": {
|
||||
"kind": "nothing",
|
||||
"args": {}
|
||||
},
|
||||
"_else": {
|
||||
"kind": "execute",
|
||||
"args": {
|
||||
"sub_sequence_id": 123
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
|
@ -2,7 +2,7 @@
|
|||
"kind": "sequence",
|
||||
"comment": "Properly formatted, syntactically valid sequence.",
|
||||
"args": {
|
||||
"version": 1
|
||||
"version": 3
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
|
@ -33,7 +33,7 @@
|
|||
"location": {
|
||||
"kind": "tool",
|
||||
"args": {
|
||||
"tool_id": 1
|
||||
"tool_id": 8888
|
||||
}
|
||||
},
|
||||
"offset": {
|
||||
|
@ -94,18 +94,27 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"kind": "if_statement",
|
||||
"kind": "_if",
|
||||
"args": {
|
||||
"lhs": "x",
|
||||
"rhs": 300,
|
||||
"op": "is",
|
||||
"sub_sequence_id": 456
|
||||
"_then": {
|
||||
"kind": "execute",
|
||||
"args": {
|
||||
"sub_sequence_id": 9999
|
||||
}
|
||||
},
|
||||
"_else": {
|
||||
"kind": "nothing",
|
||||
"args": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "execute",
|
||||
"args": {
|
||||
"sub_sequence_id": 123
|
||||
"sub_sequence_id": 9999
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -101,7 +101,7 @@ describe CeleryScript::Corpus do
|
|||
it "serializes into JSON" do
|
||||
result = JSON.parse(corpus.to_json)
|
||||
|
||||
expect(result["tag"]).to eq(2)
|
||||
expect(result["tag"]).to eq(3)
|
||||
expect(result["args"]).to be_kind_of(Array)
|
||||
expect(result["nodes"]).to be_kind_of(Array)
|
||||
expect(result["nodes"].sample.keys.sort).to eq(["allowed_args",
|
||||
|
|
|
@ -2,6 +2,6 @@ require 'spec_helper'
|
|||
|
||||
describe SequenceMigration do
|
||||
it 'has a latest version' do
|
||||
expect(SequenceMigration::Base.latest_version).to eq(2)
|
||||
expect(SequenceMigration::Base.latest_version).to eq(3)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,7 +36,7 @@ describe Sequences::Create do
|
|||
end
|
||||
|
||||
it 'Gives validation errors for malformed sub_sequence_id' do
|
||||
body[7]["args"]["sub_sequence_id"] = 0
|
||||
body[7]["args"]["_then"]["args"]["sub_sequence_id"] = 0
|
||||
seq = Sequences::Create.run(sequence_params)
|
||||
expect(seq.success?).to be(false)
|
||||
expectation = "Sequence #0 does not exist."
|
||||
|
@ -44,7 +44,7 @@ describe Sequences::Create do
|
|||
end
|
||||
|
||||
it 'Gives validation errors for malformed LHS' do
|
||||
body.select{ |x| x["kind"] == "if_statement" }.first["args"]["lhs"] = "xyz"
|
||||
body.select{ |x| x["kind"] == "_if" }.first["args"]["lhs"] = "xyz"
|
||||
seq = Sequences::Create.run(sequence_params)
|
||||
expect(seq.success?).to be(false)
|
||||
expected = "Can not put \"xyz\" into a left hand side (LHS) argument."
|
||||
|
@ -52,7 +52,7 @@ describe Sequences::Create do
|
|||
end
|
||||
|
||||
it 'Gives validation errors for malformed OP' do
|
||||
body.select{ |x| x["kind"] == "if_statement" }.first["args"]["op"] = "was"
|
||||
body.select{ |x| x["kind"] == "_if" }.first["args"]["op"] = "was"
|
||||
seq = Sequences::Create.run(sequence_params)
|
||||
expect(seq.success?).to be(false)
|
||||
expected = "Can not put \"was\" into an operand (OP) argument."
|
||||
|
|
|
@ -96,14 +96,14 @@ describe "Migration from version 0 or nil" do
|
|||
expected = BODY1.dig(0, "args", "message")
|
||||
expect(actual).to eq(expected)
|
||||
expect(seq1.body.dig(0, "args", "message_type")).to eq("info")
|
||||
expect(seq1.args["version"]).to eq(2)
|
||||
expect(seq1.args["version"]).to eq(3)
|
||||
end
|
||||
|
||||
it 'handles `channel` body nodes' do
|
||||
Sequences::Migrate.run!(device: device, sequence: seq2)
|
||||
|
||||
expect(seq2.body.dig(0, "args", "message_type")).to eq("info")
|
||||
expect(seq2.args["version"]).to eq(2)
|
||||
expect(seq2.args["version"]).to eq(3)
|
||||
results = seq2
|
||||
.body
|
||||
.map{|x| x["body"]}
|
||||
|
|
|
@ -1,25 +1,35 @@
|
|||
class Hash
|
||||
def traverse(parent=nil, &blk)
|
||||
each do |k, v|
|
||||
Hash === v ? v.traverse(k, &blk) : blk.call([parent, k, v])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Helpers
|
||||
AST_FIXTURE = File.read("./spec/lib/celery_script/ast_fixture3.json").freeze
|
||||
MAGIC_NUMBER_SEQ_ID = "9999"
|
||||
MAGIC_NUMBER_TOOL_ID = "8888"
|
||||
AST_FIXTURE = File.read("./spec/lib/celery_script/ast_fixture3.json")
|
||||
|
||||
# Create a VALID fake sequence.body for a particular user. Creates a fake
|
||||
# subsequence in the DB when called.
|
||||
def sequence_body_for(input)
|
||||
user ||= FactoryGirl.create(:user)
|
||||
body = JSON.parse(AST_FIXTURE)["body"]
|
||||
case input
|
||||
when User; id = FactoryGirl.create(:sequence, device: user.device).id
|
||||
when Sequence; id = input.id
|
||||
else; raise "?????"
|
||||
def sequence_body_for(mystery)
|
||||
case mystery
|
||||
when User
|
||||
device = user.device
|
||||
when Device
|
||||
device = mystery
|
||||
when Sequence
|
||||
device = mystery.device
|
||||
else
|
||||
raise "No #{mystery.class}"
|
||||
end
|
||||
tool_id = FactoryGirl.create(:tool, device: user.device).id
|
||||
body.map! do |node|
|
||||
has_subseq = node.dig("args", "sub_sequence_id")
|
||||
has_tool = node.dig("args", "location", "args", "tool_id")
|
||||
node["args"]["location"]["args"]["tool_id"] = tool_id if has_tool
|
||||
node["args"]["sub_sequence_id"] = id if has_subseq
|
||||
node
|
||||
end
|
||||
body
|
||||
sid = FactoryGirl.create(:sequence, device: device).id
|
||||
tid = FactoryGirl.create(:tool, device: device).id
|
||||
str = AST_FIXTURE
|
||||
.gsub(MAGIC_NUMBER_SEQ_ID, sid.to_s)
|
||||
.gsub(MAGIC_NUMBER_TOOL_ID, tid.to_s)
|
||||
JSON.parse(str)["body"]
|
||||
end
|
||||
|
||||
def sign_in_as(user)
|
||||
|
|
Loading…
Reference in New Issue