Remove wonky draft API
This commit is contained in:
parent
6c897c5361
commit
eb1b9a9a97
|
@ -4,6 +4,12 @@
|
|||
|
||||
This is a WIP [Pigeon Protocol] client written in Ruby.
|
||||
|
||||
# Caveats
|
||||
|
||||
* Not published to RubyGems yet (see installation instructions below)
|
||||
* Not thread safe. This particular implementation probably never will be. Single user only.
|
||||
* Bundle mechanism works for basic usage, but is extremely ineficient and **does not do anything with blocked identities**.
|
||||
|
||||
# Installation
|
||||
|
||||
We are not yet on Rubygems. The gem will be released after we are fully compliant with the spec and have high test coverage stats.
|
||||
|
|
|
@ -96,7 +96,7 @@ module Pigeon
|
|||
desc "create", "Begin a new Pigeon message"
|
||||
|
||||
def create(kind)
|
||||
puts db.create_draft(kind: kind).render_as_draft
|
||||
puts db.new_draft(kind: kind).render_as_draft
|
||||
end
|
||||
|
||||
desc "append", "Add a key/value pair to the current DRAFT"
|
||||
|
@ -105,7 +105,7 @@ module Pigeon
|
|||
v = (raw_value != "") ? raw_value : STDIN.read
|
||||
draft = db.current_draft
|
||||
if draft
|
||||
puts draft.put(db, key, v)
|
||||
puts db.update_draft(key, v)
|
||||
else
|
||||
bail("You must create a draft first")
|
||||
end
|
||||
|
|
|
@ -169,23 +169,13 @@ module Pigeon
|
|||
draft.signature = author.sign(unsigned)
|
||||
tokens = Lexer.tokenize_unsigned(unsigned, draft.signature)
|
||||
message = Parser.parse(db, tokens)[0]
|
||||
db.discard_draft
|
||||
db.reset_draft
|
||||
message
|
||||
end
|
||||
|
||||
# TODO: This is a wonky API
|
||||
def self.update_draft(db, draft, key, value)
|
||||
raise STRING_KEYS_ONLY unless key.is_a?(String)
|
||||
|
||||
case value[0]
|
||||
when BLOB_SIGIL, MESSAGE_SIGIL, IDENTITY_SIGIL, STRING_SIGIL
|
||||
draft.body[key] = value
|
||||
else
|
||||
# If users passes a string and forgets to append
|
||||
# the string sigil (\"), we add it for them.
|
||||
# This might be a bad or good idea. Not sure yet.
|
||||
draft.body[key] = value.inspect
|
||||
end
|
||||
def self.update_draft(db, key, value)
|
||||
draft = db.current_draft
|
||||
draft[key] = value
|
||||
db.save_draft(draft)
|
||||
return draft.body[key]
|
||||
end
|
||||
|
|
|
@ -33,9 +33,7 @@ module Pigeon
|
|||
end
|
||||
|
||||
def create_message(kind, params)
|
||||
draft = Pigeon::Draft.new(kind: kind, db: self)
|
||||
params.map { |(k, v)| draft.put(self, k, v) }
|
||||
publish_draft(draft)
|
||||
publish_draft(new_draft(kind: kind, body: params))
|
||||
end
|
||||
|
||||
# Store a message that someone (not the LocalIdentity)
|
||||
|
@ -60,9 +58,12 @@ module Pigeon
|
|||
# === DRAFTS
|
||||
def reset_current_draft; set_config(CURRENT_DRAFT, nil); end
|
||||
|
||||
def create_draft(kind:, body: {})
|
||||
draft = Draft.new(kind: kind, body: body, db: self)
|
||||
save_draft(draft)
|
||||
def new_draft(kind:, body: {})
|
||||
old = get_config(CURRENT_DRAFT)
|
||||
if old
|
||||
raise "PUBLISH OR RESET CURRENT DRAFT (#{old.kind}) FIRST"
|
||||
end
|
||||
save_draft(Draft.new(kind: kind, body: body))
|
||||
end
|
||||
|
||||
def save_draft(draft)
|
||||
|
@ -71,15 +72,22 @@ module Pigeon
|
|||
end
|
||||
|
||||
def current_draft
|
||||
store.get_config(CURRENT_DRAFT)
|
||||
draft = store.get_config(CURRENT_DRAFT)
|
||||
if draft
|
||||
return draft
|
||||
else
|
||||
raise "THERE IS NO DRAFT. CREATE ONE FIRST."
|
||||
end
|
||||
end
|
||||
|
||||
def discard_draft
|
||||
def update_draft(k, v); Helpers.update_draft(self, k, v); end
|
||||
|
||||
def reset_draft
|
||||
set_config(CURRENT_DRAFT, nil)
|
||||
end
|
||||
|
||||
# Author a new message.
|
||||
def publish_draft(draft)
|
||||
def publish_draft(draft = self.current_draft)
|
||||
Helpers.publish_draft(self, draft)
|
||||
end
|
||||
|
||||
|
|
|
@ -5,20 +5,31 @@ module Pigeon
|
|||
attr_accessor :signature, :prev, :lipmaa, :kind, :depth,
|
||||
:body, :author
|
||||
|
||||
def initialize(kind:, body: {}, db:)
|
||||
def initialize(kind:, body: {})
|
||||
@signature = Pigeon::NOTHING
|
||||
@prev = Pigeon::NOTHING
|
||||
@kind = kind
|
||||
@depth = -1
|
||||
@body = body
|
||||
@body = {}
|
||||
@author = Pigeon::NOTHING
|
||||
@lipmaa = Pigeon::NOTHING
|
||||
body.to_a.map { |(k, v)| self[k] = v }
|
||||
end
|
||||
|
||||
def [](key)
|
||||
self.body[key]
|
||||
end
|
||||
|
||||
def []=(key, value)
|
||||
raise STRING_KEYS_ONLY unless key.is_a?(String)
|
||||
case value[0]
|
||||
when BLOB_SIGIL, MESSAGE_SIGIL, IDENTITY_SIGIL, STRING_SIGIL
|
||||
body[key] = value
|
||||
else
|
||||
body[key] = value.inspect
|
||||
end
|
||||
end
|
||||
|
||||
def render_as_draft
|
||||
DraftSerializer.new(self).render
|
||||
end
|
||||
|
|
|
@ -79,6 +79,7 @@ module Pigeon
|
|||
all = []
|
||||
depth = -1
|
||||
last = ""
|
||||
# TODO: This loop may become unresponsive.
|
||||
until (last == nil) || (depth > 99999)
|
||||
last = self.get_message_by_depth(author, depth += 1)
|
||||
all.push(last) if last
|
||||
|
|
|
@ -8,11 +8,12 @@ RSpec.describe Pigeon::Draft do
|
|||
end
|
||||
|
||||
let(:message) do
|
||||
message = db.create_draft(kind: "unit_test")
|
||||
hash = db.put_blob(File.read("./logo.png"))
|
||||
message.put(db, "a", "bar")
|
||||
message.put(db, "b", hash)
|
||||
message
|
||||
db.reset_draft
|
||||
db.new_draft(kind: "unit_test")
|
||||
logo = File.read("./logo.png")
|
||||
db.update_draft("a", "bar")
|
||||
db.update_draft("b", db.put_blob(logo))
|
||||
db.current_draft
|
||||
end
|
||||
|
||||
MSG = [
|
||||
|
@ -34,7 +35,8 @@ RSpec.describe Pigeon::Draft do
|
|||
end
|
||||
|
||||
it "creates a new message" do
|
||||
message = db.create_draft(kind: "unit_test")
|
||||
db.reset_draft
|
||||
db.new_draft(kind: "unit_test")
|
||||
hash = db.put_blob(File.read("./logo.png"))
|
||||
expectations = {
|
||||
kind: "unit_test",
|
||||
|
@ -43,8 +45,8 @@ RSpec.describe Pigeon::Draft do
|
|||
"b" => hash,
|
||||
},
|
||||
}
|
||||
message.put(db, "a", "bar")
|
||||
message.put(db, "b", hash)
|
||||
db.update_draft("a", "bar")
|
||||
db.update_draft("b", hash)
|
||||
expect(message["a"]).to eq(expectations.dig(:body, "a"))
|
||||
expect(message["b"]).to eq(expectations.dig(:body, "b"))
|
||||
expect(message.kind).to eq("unit_test")
|
||||
|
|
|
@ -122,9 +122,10 @@ RSpec.describe Pigeon::Lexer do
|
|||
end
|
||||
|
||||
let(:message) do
|
||||
draft = db.create_draft(kind: "unit_test")
|
||||
draft.put(db, "foo", "bar")
|
||||
db.publish_draft(draft)
|
||||
db.reset_draft
|
||||
db.new_draft(kind: "unit_test")
|
||||
db.update_draft("foo", "bar")
|
||||
db.publish_draft
|
||||
end
|
||||
|
||||
it "tokenizes a bundle" do
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
require "spec_helper"
|
||||
|
||||
RSpec.describe Pigeon::Message do
|
||||
def create_draft(params)
|
||||
draft = db.create_draft(kind: "unit_test")
|
||||
params.each { |(k, v)| draft.put(db, k, v) }
|
||||
draft
|
||||
def reset_draft(params)
|
||||
db.reset_draft
|
||||
db.new_draft(kind: "unit_test", body: params)
|
||||
db.current_draft
|
||||
end
|
||||
|
||||
def create_message(params)
|
||||
draft = create_draft(params)
|
||||
draft = reset_draft(params)
|
||||
db.publish_draft(draft)
|
||||
end
|
||||
|
||||
|
@ -20,7 +20,7 @@ RSpec.describe Pigeon::Message do
|
|||
|
||||
let(:draft) do
|
||||
hash = db.put_blob(File.read("./logo.png"))
|
||||
create_draft({ "a" => "bar", "b" => hash })
|
||||
reset_draft({ "a" => "bar", "b" => hash })
|
||||
end
|
||||
|
||||
let(:templated_message) { create_message({ "a" => "b" }) }
|
||||
|
@ -31,7 +31,7 @@ RSpec.describe Pigeon::Message do
|
|||
|
||||
it "discards a draft after signing" do
|
||||
db.publish_draft(draft)
|
||||
expect(db.current_draft).to be(nil)
|
||||
expect { db.current_draft }.to raise_error("THERE IS NO DRAFT. CREATE ONE FIRST.")
|
||||
end
|
||||
|
||||
it "creates a single message" do
|
||||
|
@ -64,9 +64,10 @@ RSpec.describe Pigeon::Message do
|
|||
it "creates a chain of messages" do
|
||||
all = []
|
||||
0.upto(4) do |expected_depth|
|
||||
draft1 = db.create_draft(kind: "unit_test")
|
||||
draft1.put(db, "description", "Message number #{expected_depth}")
|
||||
message = db.publish_draft(draft1)
|
||||
db.reset_draft
|
||||
db.new_draft(kind: "unit_test")
|
||||
db.update_draft("description", "Message number #{expected_depth}")
|
||||
message = db.publish_draft
|
||||
all.push(message)
|
||||
expect(message.depth).to eq(expected_depth)
|
||||
if expected_depth == 0
|
||||
|
@ -78,7 +79,6 @@ RSpec.describe Pigeon::Message do
|
|||
end
|
||||
|
||||
it "verifies accuracy of hash chain" do
|
||||
print "?SLOW?"
|
||||
m1 = create_message({ "a" => "b" })
|
||||
m2 = create_message({ "c" => "d" })
|
||||
m3 = create_message({ "e" => "f" })
|
||||
|
@ -105,7 +105,6 @@ RSpec.describe Pigeon::Message do
|
|||
end
|
||||
|
||||
it "verifies accuracy of signatures" do
|
||||
print "?SLOW?"
|
||||
# === Initial setup
|
||||
secret = db.get_config(Pigeon::SEED_CONFIG_KEY)
|
||||
expect(secret).to be_kind_of(String)
|
||||
|
@ -156,20 +155,21 @@ RSpec.describe Pigeon::Message do
|
|||
WHITESPACE.map do |n|
|
||||
kind = SecureRandom.alphanumeric(8)
|
||||
kind[rand(0...8)] = n
|
||||
draft = db.create_draft(kind: kind)
|
||||
draft.put(db, "body", "empty")
|
||||
boom = ->() { Pigeon::Lexer.tokenize(db.publish_draft(draft).render) }
|
||||
db.reset_draft
|
||||
db.new_draft(kind: kind)
|
||||
boom = ->() { db.publish_draft.render }
|
||||
expect(boom).to raise_error(Pigeon::Lexer::LexError)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not allow whitespace in key names" do
|
||||
WHITESPACE.map do |n|
|
||||
draft = db.create_draft(kind: "unit_test")
|
||||
db.reset_draft
|
||||
db.new_draft(kind: "unit_test")
|
||||
key = SecureRandom.alphanumeric(8)
|
||||
key[rand(0...8)] = n
|
||||
draft.put(db, key, "should crash")
|
||||
boom = ->() { Pigeon::Lexer.tokenize(db.publish_draft(draft).render) }
|
||||
db.update_draft(key, "should crash")
|
||||
boom = ->() { Pigeon::Lexer.tokenize(db.publish_draft.render) }
|
||||
expect(boom).to raise_error(Pigeon::Lexer::LexError)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,9 +3,9 @@ require "pry"
|
|||
|
||||
db = Pigeon::Database.new(path: "my.db")
|
||||
|
||||
db.create_draft
|
||||
db.reset_draft
|
||||
db.current_draft
|
||||
db.discard_draft
|
||||
db.reset_draft
|
||||
db.publish_draft
|
||||
db.save_draft
|
||||
db.save_message
|
||||
|
|
Loading…
Reference in New Issue