sequel-protobuf 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTVjMDc0ODk3ZGE3Mzk5MjU3YmFjYzM2OWE2OGRmYWRlOTlmN2YzNA==
5
+ data.tar.gz: !binary |-
6
+ MmI0YmE0ODFjNTUzNDc4MWQyMzcwNjlhNGVjNGUyYWI4MjMyZDU0MA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ N2Q4N2Y2YzgyYmZiNDE4YTRkMjk0NGIzYzcyYzQ0MDA5YWMxOTY2ZmM3OTk4
10
+ NDQ4YjYzMmUxYjg1Mzk0YjBhMWFiOThhODY2OTZiMTM2MDI2MWIzNDBkNzhj
11
+ ZDk0OGNmZmRmY2FlMDgzOTRjM2MwMzcxNzVlMGIwOWYxYTgzZTA=
12
+ data.tar.gz: !binary |-
13
+ OGE0MzcwMDdhMmM3MGM3ZjU1MGRkOTVhMjE0NjU3Njg2NTc3MTA3ZGYxNmQ3
14
+ MGIxYjlkM2FiZDdlMDk2ZWU1MjY3OTE5YjFhNDIzNDBkMTM4YTQ0ZTRjY2Mz
15
+ N2JlNmFjMmQ3M2VkNDQ5YjYwNTc4OTIwZjVjMGU4YTJjYjI1OGU=
@@ -0,0 +1,5 @@
1
+ coverage
2
+ Gemfile.lock
3
+ *.gem
4
+ doc
5
+ .yardoc
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rake'
4
+ gem 'sequel'
5
+
6
+ group :development, :test do
7
+ gem 'minitest'
8
+ gem 'simplecov'
9
+ gem 'mocha'
10
+ gem 'yard'
11
+ gem 'redcarpet'
12
+
13
+ gem 'ruby-protocol-buffers'
14
+ end
@@ -0,0 +1,95 @@
1
+ #sequel-protobuf
2
+ [![Build Status](https://drone.io/github.com/kellydunn/sequel-protobuf/status.png)](https://drone.io/github.com/kellydunn/sequel-protobuf/latest)
3
+
4
+ ##what
5
+
6
+ A plugin for the `sequel` database library that enables `Sequel::Model` classes to be serialized into protocol buffers.
7
+
8
+ ##documentation
9
+
10
+ Documentation can be found [here](http://rubydoc.info/github/kellydunn/sequel-protobuf/master/frames).
11
+
12
+ ##installation
13
+
14
+ There is an intent to have this gem available through rubygems eventually, but for now, it's easiest to require the gem through `bundler` by specifying it in your `Gemfile`:
15
+
16
+ **Gemfile**
17
+ ```
18
+ gem 'sequel-protobuf', :git => "git@github.com/kellydunn/sequel-protobuf"
19
+ ```
20
+
21
+ ##usage
22
+
23
+ In your `Sequel::Model` definition, require `sequel`, `sequel-protobuf`, a protocol buffer utility library of your choice (like `ruby-protocol-buffers`), and the corresponding protocol buffer model definition (the `.pb.rb` file that `ruby-protoc` generates). Next, specify that you want your `Sequel::Model` class to use the `protobuf` plugin along with the class name of the protobuf model definition, like so:
24
+
25
+ ```
26
+ require 'sequel'
27
+ require 'sequel/plugins/protobuf'
28
+ require 'protocol_buffers'
29
+ require 'your/protocol/buffer/definitions/my_model_definition'
30
+
31
+ class MyModel < Sequel::Model
32
+ plugin :protobuf, :model => MyModelDefinition
33
+ end
34
+ ```
35
+
36
+ Now you can create a new instance of your record, and call `to_protobuf` or `from_protobuf` on it!
37
+
38
+ Simple `Sequel::Dataset` operations will also work as well!
39
+
40
+ ```
41
+ 5.times do
42
+ MyModel.create()
43
+ end
44
+
45
+ result = MyModel.all.to_protobuf
46
+ # result is an array of protocol buffer representations of each instance of {MyModel}!
47
+ ```
48
+
49
+ ##configuration
50
+
51
+ As of `0.2.0`, `sequel-protobuf` provides the ability to render nested protocol buffer models, re-format data-types on demand, and override default protocol buffer definitions while rendering. To do this, you may supply an options hash to the `to_protobuf` and `as_protobuf` methods with any of the following keys:
52
+
53
+ - `:include`: specifies nested protocol buffer models to render
54
+ - `:as`: specifies a different protocol buffer model definition in which to render the current object as
55
+ - `:coerce`: specifies how to re-format a specific data column of the current `Sequel::Model` such that it can fit your protocol buffer definition.
56
+
57
+ ###Example
58
+ ```
59
+ require 'sequel'
60
+ require 'sequel/plugins/protobuf'
61
+ require 'protocol_buffers'
62
+ require 'your/protocol/buffer/definitions/my_model_definition'
63
+
64
+ class MyModel < Sequel::Model
65
+ plugin :protobuf, :model => MyModelDefinition
66
+ one_to_many :nested
67
+
68
+ def app_specific_as_protobuf
69
+ config = {
70
+ :as => DifferentModelDefinition,
71
+ :include => {
72
+ :nested => {}
73
+ }
74
+ :coerce => {
75
+ # We coerce the creatd_at time since Protocol Buffers
76
+ # do not support Time types by default.
77
+ # The reccomended approach is to set the unix timestamp value
78
+ # as a int64 type.
79
+ :created_at => Proc.new { |created_at|
80
+ created_at.utc.to_i
81
+ }
82
+ }
83
+ }
84
+
85
+ return self.as_protobuf(config)
86
+ end
87
+ end
88
+ ```
89
+
90
+ ##considerations
91
+
92
+ - This library currently only supports `ruby-protocol-buffers` as a serialization driver. If you are interested in adding additional driver support, feel free to open a Pull Request!
93
+
94
+ [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/kellydunn/sequel-protobuf/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
95
+
@@ -0,0 +1,7 @@
1
+ desc "Run tests"
2
+ task :test do
3
+ puts `ruby -I lib test/test_helper.rb`
4
+ end
5
+
6
+ desc "Default task: Runs tests"
7
+ task :default => :test
@@ -0,0 +1,195 @@
1
+ require 'sequel/plugins/protobuf/drivers'
2
+
3
+ # This module contains all functionality for the Sequel library.
4
+ module Sequel
5
+
6
+ # This module contains all Sequel plugin definitions.
7
+ module Plugins
8
+
9
+ # This module defines the Protobuf plugin for the Sequel database library
10
+ module Protobuf
11
+
12
+ # This error message indicates that a {Sequel::Model} definition
13
+ # that has been required by the client is missing a protobuf model definition.
14
+ class MissingProtobufDefinitionError < StandardError
15
+
16
+ # Creates a new instance of {Sequel::Plugins::Protobuf::MissingProtobufDefinitionError}
17
+ def initialize
18
+ super("Protobuf model definition was not specified.")
19
+ end
20
+ end
21
+
22
+ # This constant lists all of the current compatible drivers in sequel-protobuf
23
+ DRIVERS = {
24
+ :ruby_protocol_buffers => Sequel::Plugins::Protobuf::Drivers::RubyProtocolBuffers
25
+ }
26
+
27
+ # This constant defines the default driver for sequel-protobuf
28
+ # If clients do not specify a driver, sequel-protobuf assumes they
29
+ # will use this gem.
30
+ DEFAULT_DRIVER = :ruby_protocol_buffers
31
+
32
+ # Initializes the sequel-protobuf the first time it is registered for a class.
33
+ #
34
+ # @param model {Sequel::Model}. The {Sequel::Model} in which to register the plugin.
35
+ # @param options {Hash}. A configuration hash that is used to help configure the application.
36
+ def self.apply(model, options={})
37
+ # TODO no-op
38
+ end
39
+
40
+ # Initializes the sequel-protobuf plugin for the passed in model
41
+ # with the passed in options
42
+ #
43
+ # @param model {Sequel::Model}. The {Sequel::Model} in which to register the plugin
44
+ # @param options {Hash}. A configuration hash to configure the plugin
45
+ def self.configure(model, options = {})
46
+ model.instance_eval {
47
+ if !options[:model]
48
+ raise Sequel::Plugins::Protobuf::MissingProtobufDefinitionError.new
49
+ else
50
+ @protobuf_model = options[:model]
51
+ end
52
+
53
+ driver = options[:driver] ? options[:driver] : DEFAULT_DRIVER
54
+ @protobuf_driver = DRIVERS[driver]
55
+ }
56
+ end
57
+
58
+ # When mixed in, this module provides the ability for objects
59
+ # to be serialized from protocol buffer strings
60
+ module ClassMethods
61
+ attr_reader :protobuf_driver, :protobuf_model
62
+
63
+ # Creates and returns a new instance of the current class
64
+ # from the passed in protobuf message
65
+ #
66
+ # @param protobuf {String}. The protobuf message to parse.
67
+ # @param options {Hash}. An options hash that will configure the parsing.
68
+ def from_protobuf(protobuf, options = {})
69
+ pb_model = @protobuf_driver.parse(@protobuf_model, protobuf, options)
70
+
71
+ # Coerce data from protobuf array to a new model
72
+ model = self.send(:new)
73
+ model.columns.each do |v|
74
+ if pb_model.respond_to?("#{v}=".to_sym)
75
+ model.send("#{v}=", pb_model.send(v.to_sym))
76
+ end
77
+ end
78
+
79
+ return model
80
+ end
81
+ end
82
+
83
+ # When mixed in, this module provides various instance-level methods that
84
+ # allow sequel models to be rendered into protocol buffers
85
+ # or rendered into a driver-specific model
86
+ module InstanceMethods
87
+
88
+ # Renders the current instance of the model to a protocol buffer message
89
+ # as it is defined in the configured protocol buffer model definition.
90
+ #
91
+ # @param options {Hash}. An options hash that is used to configure how
92
+ # the rendering is performed.
93
+ # @return {String}. A protocol buffer representation of the current {Sequel::Model} instance.
94
+ def to_protobuf(options = {})
95
+ return self.render(self, options).to_s
96
+ end
97
+
98
+ # Renders the current instance of the model to an instance of {::ProtocolBuffers::Message}.
99
+ #
100
+ # @param options {Hash}. An options hash that is used to configure how
101
+ # The rendering is performed.
102
+ # @return {Object}. A representation of the model as an instance of the protocol_buffer model class
103
+ # configured at the instance level.
104
+ def as_protobuf(options = {})
105
+ return self.render(self, options)
106
+ end
107
+
108
+ # Renders the passed in key ans the corresponding protocol buffer model.
109
+ # The passed in options specifies how to do this with the following rules:
110
+ # - `:include` This key specifies that the current protocol buffer model has a nested
111
+ # Protocol buffer model to be rendered inside of it.
112
+ # - `:coerce` This key specifies that the current model can override a specific data
113
+ # value of a particular database column. This is useful fo re-formatting
114
+ # data from your db schema so that they adhere to your protocol
115
+ # buffer definitions.
116
+ # - `:as` This key specifies a different protocol buffer model to render the
117
+ # current object.
118
+ #
119
+ # @param current {Object}. The current seciton of the schema to render.
120
+ # @param options {Hash}. An options hash to configure how to render the current object.
121
+ def render(current, options={})
122
+
123
+ # If the current element in the schema is an array,
124
+ # then we need to render them in sequence and return the result.
125
+ if current.is_a?(Array)
126
+ collection = current.inject([]) do |acc, element|
127
+ acc << render(element, options)
128
+ acc
129
+ end
130
+
131
+ return collection
132
+
133
+ # Otherwise, if the record isn't nil,
134
+ # we get the current values of the object and process them accordingly.
135
+ elsif !current.nil?
136
+ values = current.values.dup
137
+
138
+ # If the options do not specifiy a protobuf model, assume the one configured earlier
139
+ if options.has_key?(:as)
140
+ model = options[:as]
141
+ else
142
+ model = current.class.protobuf_model
143
+ end
144
+
145
+ options.each do |k, v|
146
+
147
+ # If the current key is "include", then recursively render the model specified
148
+ if k == :include
149
+ v.each do |model, opts|
150
+ values.merge!({model => render(current.send(model.to_sym), opts)})
151
+ end
152
+
153
+ # If the current key is "coerce", then call the corresponding proc
154
+ # for the desired attribute
155
+ elsif k == :coerce
156
+ v.each do |value, proc|
157
+ values[value] = proc.call(values[value])
158
+ end
159
+ end
160
+ end
161
+
162
+ # Finally, return the result of creating a new protobuf model
163
+ return current.class.protobuf_driver.create(model, values)
164
+ end
165
+ end
166
+
167
+ end
168
+
169
+ # When mixed in, this module provides the ability for Sequel datasets to
170
+ # call `to_protobuf`, which will return an array of serialized protobuf strings.
171
+ module DatasetMethods
172
+
173
+ # Renders the current dataset of the model into a collection of
174
+ # protocol buffer messages as they are defined in the configured
175
+ # protocol buffer model definition.
176
+ #
177
+ # @param options {Hash}. An options hash that is used to configure how
178
+ # the rendering is preformed.
179
+ # @return {Array}. An array of protocol buffer messages. Each element
180
+ # In the array is a serialized version of the corresponding
181
+ # object in the original dataset.
182
+ def to_protobuf(options = {})
183
+
184
+ res = self.all.inject([]) do |acc, obj|
185
+ acc << obj.to_protobuf(options)
186
+ acc
187
+ end
188
+
189
+ return res
190
+
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1 @@
1
+ require 'sequel/plugins/protobuf/drivers/ruby-protocol-buffers-driver'
@@ -0,0 +1,64 @@
1
+ module Sequel
2
+ module Plugins
3
+ module Protobuf
4
+
5
+ # This module contains all the driver definitions for the sequel-protobuf gem.
6
+ module Drivers
7
+
8
+ # This driver definition provides a standard interface
9
+ # for protocol buffer serialization with the `ruby-protocol-buffers` gem.
10
+ module RubyProtocolBuffers
11
+
12
+ # Parses the passed in protobuf message into
13
+ # an instance of the corresponding protocol buffer model definition
14
+ #
15
+ # @param protobuf_model {Object}. The class of the protocol buffer definition
16
+ # @param protobuf {String}. The protocol buffer message to be parsed
17
+ # @param options {Hash}. An options hash to help configure the parsing functionality.
18
+ def self.parse(protobuf_model, protobuf, options = {})
19
+ return protobuf_model.send(:parse, protobuf)
20
+ end
21
+
22
+ # Serializes the passed in attributes hash into an instance of the passed in
23
+ # protocol buffer model definition.
24
+ #
25
+ # @param protobuf_model {Object}. The class of the protocol buffer definition
26
+ # @param attributes {Hash}. The attributes in which to be serialized into a protocol buffer message
27
+ # @param options {Hash}. An options hash to help configure the serialization funcitonality.
28
+ # @return {::ProtocolBuffers::Message}. A newly created protocol buffer message
29
+ def self.serialize(protobuf_model, attributes, options = {})
30
+ return self.create(protobuf_model, attributes, options).to_s
31
+ end
32
+
33
+ # Creates and returns a new instance of the specified protobuf model
34
+ # initialized with the passed in attributes and configured by the passed in optoins.
35
+ #
36
+ # @param protobuf_model {Object}. The protobuf model in which to render.
37
+ # @param attributes {Hash}. A hash of attributes in which to create the new protobuf model
38
+ # @param options {Hash}. A configuration hash in which to configure the creation of the
39
+ # New protocol buffer object.
40
+ # @return {::ProtocolBuffers::Message}. A newly created protocol buffer message.
41
+ def self.create(protobuf_model, attributes, options = {})
42
+ fields = protobuf_model.fields.inject([]) do |acc, (k, v)|
43
+ acc << v.name
44
+ acc
45
+ end
46
+
47
+ attributes = attributes.inject({}) do |acc, (k, v)|
48
+ if fields.include?(k)
49
+ acc[k] = v
50
+ end
51
+
52
+ acc
53
+ end
54
+
55
+ return protobuf_model.send(:new, attributes)
56
+
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,12 @@
1
+ module Sequel
2
+ module Plugins
3
+ module Protobuf
4
+
5
+ # This constant describes the current version of the sequel-protobuf gem
6
+ # It currently makes use of the semantic-versioning specification.
7
+ # To learn more about semantic verisoning, visit http://semver.org/
8
+ VERSION="0.2.2"
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path("../lib/sequel/plugins/protobuf/version.rb", __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = ["kellydunn"]
5
+ gem.email = ["defaultstring+sequel-protobuf@gmail.com"]
6
+ gem.description = %q{Sequel plugin for protocol buffer serialization}
7
+ gem.summary = %q{Sequel plugin for protocol buffer serialization}
8
+ gem.homepage = 'http://github.com/kellydunn/sequel-protobuf'
9
+
10
+ gem.files = `git ls-files`.split($\)
11
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
12
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
13
+ gem.name = 'sequel-protobuf'
14
+ gem.require_paths = ['lib']
15
+ gem.version = Sequel::Plugins::Protobuf::VERSION
16
+ end
@@ -0,0 +1,6 @@
1
+ require 'sequel'
2
+ require 'sequel/plugins/protobuf'
3
+
4
+ class DefinitionErrorSequelModel < Sequel::Model
5
+ plugin :protobuf
6
+ end
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+
4
+ require 'protocol_buffers'
5
+
6
+ module Test
7
+ # forward declarations
8
+ class MyMessage < ::ProtocolBuffers::Message; end
9
+ class MyMessageWithNested < ::ProtocolBuffers::Message; end
10
+ class Nested < ::ProtocolBuffers::Message; end
11
+
12
+ class MyMessage < ::ProtocolBuffers::Message
13
+ set_fully_qualified_name "Test.MyMessage"
14
+
15
+ required :int64, :id, 1
16
+ optional :string, :myField, 2
17
+ end
18
+
19
+ class MyMessageWithNested < ::ProtocolBuffers::Message
20
+ set_fully_qualified_name "Test.MyMessageWithNested"
21
+
22
+ required :int64, :id, 1
23
+ optional :string, :myField, 2
24
+ repeated ::Test::Nested, :nested, 3
25
+ end
26
+
27
+ class Nested < ::ProtocolBuffers::Message
28
+ set_fully_qualified_name "Test.Nested"
29
+
30
+ required :int64, :id, 1
31
+ optional :string, :nestedField, 2
32
+ end
33
+
34
+ end
@@ -0,0 +1,17 @@
1
+ package Test;
2
+
3
+ message MyMessage {
4
+ required int64 id = 1;
5
+ optional string myField = 2;
6
+ }
7
+
8
+ message MyMessageWithNested {
9
+ required int64 id = 1;
10
+ optional string myField = 2;
11
+ repeated Nested nested = 3;
12
+ }
13
+
14
+ message Nested {
15
+ required int64 id = 1;
16
+ optional string nestedField = 2;
17
+ }
@@ -0,0 +1,8 @@
1
+ require 'sequel'
2
+ require 'sequel/plugins/protobuf'
3
+ require 'test/helpers/nested_sequel_model'
4
+
5
+ class MyMessageSequelModel < Sequel::Model
6
+ plugin :protobuf, :model => ::Test::MyMessage
7
+ one_to_many :nested, :class => NestedSequelModel
8
+ end
@@ -0,0 +1,6 @@
1
+ require 'sequel'
2
+ require 'sequel/plugins/protobuf'
3
+
4
+ class NestedSequelModel < Sequel::Model
5
+ plugin :protobuf, :model => ::Test::Nested
6
+ end
@@ -0,0 +1,62 @@
1
+ require 'sequel/plugins/protobuf/drivers/ruby-protocol-buffers-driver'
2
+
3
+ class RubyProtocolBuffersDriverTest < Minitest::Test
4
+ # Ensures that a protocol buffer defition can be serailized as expected
5
+ # with ruby-protocol-buffers as the driver
6
+ def test_serialize
7
+ d = Sequel::Plugins::Protobuf::DRIVERS[:ruby_protocol_buffers]
8
+ res = d.serialize(::Test::MyMessage, {:id => 1, :myField => "test"})
9
+ assert_equal("\b\x01\x12\x04test", res)
10
+ end
11
+
12
+ # Ensures that the return type of the create method is that of the passed in protobuf model
13
+ def test_create
14
+ d = Sequel::Plugins::Protobuf::DRIVERS[:ruby_protocol_buffers]
15
+ res = d.create(::Test::MyMessage, {:id => 1, :myField => "test"})
16
+ assert_equal(res.class, ::Test::MyMessage)
17
+ end
18
+
19
+ # Ensures that result of serialize can read with the driver's call to `parse`
20
+ # Also ensures that a successful parse will result in a new protobuf model
21
+ # with the expected fields
22
+ def test_parse
23
+ d = Sequel::Plugins::Protobuf::DRIVERS[:ruby_protocol_buffers]
24
+ msg = ::Test::MyMessage.new({:id => 1, :myField => "test"})
25
+ res = d.serialize(::Test::MyMessage, {:id => 1, :myField => "test"})
26
+ res2 = d.parse(::Test::MyMessage, res)
27
+ assert_equal(msg, res2)
28
+ assert_equal(res2.myField, "test")
29
+ end
30
+
31
+ # Ensures that passing an attributes hash that is mismatched with the
32
+ # Protobuf definition will be coerced into an acceptable attributes hash
33
+ # such that it can be serialized as defined
34
+ def test_serialize_with_mismatched_attributes
35
+ e = nil
36
+ begin
37
+ d = Sequel::Plugins::Protobuf::DRIVERS[:ruby_protocol_buffers]
38
+ res = d.serialize(::Test::MyMessage, {:id => 1, :myField => "test", :garbage => "garbage_data"})
39
+ assert_equal("\b\x01\x12\x04test", res)
40
+ rescue ::Exception => e
41
+ # No-op
42
+ end
43
+
44
+ assert e.nil?, "We should not encounter an error when attempting to serialize a model with mismatched attributes"
45
+ end
46
+
47
+ # Ensures that we do encounter an error when an insufficent attributes hash
48
+ # Is passed to a call to serialization
49
+ def test_serialize_with_mismatched_attributes_error
50
+ e = nil
51
+ begin
52
+ d = Sequel::Plugins::Protobuf::DRIVERS[:ruby_protocol_buffers]
53
+ res = d.serialize(::Test::MyMessage, {})
54
+ rescue ::Exception => e
55
+ # No-op
56
+ end
57
+
58
+ assert !e.nil?, "We should encounter an error when attempting to serialize a model with insufficient attributes"
59
+ assert_equal e.class, ::ProtocolBuffers::EncodeError
60
+ end
61
+
62
+ end
@@ -0,0 +1,135 @@
1
+ $LOAD_PATH.unshift(".")
2
+
3
+ require 'sequel/plugins/protobuf'
4
+
5
+ class ProtobufTest < Minitest::Test
6
+ def test_mixin
7
+ require 'test/helpers/my_message_sequel_model'
8
+
9
+ m = MyMessageSequelModel.create
10
+ assert m.respond_to?(:to_protobuf), "A new sequel model should respond to `to_protobuf`"
11
+ assert m.class.respond_to?(:from_protobuf), "The class of a new sequel model should respond to `from_protobuf`"
12
+ end
13
+
14
+ def test_mixin_error
15
+ begin
16
+ require 'test/helpers/definition_error_sequel_model'
17
+ rescue Exception => e
18
+ assert_equal e.class, Sequel::Plugins::Protobuf::MissingProtobufDefinitionError
19
+ assert_equal e.to_s, "Protobuf model definition was not specified."
20
+ end
21
+ end
22
+
23
+ def test_to_protobuf
24
+ require 'test/helpers/my_message_sequel_model'
25
+
26
+ m = MyMessageSequelModel.create({:myField => "test"})
27
+ res = m.to_protobuf
28
+
29
+ assert_equal res, "\b\x01\x12\x04test"
30
+ end
31
+
32
+ def test_from_protobuf
33
+ require 'test/helpers/my_message_sequel_model'
34
+
35
+ m = MyMessageSequelModel.from_protobuf("\b\x01\x12\x04test")
36
+
37
+ assert_equal m.id, 1
38
+ assert_equal m.myField, "test"
39
+ assert_equal m.class, MyMessageSequelModel
40
+ end
41
+
42
+ def test_as_protobuf
43
+ require 'test/helpers/my_message_sequel_model'
44
+
45
+ attributes = {:myField => "test", :extraField => "extra"}
46
+ m = MyMessageSequelModel.create(attributes)
47
+ proto = m.as_protobuf
48
+
49
+ attributes.delete(:extraField)
50
+ expected = attributes.merge({:id => m.id})
51
+
52
+ res = proto.fields.inject([]) do |acc, (k, v)|
53
+ acc << v.name
54
+ acc
55
+ end
56
+
57
+ assert_equal 1, proto.id
58
+ assert_equal "test", proto.myField
59
+ assert !proto.respond_to?(:extraField), "Expects protobuf model to not respond to a field that is not defined"
60
+ end
61
+
62
+ def test_dataset_to_protobuf
63
+ require 'test/helpers/my_message_sequel_model'
64
+
65
+ m = MyMessageSequelModel.create({:myField => "test"})
66
+ collection = MyMessageSequelModel.where(:myField => "test")
67
+
68
+ res = collection.to_protobuf
69
+
70
+ assert_equal(res.length, 1)
71
+ assert_equal(res[0], "\b\x01\x12\x04test")
72
+ end
73
+
74
+ def test_to_protobuf_nested_model
75
+ require 'test/helpers/my_message_sequel_model'
76
+ require 'test/helpers/nested_sequel_model'
77
+
78
+ m = MyMessageSequelModel.create({:myField => "test"})
79
+ m2 = NestedSequelModel.create({:my_message_id => m.id, :nestedField => "test-nested"})
80
+
81
+ m.reload
82
+ res = m.to_protobuf({
83
+ :as => ::Test::MyMessageWithNested,
84
+ :include => {
85
+ :nested => {
86
+ :as => ::Test::Nested
87
+ }
88
+ }
89
+ })
90
+
91
+ assert_equal(res, "\b\x01\x12\x04test\x1A\x0F\b\x01\x12\vtest-nested")
92
+
93
+ end
94
+
95
+ def test_to_protobuf_with_coerced_keys
96
+ require 'test/helpers/my_message_sequel_model'
97
+ require 'test/helpers/nested_sequel_model'
98
+
99
+ m = MyMessageSequelModel.create({:myField => "test"})
100
+ m.reload
101
+
102
+ res = m.to_protobuf({
103
+ :coerce => {
104
+ :myField => Proc.new { |value|
105
+ "#{value}-coerced"
106
+ }
107
+ }
108
+ })
109
+
110
+ assert_equal("\b\x01\x12\ftest-coerced", res)
111
+
112
+ end
113
+
114
+ # Ensures that coercing the values of a sequel model
115
+ # does not mutate the values hash of that particular instance.
116
+ def test_values_retention_after_rendering_with_coercion
117
+ require 'test/helpers/my_message_sequel_model'
118
+ require 'test/helpers/nested_sequel_model'
119
+
120
+ m = MyMessageSequelModel.create({:myField => "test"})
121
+ m.reload
122
+
123
+ res = m.to_protobuf({
124
+ :coerce => {
125
+ :myField => Proc.new { |value|
126
+ "#{value}-coerced"
127
+ }
128
+ }
129
+ })
130
+
131
+ assert_equal("\b\x01\x12\ftest-coerced", res)
132
+ assert_equal("test", m.values[:myField])
133
+ end
134
+
135
+ end
@@ -0,0 +1,32 @@
1
+ $LOAD_PATH.unshift(File.expand_path("../lib", __FILE__))
2
+
3
+ # Simplecov needs to be required before test/unit
4
+ # in order for the test suite runner to be tracked during code-coverage generation
5
+ require 'simplecov'
6
+ SimpleCov.start
7
+
8
+ require 'minitest'
9
+ require 'minitest/autorun'
10
+ require 'mocha/setup'
11
+ require 'sequel'
12
+
13
+ Sequel.mock(:fetch => [{ :id => 1,
14
+ :myField => "test",
15
+ :extraField => "extra",
16
+ :nestedField => "test-nested"}],
17
+
18
+ :columns => [:id,
19
+ :myField,
20
+ :extraField,
21
+ :my_message_id,
22
+ :nestedField])
23
+
24
+ # Require all protobuf definitions
25
+ Dir["**/*.pb.rb"].each do |f|
26
+ require File.absolute_path(f)
27
+ end
28
+
29
+ # Require unit tests
30
+ Dir["**/*_test.rb"].each do |f|
31
+ require File.absolute_path(f)
32
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel-protobuf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - kellydunn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-26 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Sequel plugin for protocol buffer serialization
14
+ email:
15
+ - defaultstring+sequel-protobuf@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - .gitignore
21
+ - Gemfile
22
+ - README.md
23
+ - Rakefile
24
+ - lib/sequel/plugins/protobuf.rb
25
+ - lib/sequel/plugins/protobuf/drivers.rb
26
+ - lib/sequel/plugins/protobuf/drivers/ruby-protocol-buffers-driver.rb
27
+ - lib/sequel/plugins/protobuf/version.rb
28
+ - sequel-protobuf.gemspec
29
+ - test/helpers/definition_error_sequel_model.rb
30
+ - test/helpers/models/test.pb.rb
31
+ - test/helpers/models/test.proto
32
+ - test/helpers/my_message_sequel_model.rb
33
+ - test/helpers/nested_sequel_model.rb
34
+ - test/sequel/plugins/protobuf/drivers/ruby_protocol_buffers_test.rb
35
+ - test/sequel/plugins/protobuf_test.rb
36
+ - test/test_helper.rb
37
+ homepage: http://github.com/kellydunn/sequel-protobuf
38
+ licenses: []
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 2.4.7
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: Sequel plugin for protocol buffer serialization
60
+ test_files:
61
+ - test/helpers/definition_error_sequel_model.rb
62
+ - test/helpers/models/test.pb.rb
63
+ - test/helpers/models/test.proto
64
+ - test/helpers/my_message_sequel_model.rb
65
+ - test/helpers/nested_sequel_model.rb
66
+ - test/sequel/plugins/protobuf/drivers/ruby_protocol_buffers_test.rb
67
+ - test/sequel/plugins/protobuf_test.rb
68
+ - test/test_helper.rb
69
+ has_rdoc: