zeng 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGE +3 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +89 -0
- data/Rakefile +37 -0
- data/TODOLIST +5 -0
- data/init.rb +4 -0
- data/lib/cute_kv/adapters/light_cloud.rb +22 -0
- data/lib/cute_kv/adapters/tokyo_cabinet.rb +33 -0
- data/lib/cute_kv/adapters/tokyo_tyrant.rb +22 -0
- data/lib/cute_kv/associations.rb +285 -0
- data/lib/cute_kv/connector.rb +27 -0
- data/lib/cute_kv/document.rb +328 -0
- data/lib/cute_kv/ext/string.rb +34 -0
- data/lib/cute_kv/ext/symbol.rb +9 -0
- data/lib/cute_kv/indexer.rb +102 -0
- data/lib/cute_kv/serialization.rb +95 -0
- data/lib/cute_kv/serializers/json_serializer.rb +75 -0
- data/lib/cute_kv/serializers/xml_serializer.rb +325 -0
- data/lib/cute_kv/timestamp.rb +56 -0
- data/lib/cute_kv/validations.rb +68 -0
- data/lib/cutekv.rb +17 -0
- data/spec/asso.yml +23 -0
- data/spec/asso_sin_plural.yml +36 -0
- data/spec/case/associations_test.rb +313 -0
- data/spec/case/document_docking_test.rb +103 -0
- data/spec/case/document_test.rb +184 -0
- data/spec/case/indexer_test.rb +40 -0
- data/spec/case/serialization_test.rb +78 -0
- data/spec/case/sin_plu_dic_test.rb +29 -0
- data/spec/case/symmetry_test.rb +80 -0
- data/spec/case/timestamp_test.rb +65 -0
- data/spec/case/validations_test.rb +74 -0
- data/spec/helper.rb +29 -0
- data/spec/light_cloud.yml +9 -0
- data/spec/model/Account.rb +5 -0
- data/spec/model/Book.rb +6 -0
- data/spec/model/Friend.rb +4 -0
- data/spec/model/Icon.rb +5 -0
- data/spec/model/Project.rb +5 -0
- data/spec/model/Topic.rb +26 -0
- data/spec/model/User.rb +6 -0
- data/tags +322 -0
- metadata +124 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','helper')
|
2
|
+
ModelDivider.divide "User"
|
3
|
+
User.assign(:name, :email, :gender=>"male", :age=>25)
|
4
|
+
User.add_timestamps
|
5
|
+
|
6
|
+
CuteKV::Associations::map(User=>:friends)
|
7
|
+
CuteKV::Associations::map(User=>[:wife,:husband])
|
8
|
+
|
9
|
+
class SerializationTest < Test::Unit::TestCase
|
10
|
+
def setup
|
11
|
+
User.clear
|
12
|
+
@jim = User.create(:name=>"jim")
|
13
|
+
@jack = User.create(:name=>"jack")
|
14
|
+
@kame = User.create(:name=>"kame")
|
15
|
+
@nacy = User.create(:name=>"nancy")
|
16
|
+
@aaron = User.create(:name=>"aaron")
|
17
|
+
@rita = User.create(:name=>"rita")
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_to_json
|
21
|
+
jim = User.new(:name=>"jim")
|
22
|
+
assert jim.to_json =~ /"name":"jim"/
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def test_to_json_include_has_many
|
27
|
+
|
28
|
+
@jim.friends << @jack
|
29
|
+
@jim.friends << @kame
|
30
|
+
@jim.friends << @nancy
|
31
|
+
|
32
|
+
assert_equal @jim.to_json(:include=>:friends).grep(/kame/).empty?,false
|
33
|
+
assert_equal @kame.to_json(:include=>:friends).grep(/jim/).empty?,false
|
34
|
+
assert_equal @jack.to_json(:include=>:friends).grep(/jim/).empty?,false
|
35
|
+
assert_equal @jim.to_json(:only=>:name),{"name"=>@jim.name}.to_json
|
36
|
+
assert_equal @jim.to_json(:except=>[:name,:email] ),{"gender"=>@jim.gender, "age"=>@jim.age, "id"=>@jim.id, "created_at"=>@jim.created_at, "updated_at"=>@jim.updated_at}.to_json
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_array_to_json_include_has_many_this_test_has_some_problem
|
40
|
+
@jim.friends << @kame
|
41
|
+
@jim.friends << @jack
|
42
|
+
@jack.friends << @kame
|
43
|
+
assert_nothing_raised do
|
44
|
+
@jim.friends.to_json(:include=>:friends)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_to_json_include_has_one
|
49
|
+
|
50
|
+
@aaron.wife = @rita
|
51
|
+
|
52
|
+
assert_equal @aaron.to_json(:include=>:wife).grep(/rita/).empty?,false
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
def test_to_xml
|
59
|
+
assert @aaron.to_xml
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_to_xml_include_has_many
|
63
|
+
@jim.friends << @jack
|
64
|
+
@jim.friends << @kame
|
65
|
+
assert_equal @jim.to_xml(:include=>:friends).grep(/jack/).empty?,false
|
66
|
+
assert_equal @jim.to_xml(:include=>:friends).grep(/kame/).empty?,false
|
67
|
+
assert_equal @jack.to_xml(:include=>:friends).grep(/jim/).empty?,false
|
68
|
+
assert_equal @kame.to_xml(:include=>:friends).grep(/jim/).empty?,false
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_to_xml_include_has_one
|
72
|
+
|
73
|
+
@aaron.wife = @rita
|
74
|
+
assert_equal @aaron.to_xml(:include=>:wife).grep(/rita/).empty?,false
|
75
|
+
assert_equal @rita.to_xml(:include=>:husband).grep(/rita/).empty?,false
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','helper')
|
2
|
+
|
3
|
+
class SinguPluralDic < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_singu_plural
|
9
|
+
assert "books".plural?
|
10
|
+
assert !"books".singular?
|
11
|
+
assert "book".singular?
|
12
|
+
assert !"book".plural?
|
13
|
+
Dic::SIN_WORDS.add("books")
|
14
|
+
assert "books".singular?
|
15
|
+
assert !"books".plural?
|
16
|
+
Dic::PLU_WORDS.add("books")
|
17
|
+
assert !"books".singular?
|
18
|
+
assert "books".plural?
|
19
|
+
Dic::PLU_WORDS.add("book")
|
20
|
+
assert !"book".singular?
|
21
|
+
assert "book".plural?
|
22
|
+
Dic::SIN_WORDS.add(["book", "dogs"])
|
23
|
+
assert !"book".plural?
|
24
|
+
assert "book".singular?
|
25
|
+
assert "dogs".singular?
|
26
|
+
assert !"dogs".plural?
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','helper')
|
2
|
+
ModelDivider.divide "User", "Icon", "Friend", "Project"
|
3
|
+
|
4
|
+
class Symmetry
|
5
|
+
attr_reader :assos
|
6
|
+
|
7
|
+
def initialize(asso={})
|
8
|
+
@asso_string = parse(asso)
|
9
|
+
@assos = @asso_string.split("#")
|
10
|
+
end
|
11
|
+
|
12
|
+
def mirror(object)
|
13
|
+
m_o = @assos[@assos.size - 1 - @assos.index(object.to_s)]
|
14
|
+
m_o = m_o.constantize if object.is_a? Class
|
15
|
+
m_o = m_o.to_sym if object.is_a? Symbol
|
16
|
+
m_o
|
17
|
+
end
|
18
|
+
|
19
|
+
def each
|
20
|
+
asso = [[@assos[0].constantize, @assos[1].to_sym ],[@assos[-1].constantize, @assos[-2].to_sym]].uniq
|
21
|
+
asso.each {|a| yield a[0], a[-1]}
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def parse(asso={})
|
26
|
+
keys = asso.keys
|
27
|
+
values = asso.values.flatten
|
28
|
+
"#{keys[0]}##{values[0]}##{values[-1]}##{keys[-1]}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class SymmetryTest < Test::Unit::TestCase
|
33
|
+
|
34
|
+
def setup
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_a_new_symmetry
|
38
|
+
assert wh = Symmetry.new(User=>[:wife, :husband])
|
39
|
+
assert f = Symmetry.new(User=>:friends)
|
40
|
+
assert ui = Symmetry.new(User=>:icon, Icon=>:user)
|
41
|
+
assert up = Symmetry.new(User=>:projects, Project=>:members)
|
42
|
+
assert_equal wh.mirror(User), User
|
43
|
+
assert_equal wh.mirror(:wife), :husband
|
44
|
+
assert_equal wh.mirror(:husband), :wife
|
45
|
+
assert_equal f.mirror(User), User
|
46
|
+
assert_equal f.mirror(:friends), :friends
|
47
|
+
assert_equal ui.mirror(User), Icon
|
48
|
+
assert_equal ui.mirror(Icon), User
|
49
|
+
assert_equal ui.mirror(:icon), :user
|
50
|
+
assert_equal ui.mirror(:user), :icon
|
51
|
+
assert_equal up.mirror(User), Project
|
52
|
+
assert_equal up.mirror(Project), User
|
53
|
+
assert_equal up.mirror(:projects), :members
|
54
|
+
assert_equal up.mirror(:members), :projects
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_symmetry_each
|
58
|
+
assert wh = Symmetry.new(User=>[:wife, :husband])
|
59
|
+
wh.each {|c, m|
|
60
|
+
assert_equal c, User
|
61
|
+
assert [:wife, :husband].include?(m)
|
62
|
+
}
|
63
|
+
assert f = Symmetry.new(User=>:friends)
|
64
|
+
f.each {|c, m|
|
65
|
+
assert_equal c, User
|
66
|
+
assert_equal m, :friends
|
67
|
+
}
|
68
|
+
assert ui = Symmetry.new(User=>:icon, Icon=>:user)
|
69
|
+
ui.each {|c, m|
|
70
|
+
}
|
71
|
+
assert up = Symmetry.new(User=>:projects, Project=>:members)
|
72
|
+
up.each {|c, m|
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','helper')
|
2
|
+
ModelDivider.divide "User", "Icon", "Project", "Book"
|
3
|
+
User.add_timestamps
|
4
|
+
Icon.add_timestamps
|
5
|
+
Project.add_timestamps
|
6
|
+
|
7
|
+
class TimestampTest < Test::Unit::TestCase
|
8
|
+
def setup
|
9
|
+
User.clear
|
10
|
+
Icon.clear
|
11
|
+
Project.clear
|
12
|
+
Book.clear
|
13
|
+
@jim = User.create(:name=>"jim")
|
14
|
+
@icon = Icon.create(:name=>"flower")
|
15
|
+
@nonobo = Project.create(:name=>"nonobo")
|
16
|
+
@ruby = Book.create(:name=>"Ruby")
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_time_zone
|
20
|
+
assert_equal User.default_timezone, :utc
|
21
|
+
assert_equal Icon.default_timezone, :utc
|
22
|
+
assert_equal Project.default_timezone, :utc
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_no_timestamp
|
26
|
+
assert_equal @ruby.respond_to?(:created_at), false
|
27
|
+
assert_equal @ruby.respond_to?(:updated_at), false
|
28
|
+
Book.add_timestamps
|
29
|
+
assert_equal @ruby.respond_to?(:created_at), true
|
30
|
+
assert_equal @ruby.respond_to?(:updated_at), true
|
31
|
+
@ruby.save
|
32
|
+
assert_equal @ruby.created_at.class, DateTime
|
33
|
+
assert_equal @ruby.updated_at.class, DateTime
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_created_at
|
37
|
+
assert_equal @jim.created_at.class, DateTime
|
38
|
+
assert_equal @icon.created_at.class, DateTime
|
39
|
+
assert_equal @nonobo.created_at.class, DateTime
|
40
|
+
jim_created_at = @jim.created_at
|
41
|
+
jim_updated_at = @jim.updated_at
|
42
|
+
object_time_test(@jim)
|
43
|
+
object_time_test(@icon)
|
44
|
+
object_time_test(@nonobo)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def object_time_test(object)
|
49
|
+
created_at = object.send :created_at
|
50
|
+
updated_at = object.send :updated_at
|
51
|
+
assert_equal created_at, updated_at
|
52
|
+
object.save
|
53
|
+
sleep 2
|
54
|
+
updated_at2 = object.send :updated_at
|
55
|
+
created_at2 = object.send :created_at
|
56
|
+
assert (updated_at2 > updated_at)
|
57
|
+
assert_equal created_at2, updated_at
|
58
|
+
assert_equal created_at2, created_at
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_no_timestamps
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'..','helper')
|
2
|
+
ModelDivider.divide "User", "Account", "Project"
|
3
|
+
CuteKV::Document::docking(CuteKV::Validations)
|
4
|
+
|
5
|
+
class ValidationsTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
User.clear
|
9
|
+
Account.clear
|
10
|
+
Project.clear
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_validates
|
14
|
+
assert User.respond_to?(:validate)
|
15
|
+
assert Account.respond_to?(:validate)
|
16
|
+
assert Project.respond_to?(:validate)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_validates_presences
|
20
|
+
User.class_eval {
|
21
|
+
validate :name_presences
|
22
|
+
|
23
|
+
def name_presences
|
24
|
+
self.errors.add(:name, "name not blank") if self.name.blank?
|
25
|
+
end
|
26
|
+
}
|
27
|
+
|
28
|
+
@wumin = User.create()
|
29
|
+
assert @wumin.save.nil?
|
30
|
+
assert User.find(@wumin.id).nil?
|
31
|
+
assert_equal @wumin.errors.on(:name), "name not blank"
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_validates_uniq
|
36
|
+
CuteKV::Indexer::map(Account=>:email)
|
37
|
+
Account.class_eval {
|
38
|
+
validate :account_should_uniq
|
39
|
+
|
40
|
+
def account_should_uniq
|
41
|
+
a = Account.find_all_by_email(self.email).first
|
42
|
+
self.errors.add(:email, "this email has been registered") if a && a.id != self.id
|
43
|
+
end
|
44
|
+
}
|
45
|
+
@jim = Account.new(:name=>'jim', :email=>'jim@nonobo.com')
|
46
|
+
assert @jim.save
|
47
|
+
Account.indexes << @jim
|
48
|
+
assert @jim.save
|
49
|
+
@jack = Account.new(:name=>'jack', :email=>'jim@nonobo.com')
|
50
|
+
assert @jack.save.nil?
|
51
|
+
assert @jack.errors_message_on(:email) == "this email has been registered"
|
52
|
+
assert Account.find(@jack.id).nil?
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_validates_length
|
56
|
+
Project.class_eval {
|
57
|
+
validate :project_name_should_long_than_8
|
58
|
+
|
59
|
+
def project_name_should_long_than_8
|
60
|
+
errors.add(:name, "project name is too short") if self.name.length < 8
|
61
|
+
end
|
62
|
+
}
|
63
|
+
nonobo_book = Project.create(:name=>"nonobo book")
|
64
|
+
assert nonobo_book.save
|
65
|
+
assert Project.find(nonobo_book.id)
|
66
|
+
nonobo = Project.create(:name=>"nonobo")
|
67
|
+
assert nonobo.save.nil?
|
68
|
+
assert Project.find(nonobo.id).nil?
|
69
|
+
assert_equal nonobo.errors_message_on(:name), "project name is too short"
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), '..','lib','cutekv')
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
|
7
|
+
def uses_mocha(description)
|
8
|
+
require 'rubygems'
|
9
|
+
require 'mocha'
|
10
|
+
yield
|
11
|
+
rescue LoadError
|
12
|
+
$stderr.puts "Skipping #{description} tests. `gem install mocha` and try again."
|
13
|
+
end
|
14
|
+
|
15
|
+
module ModelDivider
|
16
|
+
|
17
|
+
def self.divide(*models)
|
18
|
+
models.size > 1 ? models.each {|model| divide(model)} : require(locate(models))
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
def self.locate(model)
|
23
|
+
File.join(File.dirname(__FILE__), "model", "#{model.to_s}")
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
data/spec/model/Book.rb
ADDED
data/spec/model/Icon.rb
ADDED
data/spec/model/Topic.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
class Topic < ActiveObject::Base
|
2
|
+
attribute :title,:content,:create_time,:user_key,:posts
|
3
|
+
|
4
|
+
before_create do |object|
|
5
|
+
object.create_time = Time.now
|
6
|
+
end
|
7
|
+
|
8
|
+
validates_presence_of :title,:content
|
9
|
+
|
10
|
+
validate_on_create :title_is_wrong_create
|
11
|
+
|
12
|
+
|
13
|
+
def validate_on_create
|
14
|
+
if content == "Mismatch"
|
15
|
+
errors.add("title", "is Content Mismatch")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def title_is_wrong_create
|
20
|
+
errors.add("title", "is Wrong Create") if title == "Wrong Create"
|
21
|
+
end
|
22
|
+
|
23
|
+
def validate_on_update
|
24
|
+
errors.add("title", "is Wrong Update") if title == "Wrong Update"
|
25
|
+
end
|
26
|
+
end
|