ork 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: d614293fd63e1d8d2a8de96cfb92ad40c09ebdc5
4
+ data.tar.gz: f487220a7969011adfe79399feb8ddcecc0d7187
5
+ SHA512:
6
+ metadata.gz: 39953ee12661946b11f55e278253d8726871ff9b8d3eb3c389e9d2ba447460f8c959048c99b9d6ade5a7992974297bc7bc78d8b55ba0e7c9366c82b6492fb9ba
7
+ data.tar.gz: 7b565b3a8ff7901cc7457464a335a54b0c5c1a1f53cf159f87815e4402a250d168bbd275da6f7a4a12a8621c59be86e53e08cf5066e10c9eb5428ea632a6cc03
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # `ork`
2
+ [![Gem Version](https://badge.fury.io/rb/ork.png)](http://badge.fury.io/rb/ork)
3
+ [![Build Status](https://secure.travis-ci.org/eMancu/ork.png)](http://travis-ci.org/eMancu/ork)
4
+ [![Code Climate](https://codeclimate.com/github/eMancu/ork.png)](https://codeclimate.com/github/eMancu/ork)
5
+ [![Coverage Status](https://coveralls.io/repos/eMancu/ork/badge.png)](https://coveralls.io/r/eMancu/ork)
6
+ [![Dependency Status](https://gemnasium.com/eMancu/ork.png)](https://gemnasium.com/eMancu/ork)
7
+
8
+ `ork` is a small Ruby modeling layer for **Riak**, Basho's distributed database inspired by [Ohm](http://ohm.keyvalue.org).
9
+
10
+ ## Dependencies
11
+
12
+ `ork` requires Ruby 1.9 or later and the `riak-client` gem to connect to **Riak**.
13
+
14
+ ## Getting started
15
+
16
+ ## Attributes
17
+
18
+ Ork::Model provides one attribute type:
19
+
20
+ - Ork::Model.attribute attribute
21
+
22
+ And three meta types:
23
+
24
+ - Ork::Model.reference reference
25
+ - Ork::Model.referenced referenced
26
+ - Ork::Model.collection collection
27
+
28
+ ### attribute
29
+
30
+ An `attribute` is just any value that can be stored.
31
+
32
+ ### reference
33
+
34
+ It's a special kind of attribute that references another model.
35
+ Internally, Ork will keep a pointer to the model (its ID), but you get
36
+ accessors that give you real instances. You can think of it as the model
37
+ containing the foreign key to another model.
38
+
39
+ ### referenced
40
+
41
+ Provides an accessor to search for _one_ model that `reference` the current model.
42
+
43
+ ### collection
44
+
45
+ Provides an accessor to search for _all_ models that `reference` the current model.
@@ -0,0 +1,28 @@
1
+ module Ork
2
+ class Connection
3
+ attr_accessor :context, :options
4
+
5
+ def initialize(context = :main, options = {})
6
+ @context = context
7
+ @options = options
8
+ end
9
+
10
+ def reset!
11
+ threaded[context] = nil
12
+ end
13
+
14
+ def start(context, options = {})
15
+ self.context = context
16
+ self.options = options
17
+ self.reset!
18
+ end
19
+
20
+ def riak
21
+ threaded[context] ||= Riak::Client.new(options)
22
+ end
23
+
24
+ def threaded
25
+ Thread.current[:ork] ||= {}
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,138 @@
1
+ module Ork::Model
2
+ module Associations
3
+ # A macro for defining an attribute, an index, and an accessor
4
+ # for a given model.
5
+ #
6
+ # Example:
7
+ #
8
+ # class Post
9
+ # include Ork::Model
10
+ #
11
+ # reference :user, :User
12
+ # end
13
+ #
14
+ # # It's the same as:
15
+ #
16
+ # class Post
17
+ # include Ork::Model
18
+ #
19
+ # attribute :user_id
20
+ # index :user_id
21
+ #
22
+ # def user
23
+ # @_memo[:user] ||= User[user_id]
24
+ # end
25
+ #
26
+ # def user=(user)
27
+ # self.user_id = user.id
28
+ # @_memo[:user] = user
29
+ # end
30
+ #
31
+ # def user_id=(user_id)
32
+ # @_memo.delete(:user_id)
33
+ # self.user_id = user_id
34
+ # end
35
+ # end
36
+ #
37
+ def reference(name, model)
38
+ reader = :"#{name}_id"
39
+ writer = :"#{name}_id="
40
+
41
+ index reader
42
+
43
+ define_method(reader) do
44
+ @attributes[reader]
45
+ end
46
+
47
+ define_method(writer) do |value|
48
+ @_memo.delete(name)
49
+ @attributes[reader] = value
50
+ end
51
+
52
+ define_method(:"#{name}=") do |value|
53
+ @_memo.delete(name)
54
+ send(writer, value ? value.id : nil)
55
+ end
56
+
57
+ define_method(name) do
58
+ @_memo[name] ||= begin
59
+ model = Ork::Utils.const(self.class, model)
60
+ model[send(reader)]
61
+ end
62
+ end
63
+ end
64
+
65
+ # A macro for defining a method which basically does a find.
66
+ #
67
+ # Example:
68
+ # class Post
69
+ # include Ork::Model
70
+ #
71
+ # reference :user, :User
72
+ # end
73
+ #
74
+ # class User
75
+ # include Ork::Model
76
+ #
77
+ # referenced :post, :Post
78
+ # end
79
+ #
80
+ # # is the same as
81
+ #
82
+ # class User
83
+ # include Ork::Model
84
+ #
85
+ # def post
86
+ # Post.find(:user_id => self.id)
87
+ # end
88
+ # end
89
+ #
90
+ def referenced(name, model, reference = to_reference)
91
+ define_method name do
92
+ model = Ork::Utils.const(self.class, model)
93
+ model.find(:"#{reference}_id" => id).first
94
+ end
95
+ end
96
+
97
+ # A macro for defining a method which basically does a find.
98
+ #
99
+ # Example:
100
+ # class Post
101
+ # include Ork::Model
102
+ #
103
+ # reference :user, :User
104
+ # end
105
+ #
106
+ # class User
107
+ # include Ork::Model
108
+ #
109
+ # collection :posts, :Post
110
+ # end
111
+ #
112
+ # # is the same as
113
+ #
114
+ # class User
115
+ # include Ork::Model
116
+ #
117
+ # def posts
118
+ # Post.find(:user_id => self.id)
119
+ # end
120
+ # end
121
+ #
122
+ def collection(name, model, reference = to_reference)
123
+ define_method name do
124
+ model = Ork::Utils.const(self.class, model)
125
+ model.find(:"#{reference}_id" => id)
126
+ end
127
+ end
128
+
129
+ private
130
+
131
+ def to_reference
132
+ name.to_s.
133
+ match(/^(?:.*::)*(.*)$/)[1].
134
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').
135
+ downcase.to_sym
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,89 @@
1
+ module Ork::Model
2
+ module ClassMethods
3
+ attr_writer :bucket_name
4
+
5
+ # Syntactic sugar for Model.new(atts).save
6
+ def create(atts = {})
7
+ new(atts).save
8
+ end
9
+
10
+ def attributes
11
+ @attributes ||= []
12
+ end
13
+
14
+ def bucket
15
+ Ork.riak.bucket(bucket_name)
16
+ end
17
+
18
+ def bucket_name
19
+ @bucket_name ||= self.to_s.downcase
20
+ end
21
+
22
+ def indices
23
+ @indices ||= []
24
+ end
25
+
26
+ def uniques
27
+ @uniques ||= []
28
+ end
29
+
30
+ protected
31
+
32
+ # Declares persisted attributes.
33
+ # All attributes are stored on the Riak hash.
34
+ #
35
+ # Example:
36
+ # class User
37
+ # include Ork::Model
38
+ #
39
+ # attribute :name
40
+ # end
41
+ #
42
+ # # It's the same as:
43
+ #
44
+ # class User
45
+ # include Ork::Model
46
+ #
47
+ # def name
48
+ # @attributes[:name]
49
+ # end
50
+ #
51
+ # def name=(name)
52
+ # @attributes[:name] = name
53
+ # end
54
+ # end
55
+ #
56
+ def attribute(name, cast = nil)
57
+ attributes << name unless attributes.include?(name)
58
+
59
+ if cast
60
+ define_method(name) do
61
+ cast[@attributes[name]]
62
+ end
63
+ else
64
+ define_method(name) do
65
+ @attributes[name]
66
+ end
67
+ end
68
+
69
+ define_method(:"#{name}=") do |value|
70
+ @attributes[name] = value
71
+ end
72
+ end
73
+
74
+ # Index any method on your model. Once you index a method, you can
75
+ # use it in `find` statements.
76
+ def index(attribute)
77
+ indices << attribute unless indices.include?(attribute)
78
+ end
79
+
80
+ # Create a unique index for any method on your model.
81
+ #
82
+ # Note: if there is a conflict while saving, an
83
+ # `Ork::UniqueIndexViolation` violation is raised.
84
+ #
85
+ def unique(attribute)
86
+ uniques << attribute unless uniques.include?(attribute)
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,44 @@
1
+ module Ork::Model
2
+ module Finders
3
+
4
+ # Retrieve a record by ID.
5
+ #
6
+ # Example:
7
+ #
8
+ # u = User.create
9
+ # u == User[u.id]
10
+ # # => true
11
+ #
12
+ def [](id)
13
+ new.send(:load!, id) if exist?(id)
14
+ rescue Riak::FailedRequest => e
15
+ raise e unless e.not_found?
16
+ nil
17
+ end
18
+
19
+ # Check if the ID exists.
20
+ def exist?(id)
21
+ !id.nil? && bucket.exists?(id)
22
+ end
23
+ alias :exists? :exist?
24
+
25
+ # Find all documents in the Document's bucket and return them.
26
+ # @overload list()
27
+ # Get all documents and return them in an array.
28
+ # @param [Hash] options options to be passed to the
29
+ # underlying {Bucket#keys} method.
30
+ # @return [Array<Document>] all found documents in the bucket
31
+ #
32
+ # @Note: This operation is incredibly expensive and should not
33
+ # be used in production applications.
34
+ #
35
+ def all
36
+ bucket.keys.inject([]) do |acc, k|
37
+ obj = self[k]
38
+ obj ? acc << obj : acc
39
+ end
40
+ end
41
+ alias :list :all
42
+
43
+ end
44
+ end
data/lib/ork/model.rb ADDED
@@ -0,0 +1,154 @@
1
+ require_relative 'model/class_methods'
2
+ require_relative 'model/associations'
3
+ require_relative 'model/finders'
4
+
5
+ module Ork
6
+ module Model
7
+ attr_reader :attributes, :id
8
+ attr_writer :id
9
+
10
+ def self.included(klass)
11
+ klass.extend(Ork::Model::ClassMethods)
12
+ klass.extend(Ork::Model::Associations)
13
+ klass.extend(Ork::Model::Finders)
14
+ end
15
+
16
+ # Initialize a model using a dictionary of attributes.
17
+ #
18
+ # Example:
19
+ #
20
+ # u = User.new(:name => "John")
21
+ #
22
+ def initialize(atts = {})
23
+ @attributes = {}
24
+ @_memo = {}
25
+ update_attributes(atts)
26
+ end
27
+
28
+ # Check for equality by doing the following assertions:
29
+ #
30
+ # 1. That the passed model is of the same type.
31
+ # 2. That they represent the same RObject id.
32
+ #
33
+ def ==(other)
34
+ other.kind_of?(model) && other.id == id
35
+ end
36
+
37
+ alias :eql? :==
38
+
39
+ def new?
40
+ !id
41
+ end
42
+
43
+ # Pretty print for the model
44
+ #
45
+ # Example:
46
+ #
47
+ # User.new(name: 'John').inspect
48
+ # # => #<User:6kS5VHNbaed9h7gFLnVg5lmO4U7 {:name=>"John"}>
49
+ def inspect
50
+ "#<#{model}:#{id || 'nil'} #{attributes.inspect}>"
51
+ end
52
+
53
+ # Update the model attributes and call save.
54
+ #
55
+ # Example:
56
+ #
57
+ # User[1].update(:name => "John")
58
+ #
59
+ # # It's the same as:
60
+ #
61
+ # u = User[1]
62
+ # u.update_attributes(:name => "John")
63
+ # u.save
64
+ #
65
+ def update(attributes)
66
+ update_attributes(attributes)
67
+ save
68
+ end
69
+
70
+ # Write the dictionary of key-value pairs to the model.
71
+ #
72
+ def update_attributes(atts)
73
+ atts.delete('_type')
74
+ atts.each { |att, val| send(:"#{att}=", val) }
75
+ end
76
+
77
+ # Delete the model
78
+ def delete
79
+ __robject.delete unless new?
80
+ freeze
81
+ rescue Riak::FailedRequest
82
+ false
83
+ end
84
+
85
+ # Persist the model attributes and update indices and unique
86
+ # indices.
87
+ #
88
+ # If the model is not valid, nil is returned. Otherwise, the
89
+ # persisted model is returned.
90
+ #
91
+ # Example:
92
+ #
93
+ # class User
94
+ # include Ork::Model
95
+ #
96
+ # attribute :name
97
+ #
98
+ # def validate
99
+ # assert_present :name
100
+ # end
101
+ # end
102
+ #
103
+ # User.new(:name => nil).save
104
+ # # => nil
105
+ #
106
+ # u = User.new(:name => "John").save
107
+ # # => #<User:6kS5VHNbaed9h7gFLnVg5lmO4U7 {:name=>"John"}>
108
+ #
109
+ def save
110
+ # FIXME: Work with validations, scrivener or hatch?
111
+ # save! if valid?
112
+ save!
113
+ end
114
+
115
+ # Saves the model without checking for validity. Refer to
116
+ # `Model#save` for more details.
117
+ def save!
118
+ __save__
119
+ end
120
+
121
+ # Preload all the attributes of this model from Riak.
122
+ def reload
123
+ new? ? self : self.load!(@id)
124
+ end
125
+
126
+ protected
127
+
128
+ def load!(id)
129
+ @id = self.__robject.key = id
130
+ @__robject = @__robject.reload(force: true)
131
+ update_attributes(@__robject.data)
132
+
133
+ self
134
+ end
135
+
136
+ # Persist the object in Riak database
137
+ def __save__
138
+ __robject.content_type = 'application/json'
139
+ __robject.data = @attributes.merge('_type' => model.name)
140
+ __robject.store
141
+ @id = __robject.key
142
+
143
+ self
144
+ end
145
+
146
+ def __robject
147
+ @__robject ||= model.bucket.new
148
+ end
149
+
150
+ def model
151
+ self.class
152
+ end
153
+ end
154
+ end
data/lib/ork/utils.rb ADDED
@@ -0,0 +1,35 @@
1
+ module Ork
2
+ # Instead of monkey patching Kernel or trying to be clever, it's
3
+ # best to confine all the helper methods in a Utils module.
4
+ module Utils
5
+
6
+ # Used by: `attribute`, `reference`, `collection`.
7
+ #
8
+ # Employed as a solution to avoid `NameError` problems when trying
9
+ # to load models referring to other models not yet loaded.
10
+ #
11
+ # Example:
12
+ #
13
+ # class Comment
14
+ # include Ork::Model
15
+ #
16
+ # reference :user, User # NameError undefined constant User.
17
+ # end
18
+ #
19
+ # Instead of relying on some clever `const_missing` hack, we can
20
+ # simply use a Symbol.
21
+ #
22
+ # class Comment
23
+ # include Ork::Model
24
+ #
25
+ # reference :user, :User
26
+ # end
27
+ #
28
+ def self.const(context, name)
29
+ case name
30
+ when Symbol then context.const_get(name)
31
+ else name
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ class Ork
2
+ VERSION = "0.0.1"
3
+ end
data/lib/ork.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'ork/connection'
2
+ require 'ork/model'
3
+ require 'ork/utils'
4
+ require "riak"
5
+
6
+ module Ork
7
+ class Error < StandardError; end
8
+
9
+ def self.conn
10
+ @conn ||= Ork::Connection.new
11
+ end
12
+
13
+ # Stores the connection options for the Riak instance.
14
+ #
15
+ # Examples:
16
+ #
17
+ # Ork.connect(:http_port => 6380, :pb_port => 15000)
18
+ #
19
+ # All of the options are simply passed on to `Riak::Client.new`.
20
+ #
21
+ def self.connect(context = :main, options = {})
22
+ conn.start(context, options)
23
+ end
24
+
25
+ # Use this if you want to do quick ad hoc riak commands against the
26
+ # defined Ork connection.
27
+ #
28
+ # Examples:
29
+ #
30
+ # Ork.riak.buckets
31
+ # Ork.riak.bucket('foo').keys
32
+ #
33
+ def self.riak
34
+ conn.riak
35
+ end
36
+ end
data/ork.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'ork'
3
+ s.version = '0.0.1'
4
+ s.date = Time.now.strftime('%Y-%m-%d')
5
+ s.summary = 'Ruby modeling layer for Riak.'
6
+ s.description = 'Ork is a small Ruby modeling layer for Riak, inspired by Ohm.'
7
+ s.authors = ['Emiliano Mancuso']
8
+ s.email = ['emiliano.mancuso@gmail.com']
9
+ s.homepage = 'http://github.com/eMancu/ork'
10
+ s.license = 'MIT'
11
+
12
+ s.files = Dir[
13
+ 'README.md',
14
+ 'rakefile',
15
+ 'lib/**/*.rb',
16
+ '*.gemspec'
17
+ ]
18
+ s.test_files = Dir['test/*.*']
19
+
20
+ s.add_dependency 'riak-client'
21
+ s.add_development_dependency 'protest'
22
+ s.add_development_dependency 'toml-rb'
23
+ end
24
+
data/rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require "rake/testtask"
2
+
3
+ task :default => :test
4
+
5
+ desc 'Start riak test server'
6
+ task :start do
7
+ require File.expand_path("./test/helper", File.dirname(__FILE__))
8
+ puts '..:: Starting riak test server ::..'
9
+ test_server.start
10
+ end
11
+
12
+ desc 'Run tests'
13
+ task :test => [:start] do
14
+ Dir["test/*.rb"].each { |file| load file unless file =~ /helper.rb/ }
15
+ end
16
+
17
+ desc 'Stop riak test server'
18
+ task :stop => [:start] do
19
+ puts '..:: Stop riak test server ::..'
20
+
21
+ flush_db!
22
+ test_server.stop
23
+ end
24
+
25
+ at_exit do
26
+ puts '..:: Stop riak test server ::..'
27
+ sleep 1
28
+
29
+ flush_db!
30
+ test_server.stop
31
+ end
data/test/finders.rb ADDED
@@ -0,0 +1,43 @@
1
+ require_relative 'helper'
2
+
3
+ class Human
4
+ include Ork::Model
5
+
6
+ attribute :name
7
+ attribute :last_name
8
+
9
+ unique :name
10
+ index :last_name
11
+ end
12
+
13
+ Protest.describe 'Finders' do
14
+ setup do
15
+ @human1 = Human.create(name: 'Tony', last_name: 'Montana')
16
+ @human2 = Human.create(name: 'Cacho', last_name: 'Castaña')
17
+ end
18
+
19
+ teardown do
20
+ flush_db!
21
+ end
22
+
23
+ test 'retrieve an object by id' do
24
+ assert_equal @human1, Human[@human1.id]
25
+ end
26
+
27
+ test 'return nil when the id does not belong to an object of this bucket' do
28
+ assert_equal nil, Human['not_an_id']
29
+ end
30
+
31
+ test 'if exist an object with the id' do
32
+ assert !Human.exist?(nil)
33
+ assert !Human.exist?('not_an_id')
34
+ assert Human.exist?(@human1.id)
35
+ end
36
+
37
+ test 'list all the objects' do
38
+ assert_equal 2, Human.list.size
39
+ assert Human.list.include?(@human1)
40
+ assert Human.list.include?(@human2)
41
+ end
42
+
43
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,41 @@
1
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
2
+
3
+ require "rubygems"
4
+ require "protest"
5
+ require "ork"
6
+
7
+ # require 'coveralls'
8
+ # Coveralls.wear!
9
+
10
+ Riak.disable_list_keys_warnings = true
11
+
12
+ require 'riak/test_server'
13
+
14
+ def test_server
15
+ $test_server ||= begin
16
+ require 'toml'
17
+ path = File.expand_path("../test_riak_server.toml", __FILE__)
18
+ config = TOML.load_file(path, symbolize_keys: true)
19
+
20
+
21
+ server = Riak::TestServer.create(root: config[:root],
22
+ source: config[:source],
23
+ min_port: config[:min_port])
24
+
25
+
26
+ Ork.connect(:test, {
27
+ http_port: server.http_port,
28
+ pb_port: server.pb_port
29
+ })
30
+
31
+ server
32
+ rescue => e
33
+ puts ("Can't run Ork tests without the test server.\n" +
34
+ "Specify the location of your Riak installation in test/test_riak_server.toml\n" +
35
+ e.inspect)
36
+ end
37
+ end
38
+
39
+ def flush_db!
40
+ test_server.drop
41
+ end
data/test/model.rb ADDED
@@ -0,0 +1,139 @@
1
+ # encoding: UTF-8
2
+ require_relative 'helper'
3
+
4
+ class Event
5
+ include Ork::Model
6
+
7
+ attribute :name
8
+ attribute :location
9
+
10
+ unique :name
11
+ index :location
12
+ end
13
+
14
+ Protest.describe 'Ork::Model' do
15
+ context 'Definition' do
16
+ test 'have an attributes list' do
17
+ assert_equal [:name, :location], Event.attributes
18
+ end
19
+
20
+ test 'have a uniques list' do
21
+ assert_equal [:name], Event.uniques
22
+ end
23
+
24
+ test 'have an indices list' do
25
+ assert_equal [:location], Event.indices
26
+ end
27
+
28
+ test 'model owns a bucket name by default' do
29
+ assert_equal 'event', Event.bucket_name
30
+ end
31
+
32
+ test 'generate accessors for attributes' do
33
+ event = Event.new
34
+
35
+ assert event.respond_to? :name
36
+ assert event.respond_to? :name=
37
+ assert event.respond_to? :location
38
+ assert event.respond_to? :location=
39
+ end
40
+
41
+ test 'cast to different types' do
42
+ pending 'Define how to cast objects'
43
+ end
44
+
45
+ test 'model can change bucket name' do
46
+ Event.bucket_name= 'other_bucket_for_event'
47
+ assert_equal 'other_bucket_for_event', Event.bucket_name
48
+ end
49
+
50
+ test 'there is a Riak::Bucket corresponding to the model' do
51
+ assert_equal Riak::Bucket, Event.bucket.class
52
+ end
53
+ end
54
+
55
+ context 'Instance' do
56
+ setup do
57
+ @event = Event.new(name: 'Ruby')
58
+ end
59
+
60
+ test 'determine if it is a new instance or it was saved' do
61
+ assert @event.new?
62
+ @event.save
63
+ assert !@event.new?
64
+ end
65
+
66
+ test 'assign attributes from the hash' do
67
+ assert_equal 'Ruby', @event.name
68
+ end
69
+
70
+ test 'inspect a new object shows the class, attributes with id nil' do
71
+ assert_equal '#<Event:nil {:name=>"Ruby"}>', @event.inspect
72
+ end
73
+
74
+ test 'inspect a saved object shows the class, attributes with id nil' do
75
+ @event.save
76
+ assert_equal '#<Event:' + @event.id + ' {:name=>"Ruby"}>', @event.inspect
77
+ end
78
+
79
+ test 'assign an ID and save the object' do
80
+ event = Event.create(name: 'Ruby')
81
+
82
+ assert !event.new?
83
+ assert !event.id.nil?
84
+ end
85
+
86
+ test 'update and save the attributes in UTF8' do
87
+ @event.update(name: '32° Kisei-sen')
88
+ assert_equal '32° Kisei-sen', Event[@event.id].name
89
+ end
90
+
91
+ test 'update_attributes changes attributes but does not save the object' do
92
+ assert @event.new?
93
+ assert_equal 'Ruby', @event.name
94
+
95
+ @event.update_attributes(name: 'Emerald', location: 4)
96
+
97
+ assert @event.new?
98
+ assert_equal 'Emerald', @event.name
99
+ assert_equal 4, @event.location
100
+ end
101
+
102
+ context 'Deletion' do
103
+ test 'freeze the object' do
104
+ assert !@event.frozen?
105
+ @event.delete
106
+ assert @event.frozen?
107
+ end
108
+
109
+ test 'delete the object from the bucket' do
110
+ @event.save
111
+ assert Event.bucket.exist?(@event.id)
112
+ @event.delete
113
+ assert !Event.bucket.exist?(@event.id)
114
+ end
115
+ end
116
+ end
117
+
118
+ context "Equality" do
119
+ setup do
120
+ @event = Event.new(name: 'Ruby')
121
+ @other = Event.new(name: 'Emerald')
122
+ end
123
+
124
+ test 'different types' do
125
+ assert @event != 'Not an event'
126
+ end
127
+
128
+ test 'saved instances with different ids' do
129
+ @event.save
130
+ @other.save
131
+
132
+ assert @event != @other
133
+ end
134
+
135
+ test 'unsaved intances' do
136
+ pending 'Define how equality will be'
137
+ end
138
+ end
139
+ end
data/test/reference.rb ADDED
@@ -0,0 +1,73 @@
1
+ require_relative 'helper'
2
+
3
+ class Post
4
+ include Ork::Model
5
+ attribute :name
6
+ end
7
+
8
+ class Comment
9
+ include Ork::Model
10
+ attribute :text
11
+
12
+ reference :post, :Post
13
+ reference :weird_post, :Post
14
+ end
15
+
16
+ Protest.describe 'reference' do
17
+ teardown do
18
+ flush_db!
19
+ end
20
+
21
+ should 'return nil when there is no reference object' do
22
+ comment = Comment.new
23
+
24
+ assert comment.post.nil?
25
+ end
26
+
27
+ should 'raise an exception assigning an object of the wrong type' do
28
+ pending 'Not sure to support this'
29
+ assert_raise(Error) do
30
+ Comment.new post: 'Not a post'
31
+ end
32
+ end
33
+
34
+ should 'return the object referenced' do
35
+ post = Post.create name: 'New'
36
+ comment = Comment.new post: post
37
+
38
+ assert_equal post, comment.post
39
+ assert_equal post.id, comment.post_id
40
+ end
41
+
42
+ test 'object reference with not default key' do
43
+ post = Post.create name: 'New'
44
+ comment = Comment.new weird_post: post
45
+
46
+ assert_equal post, comment.weird_post
47
+ assert_equal post.id, comment.weird_post_id
48
+ end
49
+
50
+ should 'update reference to an object given the id or object' do
51
+ post = Post.create name: 'New'
52
+ comment = Comment.new
53
+
54
+ assert comment.post.nil?
55
+ assert comment.post_id.nil?
56
+
57
+ comment.post = post
58
+
59
+ assert_equal post, comment.post
60
+ assert_equal post.id, comment.post_id
61
+
62
+ post = Post.create name: 'Other'
63
+ comment.post_id = post.id
64
+
65
+ assert_equal post, comment.post
66
+ assert_equal post.id, comment.post_id
67
+ end
68
+
69
+ context 'Deletion' do
70
+ # Discuss if we want cascade all deletetion and that sort of things
71
+ end
72
+
73
+ end
@@ -0,0 +1,15 @@
1
+ # This is where the test server node will be generated. Something on
2
+ # /tmp is usually ok.
3
+ root = "/tmp/.ork_node"
4
+ min_port = 15000
5
+
6
+ # This is where Riak is installed on your system, that is, the path to
7
+ # the 'riak' and 'riak-admin' scripts. I use a self-built node, but
8
+ # here's where it will generally be on various platforms:
9
+ #
10
+ # Linux: /usr/sbin
11
+ # Solaris/OpenSolaris: /opt/riak/bin
12
+ # Mac OS/X (Homebrew): /usr/local/bin
13
+ # Source/Self built: /path/to/your/install/rel/riak/bin
14
+ #
15
+ source = "/usr/local/bin"
@@ -0,0 +1,15 @@
1
+ # This is where the test server node will be generated. Something on
2
+ # /tmp is usually ok.
3
+ root = "/tmp/.ork_node"
4
+ min_port = 15000
5
+
6
+ # This is where Riak is installed on your system, that is, the path to
7
+ # the 'riak' and 'riak-admin' scripts. I use a self-built node, but
8
+ # here's where it will generally be on various platforms:
9
+ #
10
+ # Linux: /usr/sbin
11
+ # Solaris/OpenSolaris: /opt/riak/bin
12
+ # Mac OS/X (Homebrew): /usr/local/bin
13
+ # Source/Self built: /path/to/your/install/rel/riak/bin
14
+ #
15
+ source = "/usr/local/bin"
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ork
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Emiliano Mancuso
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: riak-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: protest
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: toml-rb
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Ork is a small Ruby modeling layer for Riak, inspired by Ohm.
56
+ email:
57
+ - emiliano.mancuso@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - README.md
63
+ - rakefile
64
+ - lib/ork/connection.rb
65
+ - lib/ork/model/associations.rb
66
+ - lib/ork/model/class_methods.rb
67
+ - lib/ork/model/finders.rb
68
+ - lib/ork/model.rb
69
+ - lib/ork/utils.rb
70
+ - lib/ork/version.rb
71
+ - lib/ork.rb
72
+ - ork.gemspec
73
+ - test/finders.rb
74
+ - test/helper.rb
75
+ - test/model.rb
76
+ - test/reference.rb
77
+ - test/test_riak_server.toml
78
+ - test/test_riak_server.toml.example
79
+ homepage: http://github.com/eMancu/ork
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 2.0.3
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Ruby modeling layer for Riak.
103
+ test_files:
104
+ - test/finders.rb
105
+ - test/helper.rb
106
+ - test/model.rb
107
+ - test/reference.rb
108
+ - test/test_riak_server.toml
109
+ - test/test_riak_server.toml.example