forked from ghaskins/clojure-protobuf
-
Notifications
You must be signed in to change notification settings - Fork 8
Open
Description
Hey folks, I am evaluating this and testing some simple scenarios of mutation. What I am trying to test is:
- creating a proto object
- mutate in some Clojure map-related API (that is allowed by the schema)
- serialize to bytes
- deserialize and see that the mutation actually worked:
now, given this schema:
syntax = "proto2";
package clojure_protobuf_poc.core.person;
option java_outer_classname = "PersonProto";
message Name {
optional string name = 1;
optional string surname = 2;
}
message Person {
optional int32 id = 1;
optional Name name = 2;
optional string email = 3;
repeated string likes = 4;
}and this test code:
(ns clojure-protobuf-poc.core-test
(:require [clojure.test :refer [testing deftest is]]
[protobuf.core :as protobuf])
(:import [clojure_protobuf_poc.core.person PersonProto$Name PersonProto$Person]
[protobuf.impl.flatland.core FlatlandProtoBuf]))
(defn bytes->Person [person-bytes]
(protobuf/bytes-> (protobuf/create PersonProto$Person) person-bytes))
(defn mutate->round-trip [pb f]
(let [mutated (f pb)]
(is (= FlatlandProtoBuf (type mutated)))
(-> mutated
protobuf/->bytes
bytes->Person)))
(deftest mutation
(let [alice-name (protobuf/create PersonProto$Name {:name "Alice" :surname "Cohen"})
alice (protobuf/create PersonProto$Person {:id 108 :name alice-name :email "[email protected]"})]
(println alice)
(testing "no mutation"
(let [alice-tag (mutate->round-trip alice identity)]
(is (= alice-tag alice))))
(testing "dissoc"
(let [no-id (mutate->round-trip alice #(dissoc % :id))]
(is (= nil (:id no-id)))))
(testing "assoc-in"
(let [new-surname (mutate->round-trip alice #(assoc-in % [:name :surname] "Levi"))]
(is (= "Levi" (get-in new-surname [:name :surname])))))
(testing "update-in"
(let [no-surname (mutate->round-trip alice #(update-in % [:name] dissoc :surname))]
(is (= nil (get-in no-surname [:name :surname]))))) ; fails-> we get "Cohen"
(testing "assoc"
(let [new-email1 (mutate->round-trip alice #(assoc % :email "new-email"))]
(is (= "new-email" (:email new-email1)))))
(testing "merge"
; crashes cause after the merge we get java.lang.IllegalArgumentException: No implementation of
; method: :->bytes of protocol: #'protobuf.core/ProtoBufAPI
; found for class: protobuf.PersistentProtocolBufferMap
(let [new-email2 (mutate->round-trip alice #(merge % {:email "new-email"}))]
(is (= "new-email" (:email new-email2)))))))tests fail with:
FAIL in (mutation) (core_test.clj:31)
update-in
expected: nil
actual: "Cohen"
diff: + "Cohen"
lein test :only clojure-protobuf-poc.core-test/mutation
FAIL in (mutation) (core_test.clj:12)
merge
expected: protobuf.impl.flatland.core.FlatlandProtoBuf
actual: protobuf.PersistentProtocolBufferMap
diff: - protobuf.impl.flatland.core.FlatlandProtoBuf
+ protobuf.PersistentProtocolBufferMap
lein test :only clojure-protobuf-poc.core-test/mutation
ERROR in (mutation) (core_deftype.clj:583)
Uncaught exception, not in assertion.
expected: nil
actual: java.lang.IllegalArgumentException: No implementation of method: :->bytes of protocol: #'protobuf.core/ProtoBufAPI found for class: protobuf.PersistentProtocolBufferMap
at clojure.core$_cache_protocol_fn.invokeStatic (core_deftype.clj:583)
...
...
Can you explain why update-in and merge aren't supported and what I (probably) have done wrong?
Thanks!
Maybe, put differently, it looks like PersistentProtocolBufferMap isn't 100% compatible with a Clojure map:
- Is that correct?
- If so, should I strive to convert it into a Clojure map? What is the fastest way to do so (recursively)?
fr33m0nk, sskorokhodov and pratik97
Metadata
Metadata
Assignees
Labels
No labels