zebris 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d82aa602d7e4e5640c78087c63c0707c0301dbb0
4
+ data.tar.gz: 85bda8fd3143cd50cfa3e0b43af3e216a2fcc287
5
+ SHA512:
6
+ metadata.gz: 582d250221952c4a7694fb069681a8d2792b140ad8b25e76546d1128bb97c3d4d50d5dd3025093f344bee9ac22b34788d47bfe98c1eaefe2e89efc84829ba6ba
7
+ data.tar.gz: d56c3bf257822fd2165abced26b19bb7dcb434bc5e576bf6d2305be58bd76fb3634dd47d42865b1e344dcc44317f781abb7ce39448acbe054ee134598bad52fb
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .ruby-version
7
+ .tags
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in zebris.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jeremy Gailor
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Zebris
2
+
3
+ Zebris is built to allow you to add persisting and retrieving your objects to and from Redis with a minimum of hassle or re-writing of your code.
4
+ When I needed a library to do something similar, I noticed that a lot of the other Redis persistence libraries were very opinionated or tried to
5
+ implement the ActiveRecord pattern, which is nice but would have required me to re-write a lot more of my code to conform to the libraries idioms
6
+ than I wanted to do. My goal was to make it as easy as possible to add a ruby gem to my project and with as little code as possible make it easy to
7
+ persist the object to Redis and retrieve it later. Such is Zebris, or so I hope.
8
+
9
+ I welcome all feedback and suggestions on how to improve Zebris. It's very young, but I have a roadmap in mind to add some things that I think will
10
+ allow Zebris to keep it's simplicity and general purpose use while adding a lot of utility for anyone using it.
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ gem 'zebris'
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install zebris
25
+
26
+ ## Usage
27
+
28
+ ### Configuration
29
+ Zebris is happy to delegate to any Redis client that supports the 2.0+ command list. To configure Zebris, just pass it a connected Redis client object:
30
+
31
+ Zebris.redis = Redis.new
32
+
33
+ ### Basic Document Peristence
34
+
35
+ class Person
36
+ include Zebris::Document
37
+
38
+ key {UUID.generate} # Or anything that will generate unique keys
39
+
40
+ # String, Integer, Float, Date are built-in types to Zebris that understand
41
+ # serialization and deserialization of those types
42
+ property :name, String
43
+ property :weight, Float
44
+ property :lucky_number, Integer
45
+ property :birthday, Date
46
+ end
47
+
48
+ person = Person.new
49
+ person.name = "Tyler Durden"
50
+ person.weight = 175.2
51
+ person.lucky_number = 13
52
+ person.birthday = Date.parse('1979-05-20')
53
+
54
+ key = person.save
55
+ => "some uuid here"
56
+
57
+ tyler = Person.find(key)
58
+
59
+ # Tyler is back
60
+
61
+ ## Contributing
62
+
63
+ 1. Fork it
64
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
65
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
66
+ 4. Push to the branch (`git push origin my-new-feature`)
67
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,144 @@
1
+ module Zebris
2
+ module Document
3
+ def self.included(klass)
4
+ klass.extend(ClassMethods)
5
+ end
6
+
7
+ def save
8
+ raise "#{self.class} does not define a key generator" unless self.class.keygen.kind_of?(Proc)
9
+
10
+ self.class.scrub
11
+ data = self.class.serialize(self)
12
+
13
+ result = Zebris.redis.set self.key, data.to_json
14
+
15
+ raise "Could not save #{self.class}" unless result == "OK"
16
+
17
+ self.key
18
+ end
19
+
20
+ def key
21
+ @key ||= self.class.keygen.call
22
+ end
23
+
24
+ module ClassMethods
25
+ def const_missing(const)
26
+ const
27
+ end
28
+
29
+ def find(key)
30
+ stored = Zebris.redis.get key
31
+
32
+ if stored
33
+ data = JSON.parse(stored)
34
+ deserialize(data)
35
+ else
36
+ nil
37
+ end
38
+ end
39
+
40
+ def serialize(object)
41
+ attributes = {"key" => object.key}
42
+
43
+ properties.each do |property, conversion|
44
+ if val = object.send(property.to_sym)
45
+ if conversion.kind_of?(Zebris::Types::GenericConverter)
46
+ attributes[property.to_s] = conversion.serializer.call(val)
47
+ else
48
+ attributes[property.to_s] = conversion.serialize(val)
49
+ end
50
+ end
51
+ end
52
+
53
+ collections.each do |property, klass|
54
+ attributes[property] ||= []
55
+ object.send(:instance_variable_get, :"@#{property}").each do |record|
56
+ attributes[property] << record.serialize
57
+ end
58
+ end
59
+
60
+ attributes
61
+ end
62
+
63
+ def scrub
64
+ unless @scrubbed
65
+ self.properties.each do |property, type|
66
+ unless type.kind_of?(Zebris::Types::GenericConverter)
67
+ if type.kind_of?(Symbol)
68
+ type = self.properties[property] = self.const_get(self.properties[property])
69
+ end
70
+
71
+ unless type.ancestors.include?(Zebris::Document) || self.properties[property].to_s.start_with?(Zebris::Types.to_s)
72
+ raise "#{type} does not implement the Zebris::Document interface"
73
+ end
74
+ end
75
+ end
76
+
77
+ self.collections.each do |property, type|
78
+ if self.collections[property].kind_of?(Symbol)
79
+ self.collections[property] = self.const_get(self.collections[property])
80
+ end
81
+ end
82
+
83
+ @scrubbed = true
84
+ end
85
+ end
86
+
87
+ def deserialize(data)
88
+ scrub
89
+
90
+ self.new.tap do |instance|
91
+ data.each do |property, value|
92
+ property = property.to_sym
93
+ if self.properties[property]
94
+ if self.properties[property].kind_of?(Zebris::Types::GenericConverter)
95
+ instance.send(:"#{property}=", self.properties[property].deserializer.call(value))
96
+ else
97
+ instance.send(:"#{property}=", self.properties[property].deserialize(value))
98
+ end
99
+ elsif self.collections[property] && value.instance_of?(Array)
100
+ value.each do |row|
101
+ instance.send(:"instance_variable_get", :"@#{property}") << self.collections[property].deserialize(row)
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def key(&block)
109
+ @keygen = block
110
+ end
111
+
112
+ def keygen
113
+ @keygen
114
+ end
115
+
116
+ def properties
117
+ @properties ||= {}
118
+ end
119
+
120
+ def property(name, type_or_serializer, deserializer = nil)
121
+ if type_or_serializer.kind_of?(Proc)
122
+ raise "When providing a deserializer you need to provide a deserializer" if deserializer.nil?
123
+ properties[name] = Zebris::Types::GenericConverter.new(type_or_serializer, deserializer)
124
+ else
125
+ if Zebris::Types.constants.include?(type_or_serializer.to_s.to_sym)
126
+ properties[name] = Zebris::Types.const_get(type_or_serializer.to_s.to_sym)
127
+ else
128
+ properties[name] = type_or_serializer
129
+ end
130
+ end
131
+ self.send(:attr_accessor, name)
132
+ end
133
+
134
+ def collections
135
+ @collections ||= {}
136
+ end
137
+
138
+ def collection(name, klass)
139
+ collections[name] = klass
140
+ self.send(:attr_accessor, name)
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,52 @@
1
+ module Zebris
2
+ module Types
3
+ class GenericConverter
4
+ attr_reader :serializer, :deserializer
5
+
6
+ def initialize(serializer, deserializer)
7
+ @serializer = serializer
8
+ @deserializer = deserializer
9
+ end
10
+ end
11
+
12
+ class Date
13
+ def self.deserialize(date)
14
+ ::Date.parse(date)
15
+ end
16
+
17
+ def self.serialize(val)
18
+ val.rfc3339
19
+ end
20
+ end
21
+
22
+ class Integer
23
+ def self.deserialize(val)
24
+ (val && val != "") ? val.to_i : nil
25
+ end
26
+
27
+ def self.serialize(val)
28
+ val
29
+ end
30
+ end
31
+
32
+ class Float
33
+ def self.deserialize(val)
34
+ (val && val != "") ? val.to_f : nil
35
+ end
36
+
37
+ def self.serialize(val)
38
+ val
39
+ end
40
+ end
41
+
42
+ class String
43
+ def self.deserialize(val)
44
+ val ? val.to_s : nil
45
+ end
46
+
47
+ def self.serialize(val)
48
+ val
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ module Zebris
2
+ VERSION = "0.0.1"
3
+ end
data/lib/zebris.rb ADDED
@@ -0,0 +1,14 @@
1
+ require "zebris/version"
2
+ require "zebris/types"
3
+ require "zebris/document"
4
+ require 'json'
5
+
6
+ module Zebris
7
+ def self.redis=(connection)
8
+ @redis = connection
9
+ end
10
+
11
+ def self.redis
12
+ @redis
13
+ end
14
+ end
@@ -0,0 +1,161 @@
1
+ require_relative "../../lib/zebris"
2
+ require 'uuid'
3
+
4
+ describe Zebris::Document do
5
+ class Document
6
+ include Zebris::Document
7
+ key {UUID.generate}
8
+ property :name, String
9
+ property :age, Integer
10
+ property :last_update, Date
11
+ end
12
+
13
+ class KeylessDocument
14
+ include Zebris::Document
15
+ property :name, String
16
+ end
17
+
18
+ class LambdaDocument
19
+ include Zebris::Document
20
+ key {UUID.generate}
21
+ property :name, lambda {|n| n}, lambda {|n| String.new(n)}
22
+ end
23
+
24
+ class NestedDocument
25
+ include Zebris::Document
26
+ key {UUID.generate}
27
+ property :person, Person
28
+
29
+ class Person
30
+ include Zebris::Document
31
+ key {UUID.generate}
32
+ property :name, String
33
+ property :age, Integer
34
+ end
35
+ end
36
+
37
+ let!(:redis) {double(:redis, set: "OK", get: true)}
38
+ let(:key) {"ABCDEFG"}
39
+ let(:name) {"John Henry"}
40
+ let(:age) {34}
41
+ let(:last_update) {Date.today - 2}
42
+
43
+ before do
44
+ Zebris.redis = redis
45
+ end
46
+
47
+ context "saving documents" do
48
+ it "should persist a document with a name property" do
49
+ document = Document.new
50
+ document.stub(:key).and_return(key)
51
+ redis.should_receive(:set).with(key, {"key" => key, "name" => name}.to_json)
52
+
53
+ document.name = name
54
+ document.save
55
+ end
56
+
57
+ it "raises an error when trying to save a document without a key generator" do
58
+ document = KeylessDocument.new
59
+ document.name = name
60
+ expect{document.save}.to raise_exception
61
+ end
62
+
63
+ context "property types" do
64
+ it "properly serializes the built in types" do
65
+ document = Document.new
66
+ document.stub(:key).and_return(key)
67
+ redis.should_receive(:set).with(key, {"key" => key, "name" => name, "age" => age, "last_update" => last_update.rfc3339}.to_json)
68
+
69
+ document.name = name
70
+ document.age = age
71
+ document.last_update = last_update
72
+ document.save
73
+ end
74
+
75
+ it "properly serializes the data when given a lambda" do
76
+ document = LambdaDocument.new
77
+ document.stub(:key).and_return(key)
78
+ redis.should_receive(:set).with(key, {"key" => key, "name" => name}.to_json)
79
+
80
+ document.name = name
81
+ document.save
82
+ end
83
+
84
+ context "nested type collections" do
85
+ it "serializes nested types if they include Zebris::Document" do
86
+ person_key = "123456"
87
+ person = NestedDocument::Person.new
88
+ person.name = name
89
+ person.age = age
90
+ person.stub(:key).and_return(person_key)
91
+
92
+ redis.should_receive(:set).with(key, {"key" => key, "person" => {"key" => person_key, "name" => name, "age" => age}}.to_json)
93
+
94
+ document = NestedDocument.new
95
+ document.stub(:key).and_return(key)
96
+ document.person = person
97
+ document.save
98
+ end
99
+
100
+ it "raises an exception if you attempt to declare a collection of things that aren't Zebris::Document" do
101
+ class BadDocument
102
+ include Zebris::Document
103
+
104
+ key {"This is a horrible key"}
105
+
106
+ property :person, Object
107
+ end
108
+
109
+ expect {
110
+ document = BadDocument.new
111
+ document.person = Object.new
112
+ document.save
113
+ }.to raise_exception
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ context "restoring documents" do
120
+ let(:serialized_document) {{"key" => key, "name" => name}.to_json}
121
+ let(:types_serialized_document) {{"key" => key, "name" => name, "age" => age, "last_update" => last_update.rfc3339}.to_json}
122
+ let(:lambda_serialized_document) {{"key" => key, "name" => name}.to_json}
123
+ let(:nested_serialized_document) {{"key" => key, "person" => {"name" => name, "age" => age}}.to_json}
124
+
125
+ it "delegates to the redis object" do
126
+ redis.should_receive(:get).with(key).and_return(serialized_document)
127
+ Document.find(key)
128
+ end
129
+
130
+ it "rebuilds an object that has been saved to redis" do
131
+ redis.stub(:get).and_return(serialized_document)
132
+ document = Document.find(key)
133
+ expect(document.name).to eq(name)
134
+ end
135
+
136
+ context "property types" do
137
+ it "rebuilds an object using built-in types" do
138
+ redis.stub(:get).and_return(types_serialized_document)
139
+ document = Document.find(key)
140
+ expect(document.name).to eq(name)
141
+ expect(document.age).to eq(age)
142
+ expect(document.last_update).to eq(last_update)
143
+ end
144
+
145
+ it "rebuilds an object using lambda serializers/deserializers" do
146
+ redis.stub(:get).and_return(lambda_serialized_document)
147
+ document = LambdaDocument.find(key)
148
+ expect(document.name).to eq(name)
149
+ end
150
+
151
+ context "nested documents" do
152
+ it "rebuilds a nested object structure" do
153
+ redis.stub(:get).and_return(nested_serialized_document)
154
+ document = NestedDocument.find(key)
155
+ expect(document.person.name).to eq(name)
156
+ expect(document.person.age).to eq(age)
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,77 @@
1
+ require_relative '../../lib/zebris/types'
2
+ require 'date'
3
+
4
+ describe Zebris::Types do
5
+ context Zebris::Types::Date do
6
+ it "deserializes a valid date" do
7
+ d = Date.today
8
+ expect(Zebris::Types::Date.deserialize(d.to_s)).to eq(d)
9
+ end
10
+
11
+ it "raises an exception if the date is invalid" do
12
+ d = ""
13
+ expect{Zebris::Types::Date.deserialize(d.to_s)}.to raise_exception
14
+ end
15
+ end
16
+
17
+ context Zebris::Types::Integer do
18
+ it "deserializes a valid integer" do
19
+ i = 101
20
+ expect(Zebris::Types::Integer.deserialize(i.to_s)).to eq(i)
21
+ end
22
+
23
+ it "returns nil if the integer is an empty string" do
24
+ i = ""
25
+ expect(Zebris::Types::Integer.deserialize(i.to_s)).to eq(nil)
26
+ end
27
+
28
+ it "returns nil if the integer is nil" do
29
+ i = nil
30
+ expect(Zebris::Types::Integer.deserialize(i)).to eq(nil)
31
+ end
32
+
33
+ it "raises an exception if the object does not support being converted to an integer" do
34
+ o = Object.new
35
+ expect{Zebris::Types::Integer.deserialize(o)}.to raise_exception
36
+ end
37
+ end
38
+
39
+ context Zebris::Types::Float do
40
+ it "deserializes and returns serialized float" do
41
+ f = 10.23
42
+ expect(Zebris::Types::Float.deserialize(f.to_s)).to eq(f)
43
+ end
44
+
45
+ it "deserializes and returns nil on an empty string" do
46
+ f = ""
47
+ expect(Zebris::Types::Float.deserialize(f.to_s)).to eq(nil)
48
+ end
49
+
50
+ it "deserializes and returns nil on an empty string" do
51
+ f = nil
52
+ expect(Zebris::Types::Float.deserialize(f)).to eq(nil)
53
+ end
54
+
55
+ it "raises an exception if the object does not support being converted to a float" do
56
+ o = Object.new
57
+ expect{Zebris::Types::Float.deserialize(o)}.to raise_exception
58
+ end
59
+ end
60
+
61
+ context Zebris::Types::String do
62
+ it "deserializes and returns a string as itself" do
63
+ s = %q{Do the ham bone}
64
+ expect(Zebris::Types::String.deserialize(s)).to eq(s)
65
+ end
66
+
67
+ it "deserializes and returns nil as nil" do
68
+ s = nil
69
+ expect(Zebris::Types::String.deserialize(s)).to eq(nil)
70
+ end
71
+
72
+ it "raises an exception if the object does not support being converted to a string" do
73
+ o = BasicObject.new
74
+ expect{Zebris::Types::String.deserialize(o)}.to raise_exception
75
+ end
76
+ end
77
+ end
data/zebris.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'zebris/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "zebris"
8
+ spec.version = Zebris::VERSION
9
+ spec.authors = ["Jeremy Gailor"]
10
+ spec.email = ["jgailor@gmail.com"]
11
+ spec.description = %q{Zebris is a library to persist your object data to Redis. Its goal is to be as unobtrusive as possible.}
12
+ spec.summary = %q{Zebris makes persisting your objects to Redis easy.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", "~> 2.14.1"
24
+ spec.add_development_dependency "uuid"
25
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zebris
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jeremy Gailor
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 2.14.1
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.14.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: uuid
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Zebris is a library to persist your object data to Redis. Its goal is
70
+ to be as unobtrusive as possible.
71
+ email:
72
+ - jgailor@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - lib/zebris.rb
83
+ - lib/zebris/document.rb
84
+ - lib/zebris/types.rb
85
+ - lib/zebris/version.rb
86
+ - spec/lib/document_spec.rb
87
+ - spec/lib/types_spec.rb
88
+ - zebris.gemspec
89
+ homepage: ''
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.0.3
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Zebris makes persisting your objects to Redis easy.
113
+ test_files:
114
+ - spec/lib/document_spec.rb
115
+ - spec/lib/types_spec.rb