thingtank 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+