Skip to content

mutating protobuf.impl.flatland.core.FlatlandProtoBufΒ #41

@barkanido

Description

@barkanido

Hey folks, I am evaluating this and testing some simple scenarios of mutation. What I am trying to test is:

  1. creating a proto object
  2. mutate in some Clojure map-related API (that is allowed by the schema)
  3. serialize to bytes
  4. 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:

  1. Is that correct?
  2. If so, should I strive to convert it into a Clojure map? What is the fastest way to do so (recursively)?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions