thingtank 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.
@@ -0,0 +1,63 @@
1
+ class ThingTank
2
+ module SharedMethods
3
+ def self.included(klass)
4
+ klass.class_eval do
5
+
6
+ # only export the changed properties
7
+ def changed_to_role_hash(exclude_roles=false)
8
+ skips = skip_keys(exclude_roles)
9
+ hsh = {}
10
+ changes.each do |key,arr|
11
+ _old, _new = arr
12
+ unless skips.include? key
13
+ hsh[key] = _new
14
+ end
15
+ end
16
+ hsh
17
+ end
18
+
19
+ def skip_keys(exclude_roles=false)
20
+ arr = %w|_id _rev type update_me updated_at created_at|
21
+ arr << 'roles' if exclude_roles
22
+ arr
23
+ end
24
+
25
+ def to_role_hash(exclude_roles=false)
26
+ hsh = to_hash
27
+ skip_keys(exclude_roles).each{ |k| hsh.delete k }
28
+ hsh
29
+ end
30
+
31
+ def nth_role(klass, key, n, &code)
32
+ orig_role = to_role(klass, key)
33
+ list = [orig_role].flatten
34
+ role = case n
35
+ when :last
36
+ list.last
37
+ when :first
38
+ list.first
39
+ else
40
+ list[n]
41
+ end
42
+ if code
43
+ code.call(role)
44
+ role.flush_to_doc
45
+ end
46
+ if orig_role.is_a?(Array)
47
+ role._role_doc.dependencies.refresh_parent
48
+ end
49
+ role
50
+ end
51
+
52
+ def last_role(klass, key, &code)
53
+ nth_role(klass, key, :last, &code)
54
+ end
55
+
56
+ def first_role(klass, key, &code)
57
+ nth_role(klass, key, :first, &code)
58
+ end
59
+
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,36 @@
1
+ class ThingTank
2
+ module Shortcuts
3
+ def self.included(klass)
4
+ klass.class_eval do
5
+
6
+ def >(klass_or_hash)
7
+ case klass_or_hash
8
+ when Array
9
+ last_role(klass_or_hash.first, klass_or_hash.last)
10
+ else
11
+ to_role(klass_or_hash)
12
+ end
13
+ end
14
+
15
+ def <(klass_or_hash)
16
+ case klass_or_hash
17
+ when Array
18
+ first_role(klass_or_hash.first, klass_or_hash.last)
19
+ else
20
+ to_role(klass_or_hash)
21
+ end
22
+ end
23
+
24
+ def << (arr)
25
+ klass, key, code= arr.flatten
26
+ if code
27
+ add_role(klass, key, &code)
28
+ else
29
+ add_role(klass, key)
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ require 'couchrest'
2
+ require 'couchrest_model'
3
+
4
+ class ThingTank < CouchRest::Model::Base
5
+
6
+ mass_assign_any_attribute true # should always allow to set non defined arbitrary properties
7
+ timestamps!
8
+
9
+ def role_view_by(klass, *keys)
10
+ opts = keys.pop if keys.last.is_a?(Hash)
11
+ opts ||= {}
12
+ opts[:guards] ||= []
13
+ # there is no "inArray" like function in couchdb, see http://stackoverflow.com/questions/3740464/i-have-to-write-every-function-i-need-for-couchdb
14
+ opts[:guards] << "((doc['roles'] !== undefined) && (function (item,arr) { for(p=0;p<arr.length;p++) if (item == arr[p]) return true; return false;})('#{klass.to_s}',doc['roles']))"
15
+ view_by(*keys, opts)
16
+ end
17
+
18
+ end
19
+
20
+
21
+
data/lib/thingtank.rb ADDED
@@ -0,0 +1,27 @@
1
+ require_relative File.join('thingtank', 'thingtank.rb')
2
+ require_relative File.join('couchrest', 'extensions', 'view.rb')
3
+ require_relative File.join('thingtank', 'dependencies.rb')
4
+ require_relative File.join('thingtank', 'callbacks.rb')
5
+ require_relative File.join('thingtank', 'force_update.rb')
6
+ require_relative File.join('thingtank', 'shared_methods.rb')
7
+ require_relative File.join('thingtank', 'instance_methods.rb')
8
+ require_relative File.join('thingtank', 'shortcuts.rb')
9
+ require_relative File.join('thingtank', 'role_handling.rb')
10
+ require_relative File.join('thingtank', 'role.rb')
11
+ require_relative File.join('thingtank', 'fakebase.rb')
12
+
13
+ # TODO:
14
+ # role validator
15
+
16
+ class ThingTank
17
+
18
+ include ThingTank::ForceUpdate
19
+ include ThingTank::SharedMethods
20
+ include ThingTank::InstanceMethods
21
+ include ThingTank::RoleHandling
22
+ include ThingTank::Shortcuts
23
+ include ThingTank::Callbacks
24
+
25
+ end
26
+
27
+
@@ -0,0 +1,15 @@
1
+ require 'helper'
2
+ require 'bear_julius'
3
+
4
+ describe "bear a julius" do
5
+
6
+ before do
7
+ reset_test_db!
8
+ end
9
+
10
+ it "should be him" do
11
+ test_bear_julius()
12
+ end
13
+
14
+ end
15
+
@@ -0,0 +1,20 @@
1
+ require 'helper'
2
+ require 'first_marriage'
3
+
4
+
5
+ describe "with first marriage" do
6
+
7
+ before do
8
+ reset_test_db!
9
+ end
10
+
11
+ it "should make the first marriage" do
12
+ test_first_marriage()
13
+ end
14
+
15
+ it "should make the first marriage with shortcuts" do
16
+ test_first_marriage_shortcuts()
17
+ end
18
+
19
+ end
20
+
@@ -0,0 +1,16 @@
1
+ require 'helper'
2
+ require 'immortal_julius'
3
+
4
+ describe "immortal julius" do
5
+
6
+ before do
7
+ reset_test_db!
8
+ end
9
+
10
+ it "should be an immortal julius" do
11
+ test_julius_immortal
12
+ end
13
+
14
+ end
15
+
16
+
@@ -0,0 +1,22 @@
1
+ require_relative File.join('..', 'helper')
2
+ require 'marriage_improvement'
3
+
4
+ describe "with improved marriage" do
5
+
6
+ before do
7
+ reset_test_db!
8
+ end
9
+
10
+ it "should make the improved marriage" do
11
+ test_improved_marriage()
12
+ end
13
+
14
+ it "should make the improved marriage with shortcuts" do
15
+ test_improved_marriage_shortcuts()
16
+ end
17
+
18
+ it "should divorce properly" do
19
+ test_improved_marriage_divorce()
20
+ end
21
+ end
22
+
@@ -0,0 +1,18 @@
1
+ require 'helper'
2
+ require 'second_marriage'
3
+
4
+ describe "second marriage" do
5
+
6
+ before do
7
+ reset_test_db!
8
+ end
9
+
10
+ it "make a second marriage" do
11
+ test_second_marriage
12
+ end
13
+
14
+ it "should make a second marriage after conny died" do
15
+ test_second_marriage_after_conny_died()
16
+ end
17
+ end
18
+
data/test/helper.rb ADDED
@@ -0,0 +1,118 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+
11
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ #$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib', 'thingtank'))
14
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'examples'))
15
+ require 'thingtank'
16
+
17
+ require 'minitest/autorun'
18
+
19
+ unless defined?(COUCHHOST)
20
+ COUCHHOST = ENV['COUCH_POTATO_TEST_DB']
21
+ db_config = CouchRest.parse(ENV['COUCH_POTATO_TEST_DB'])
22
+ db_config.delete(:doc)
23
+ protocol, host = db_config.delete(:host).split('://')
24
+ username, *host = host.split(':')
25
+ password, host = host.join(':').split('@')
26
+ host, port = host.split(':')
27
+ DB_CONFIG = db_config.merge :protocol => protocol, :host => host, :username => username, :port => port, :password => password
28
+ #p [COUCHHOST, DB_CONFIG]
29
+
30
+ DB = CouchRest.database COUCHHOST
31
+ end
32
+
33
+ CouchRest::Model::Base.configure do |config|
34
+ config.connection = DB_CONFIG
35
+ end
36
+
37
+ require 'ruby-debug'
38
+
39
+ class ThingTank
40
+ use_database "test_potato"
41
+ end
42
+
43
+ def reset_test_db!
44
+ ThingTank.database.recreate! rescue nil
45
+ ThingTank.database
46
+ end
47
+
48
+ def create(hsh={})
49
+ doc = ThingTank.create hsh
50
+ doc.save
51
+ doc.reload
52
+ doc
53
+ end
54
+
55
+ def new(hsh={})
56
+ ThingTank.new hsh
57
+ end
58
+
59
+ def load(id)
60
+ "ThingTank".constantize.new(ThingTank.database.get(id), :directly_set_attributes => true) # same as ThingTank.get id
61
+ end
62
+
63
+ class Check < ThingTank::Role
64
+ property :a
65
+ property :c
66
+ property :check_saved
67
+ property :check_updated
68
+ property :check_created
69
+ property :check_destroyed
70
+ property :shared
71
+
72
+ def ping
73
+ "pong"
74
+ end
75
+
76
+ def access_other_role
77
+ checker = database.to_role(Checker)
78
+ checker["checker1"] = "I was here"
79
+ end
80
+
81
+ def set_properties_we_don_t_have
82
+ self["ooops"] = "got it"
83
+ end
84
+
85
+ def set_properties_of_doc
86
+ _doc["ooops"] = "got it"
87
+ end
88
+
89
+ before_save do
90
+ self["check_saved"] = true
91
+ end
92
+
93
+ before_update do
94
+ self["check_updated"] = true
95
+ end
96
+
97
+ before_create do
98
+ self["check_created"] = true
99
+ end
100
+
101
+ before_destroy do
102
+ self["check_destroyed"] = true
103
+ #p :check_destroyed
104
+ true
105
+ end
106
+
107
+ validates_presence_of :a
108
+ end
109
+
110
+ class Checker < ThingTank::Role
111
+ property :shared
112
+ property :checker1
113
+
114
+ end
115
+
116
+ class Testmodel < CouchRest::Model::Base
117
+ end
118
+