(99.44% coverage) TODO: Need to reset current draft when a draft is signed/committed to the log

This commit is contained in:
Netscape Navigator 2020-03-06 08:42:19 -06:00
parent 7568d0412e
commit f4b6ddbf51
9 changed files with 93 additions and 63 deletions

View File

@ -36,5 +36,5 @@ Eg: `pigeon identity show` becomes `./pigeon-cli show`.
- [ ] add parsers and validators for all CLI inputs
- [ ] Performance benchmarks
- [ ] Performance tuning (DO THIS LAST!)
- [ ] Add Lipmaa links like the Bamboo folks do.
- [ ] Update spec to look [like this](https://gist.github.com/RickCarlino/3ff4178db4a75fd135832c403cd313d4)

1
dist/pigeon.rb vendored
View File

@ -32,6 +32,7 @@ module Pigeon
USER_NS = "user"
BLCK_NS = "blocked"
MESG_NS = "messages"
DEPTH_INDEX_NS = "messages.by_depth"
# ^ Internal namespaces for PStore keys

View File

@ -2,62 +2,42 @@ require "digest"
module Pigeon
class Message
attr_reader :author, :kind, :body, :signature
attr_reader :author, :kind, :body, :signature, :depth, :prev
def self.from_draft(draft, author: KeyPair.current)
self.new(author: KeyPair.current,
kind: draft.kind,
body: draft.body).save
end
def initialize(author:, kind:, body: )
@author = author
@kind = kind
@body = body
end
def save
Pigeon::Storage.current.set_config(CURRENT_DRAFT, self)
self
body: draft.body)
end
def sign
store = Pigeon::Storage.current
@signature = calculate_signature
@depth = Pigeon::Storage.current.message_count
@saved = true
@depth = store.message_count
@prev = store.get_message_by_depth(@depth - 1)
self.freeze
Pigeon::Storage.current.save_message(self)
Pigeon::Message.reset_current
@signature
store.save_message(self)
self
end
def render
Template.new(self).render
end
def depth
calculate_depth
end
def prev
if @saved
previous_message
else
raise Pigeon::PREV_REQUIRES_SAVE
end
end
private
def initialize(author:, kind:, body:)
@author = author
@kind = kind
@body = body
# Side effects in a constructor? Hmm...
sign
end
def calculate_signature
template = Template.new(self)
string = template.render_without_signature
KeyPair.current.sign(string)
end
def previous_message
raise "TODO - I need to create a `Pigeon::Index` class or something. " \
"need a way to index messages by: signature, depth"
end
end
end

View File

@ -21,12 +21,12 @@ module Pigeon
private
def do_render(template)
author = message.author
author = message.author.public_key
body = message.body
depth = message.depth
kind = message.kind
depth = message.depth || "NONE"
prev = message.saved? ? message.prev : "NONE"
signature = message.signature || "NONE"
prev = message.prev || "NONE"
signature = message.signature
ERB.new(template).result(binding)
end

View File

@ -11,19 +11,27 @@ module Pigeon
@current ||= self.new
end
# def message_count
# store.transaction do
# store[MESG_NS] ||= {}
# store[MESG_NS].count
# end
# end
def get_message_by_depth(depth)
store.transaction do
# Map<Integer, Signature>
index = store[DEPTH_INDEX_NS] ||= {}
index[depth]
end
end
# def save_message(msg)
# store.transaction do
# store[MESG_NS] ||= {}
# store[MESG_NS][msg.depth || -100] = msg
# end
# end
def message_count
store.transaction do
index = store[MESG_NS] ||= {}
index.count
end
end
def save_message(msg)
store.transaction do
store[MESG_NS] ||= {}
store[MESG_NS][msg.signature] = msg
end
end
def set_config(key, value)
store.transaction do

View File

@ -97,7 +97,7 @@ module Pigeon
desc "sign", "Commit current DRAFT to local feed."
def sign
puts Pigeon::Draft.current.sign.render
raise "Work in progress! under_construction.gif"
end
end

View File

@ -1,9 +0,0 @@
BEFORE DELETING CONSTANTS:
==========================
rspec ./spec/pigeon/kitchen_sink_spec.rb:4 # Kitch sink spec does everything
rspec ./spec/pigeon/storage_spec.rb:15 # Pigeon::Storage deletes a config
rspec ./spec/pigeon/storage_spec.rb:34 # Pigeon::Storage manages blobs
rspec ./spec/pigeon/storage_spec.rb:41 # Pigeon::Storage manages peers
rspec ./spec/pigeon/storage_spec.rb:26 # Pigeon::Storage manages configs
rspec ./spec/pigeon/key_pair_spec.rb:36 # Pigeon::KeyPair saves to disk

View File

@ -0,0 +1,44 @@
require "spec_helper"
RSpec.describe Pigeon::Message do
before(:each) do
Pigeon::Storage.reset
Pigeon::KeyPair.reset
end
let(:draft) do
draft = Pigeon::Draft.create(kind: "unit_test")
hash = Pigeon::Storage.current.set_blob(File.read("./logo.png"))
draft["a"] = "bar"
draft["b"] = hash
draft
end
it "creates a single message" do
message = Pigeon::Message.from_draft(draft)
expect(message.author).to eq(Pigeon::KeyPair.current)
expect(message.body).to eq(draft.body)
expect(message.depth).to eq(0)
expect(message.kind).to eq("unit_test")
expect(message.prev).to eq(nil)
expect(message.signature.include?(".sig.ed25519")).to eq(true)
expect(message.signature.length).to be > 99
actual = message.render
expected = [
"author __AUTHOR__",
"kind unit_test",
"prev NONE",
"depth 0",
"",
"a:\"bar\"",
"b:&6462a5f5174b53702fc25afe67a8f9a29f572610a65bafefff627531552f096f.sha256",
"",
"signature __SIGNATURE__ \n",
].join("\n")
.gsub("__AUTHOR__", message.author.public_key)
.gsub("__SIGNATURE__", message.signature)
expect(actual).to eq(expected)
end
it "creates a chain of messages"
end

View File

@ -11,8 +11,14 @@ RSpec.describe Pigeon::Template do
BOTTOM_HALF = "signature XYZ.sig.sha256 \n"
EXPECTED_DRAFT = TOP_HALF + BOTTOM_HALF
class FakeKeypair
def self.public_key
"FAKE_AUTHOR"
end
end
it "renders a draft" do
args = ["FAKE_AUTHOR",
args = [FakeKeypair,
{ foo: "bar".inspect },
"FAKE_KIND",
23,