dm-svn 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+ require 'dm-svn'
3
+
4
+ class MockArticle
5
+ include DataMapper::Resource
6
+ include DmSvn::Svn
7
+
8
+ property :id, Serial
9
+ property :title, String
10
+ property :contents, Text, :body_property => true
11
+ end
12
+
13
+ class MockArticleNoSvn
14
+ include DataMapper::Resource
15
+
16
+ property :id, Serial
17
+ property :title, String
18
+ property :contents, Text
19
+ end
20
+
21
+ class MockSyncModel
22
+ include DataMapper::Resource
23
+ include DmSvn::Svn
24
+
25
+ property :id, Serial
26
+ property :title, String
27
+ property :body, Text, :body_property => true
28
+ property :published_at, DateTime
29
+ property :random_number, Integer # because some tests need a non-datetime prop
30
+ end
31
+
32
+ class MockCategory
33
+ include DataMapper::Resource
34
+ include DmSvn::Svn
35
+ has n, :mock_categorized_articles
36
+
37
+ property :id, Serial
38
+ property :title, String
39
+ property :random_number, Integer
40
+ end
41
+
42
+ class MockCategorizedArticle
43
+ include DataMapper::Resource
44
+ include DmSvn::Svn
45
+ belongs_to :mock_category, :svn => true
46
+
47
+ property :id, Serial
48
+ property :title, String
49
+ property :article, String
50
+ property :body, Text, :body_property => true
51
+ property :published_at, DateTime
52
+ property :random_number, Integer # because some tests need a non-datetime prop
53
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe DmSvn::Model do
4
+
5
+ end
@@ -0,0 +1,50 @@
1
+ class MockArticle
2
+ include DataMapper::Resource
3
+ include DmSvn::Svn
4
+
5
+ property :id, Integer, :serial => true
6
+ property :title, String
7
+ property :contents, Text, :body_property => true
8
+ end
9
+
10
+ class MockArticleNoSvn
11
+ include DataMapper::Resource
12
+
13
+ property :id, Integer, :serial => true
14
+ property :title, String
15
+ property :contents, Text
16
+ end
17
+
18
+ class MockSyncModel
19
+ include DataMapper::Resource
20
+ include DmSvn::Svn
21
+
22
+ property :id, Integer, :serial => true
23
+ property :title, String
24
+ property :body, Text, :body_property => true
25
+ property :published_at, DateTime
26
+ property :random_number, Integer # because some tests need a non-datetime prop
27
+ end
28
+
29
+ class MockCategory
30
+ include DataMapper::Resource
31
+ include DmSvn::Svn
32
+ has n, :mock_categorized_articles
33
+
34
+ property :id, Integer, :serial => true
35
+ property :title, String
36
+ property :random_number, Integer
37
+ end
38
+
39
+ class MockCategorizedArticle
40
+ include DataMapper::Resource
41
+ include DmSvn::Svn
42
+ belongs_to :mock_category, :svn => true
43
+
44
+ property :id, Integer, :serial => true
45
+ property :title, String
46
+ property :article, String
47
+ property :body, Text, :body_property => true
48
+ property :published_at, DateTime
49
+ property :random_number, Integer # because some tests need a non-datetime prop
50
+ end
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+ require 'dm-svn/mock_models'
3
+
4
+ describe DmSvn::Svn::Categorized do
5
+ before(:all) do
6
+ DmSvn::Model.auto_migrate!
7
+ MockCategory.auto_migrate!
8
+ MockCategorizedArticle.auto_migrate!
9
+ end
10
+
11
+ before(:each) do
12
+ MockCategory.all.each { |m| m.destroy }
13
+ end
14
+
15
+ describe ".belongs_to" do
16
+ it "should initialize @svn_category" do
17
+ MockCategorizedArticle.instance_variable_get('@svn_category').should ==
18
+ :mock_category
19
+ end
20
+
21
+ it 'should initialize @svn_category_model' do
22
+ MockCategorizedArticle.instance_variable_get('@svn_category_model').should ==
23
+ 'MockCategory'
24
+ end
25
+ end
26
+
27
+ it '.svn_category should get name of category (as method name)' do
28
+ MockCategorizedArticle.svn_category.should == :mock_category
29
+ end
30
+
31
+ it '.svn_category_model should get name of category (as constant)' do
32
+ MockCategorizedArticle.svn_category_model.should == 'MockCategory'
33
+ end
34
+
35
+ describe "#path" do
36
+ before(:each) do
37
+ @article = MockCategorizedArticle.new(:svn_name => 'article')
38
+ @category = MockCategory.new(:svn_name => 'cat/path')
39
+ @article.mock_category = @category
40
+ end
41
+
42
+ it "should append @svn_name to svn_category.path" do
43
+ @article.path.should == 'cat/path/article'
44
+ end
45
+
46
+ it "should return just @svn_name if svn_category.path is blank" do
47
+ @category.path = ''
48
+ @article.path.should == 'article'
49
+ end
50
+
51
+ it "should return just @svn_name if svn_category is nil" do
52
+ @article.mock_category = nil
53
+ @article.path.should == 'article'
54
+ end
55
+ end
56
+
57
+ describe "#path=" do
58
+ before(:each) do
59
+ @article = MockCategorizedArticle.new(:svn_name => 'article')
60
+ @category = MockCategory.create(:svn_name => 'cat/path')
61
+ @article.mock_category = @category
62
+ end
63
+
64
+ it "should move instance to a different category" do
65
+ new_cat = MockCategory.create(:svn_name => 'cat/new')
66
+ @article.path = "cat/new/article"
67
+ @article.mock_category.should == new_cat
68
+ end
69
+
70
+ it "should update @svn_name" do
71
+ @article.path = "cat/path/article2"
72
+ @article.svn_name.should == 'article2'
73
+ end
74
+
75
+ it "should remove any category if only one path level" do
76
+ MockCategory.should_not_receive(:get_or_create)
77
+ @article.path = "article"
78
+ @article.mock_category.should be_nil
79
+ @article.path.should == 'article'
80
+ end
81
+
82
+ it "should ignore leading slash" do
83
+ new_cat = MockCategory.create(:svn_name => 'cat/new')
84
+ MockCategory.should_receive(:get_or_create).with('cat/new')
85
+ @article.path = "//cat/new/article"
86
+ end
87
+
88
+ end
89
+
90
+ describe ".get" do
91
+ it "should get an instance if possible" do
92
+ MockCategorizedArticle.should_receive(:get_by_path).
93
+ with('path/to/name').
94
+ and_return(1)
95
+
96
+ MockCategorizedArticle.get('path/to/name', true) == 1
97
+ end
98
+
99
+ it "should try to get an instance of parent if needed (and get_parent is true)" do
100
+ MockCategorizedArticle.should_receive(:get_by_path).
101
+ with('path/to/name').
102
+ and_return(nil)
103
+
104
+ MockCategory.should_receive(:get_by_path).with('path/to/name').and_return(2)
105
+ MockCategorizedArticle.get('path/to/name', true) == 2
106
+ end
107
+
108
+ it "should not try to get an instance of parent by default" do
109
+ MockCategorizedArticle.should_receive(:get_by_path).
110
+ with('path/to/name').
111
+ and_return(nil)
112
+
113
+ MockCategory.should_not_receive(:get_by_path)
114
+
115
+ MockCategorizedArticle.get('path/to/name').should be_nil
116
+ end
117
+
118
+ end
119
+
120
+ describe ".get_by_path" do
121
+ it "should scope by category" do
122
+ category = mock(MockCategory)
123
+
124
+ MockCategory.should_receive(:first).
125
+ with(:svn_name => 'path/to').
126
+ and_return(category)
127
+
128
+ category.should_receive(:id).and_return(3)
129
+
130
+ MockCategorizedArticle.should_receive(:first).
131
+ with(:svn_name => 'name', :mock_category_id => 3).
132
+ and_return(nil)
133
+
134
+ MockCategorizedArticle.get_by_path('path/to/name')
135
+ end
136
+ end
137
+
138
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ require 'dm-svn/mock_models'
3
+
4
+ describe DmSvn::Svn::Changeset do
5
+ before(:all) do
6
+ DmSvn::Model.auto_migrate!
7
+ end
8
+
9
+ describe "#short_path" do
10
+ before(:each) do
11
+ DmSvn::Model.all.each { |m| m.destroy }
12
+ sync = mock('DmSvn::Svn::Sync')
13
+ @config = DmSvn::Config.new
14
+ @config.extension = nil
15
+ @config.path_from_root = "/articles"
16
+ sync.stub!(:config).and_return @config
17
+ sync.stub!(:model).and_return nil
18
+ sync.stub!(:repos).and_return nil
19
+
20
+ @changeset = DmSvn::Svn::Changeset.new([], 1, '', Time.now, sync)
21
+ end
22
+
23
+ it "should remove 'leading path'" do
24
+ @changeset.__send__(:short_path, "/articles/something").should == "something"
25
+ end
26
+
27
+ it "should remove extension if configured" do
28
+ @config.extension = 'txt'
29
+ @changeset.__send__(:short_path, "/articles/something.txt").should == "something"
30
+ end
31
+
32
+ it "should not remove other extensions" do
33
+ @config.extension = 'txt'
34
+ @changeset.__send__(:short_path, "/articles/something.jpg").should == "something.jpg"
35
+ end
36
+
37
+ it "should not remove extension if not configured" do
38
+ @changeset.__send__(:short_path, "/articles/something.txt").should == "something.txt"
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,125 @@
1
+ require 'spec_helper'
2
+ require 'dm-svn/mock_models'
3
+
4
+ describe DmSvn::Svn::Node do
5
+ before(:all) do
6
+ @repos_uri = load_svn_fixture('articles_comments')
7
+
8
+ DmSvn::Model.auto_migrate!
9
+ @ws_model = DmSvn::Model.create(:name => 'MockSyncModel', :revision => 0)
10
+ @ws_model.config = DmSvn::Config.new
11
+ @ws_model.config.uri = @repos_uri
12
+ @sync = DmSvn::Svn::Sync.new(@ws_model)
13
+ @sync.__send__(:connect, @repos_uri)
14
+
15
+ @cs = @sync.changesets[1] # revision 2
16
+ @cs3 = @sync.changesets[2] # revision 9
17
+ @cs9 = @sync.changesets[7] # revision 9
18
+ @dir = DmSvn::Svn::Node.new(@cs, "/articles")
19
+ @file = DmSvn::Svn::Node.new(@cs3, "/articles/unpublished.txt")
20
+ end
21
+
22
+ after(:all) do
23
+ SvnFixture::Repository.destroy_all
24
+ end
25
+
26
+ it "should get short_path" do
27
+ @file.short_path.should == "unpublished"
28
+ end
29
+
30
+ it "should check if file" do
31
+ @dir.file?.should be_false
32
+ @file.file?.should be_true
33
+ end
34
+
35
+ it "should check if directory" do
36
+ @dir.directory?.should be_true
37
+ @file.directory?.should be_false
38
+ end
39
+
40
+ it "should get body" do
41
+ @dir.body.should be_nil
42
+ @file.body.should == "See, it's not published.\nYou can't read it."
43
+ end
44
+
45
+ it "should remove yaml from body" do
46
+ DmSvn::Svn::Node.new(@cs9, "/articles/turtle.txt").body.should == 'Hi, turtle.'
47
+ end
48
+
49
+ describe "#properties" do
50
+ it "should get properties from svn properties" do
51
+ @dir.properties.should ==
52
+ {
53
+ 'svn_updated_at' => @dir.date,
54
+ 'svn_updated_by' => @dir.author,
55
+ 'svn_updated_rev' => @dir.revision,
56
+ 'title' => 'Articles'
57
+ }
58
+
59
+ @file.properties.should ==
60
+ {
61
+ 'svn_updated_at' => @file.date,
62
+ 'svn_updated_by' => @file.author,
63
+ 'svn_updated_rev' => @file.revision,
64
+ 'title' => 'Private Thoughts'
65
+ }
66
+
67
+ end
68
+
69
+ it "should get properties from yaml properties" do
70
+ dir9 = DmSvn::Svn::Node.new(@cs9, "/articles")
71
+ dir9.properties.should ==
72
+ {
73
+ 'svn_updated_at' => dir9.date,
74
+ 'svn_updated_by' => dir9.author,
75
+ 'svn_updated_rev' => dir9.revision,
76
+ 'title' => 'Lots of Articles',
77
+ 'random_number' => 7
78
+ }
79
+
80
+ file9 = DmSvn::Svn::Node.new(@cs9, "/articles/turtle.txt")
81
+ file9.properties.should ==
82
+ {
83
+ 'svn_updated_at' => file9.date,
84
+ 'svn_updated_by' => file9.author,
85
+ 'svn_updated_rev' => file9.revision,
86
+ 'title' => 'Turtle',
87
+ 'random_number' => 2
88
+ }
89
+
90
+ end
91
+ end
92
+
93
+ describe "variables from changeset" do
94
+ before(:each) do
95
+ @cs = mock(DmSvn::Svn::Changeset)
96
+ @node = DmSvn::Svn::Node.new(@cs, 'path')
97
+ end
98
+
99
+ it "should get revision" do
100
+ @cs.should_receive(:revision).and_return(2)
101
+ @node.revision.should == 2
102
+ end
103
+
104
+ it "should get author" do
105
+ @cs.should_receive(:author).and_return('jmorgan')
106
+ @node.author.should == 'jmorgan'
107
+ end
108
+
109
+ it "should get date" do
110
+ @cs.should_receive(:date).and_return('2008-05-10')
111
+ @node.date.should == '2008-05-10'
112
+ end
113
+
114
+ it "should get repos" do
115
+ @cs.should_receive(:repos).and_return(:repos)
116
+ @node.repos.should == :repos
117
+ end
118
+
119
+ it "should get config" do
120
+ @cs.should_receive(:config).and_return(:config)
121
+ @node.config.should == :config
122
+ end
123
+ end
124
+
125
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+ require 'dm-svn/mock_models'
3
+
4
+ describe DmSvn::Svn::Sync do
5
+ after(:all) do
6
+ SvnFixture::Repository.destroy_all
7
+ end
8
+
9
+ describe "#run" do
10
+ before(:all) do
11
+ DmSvn::Model.auto_migrate!
12
+ MockSyncModel.auto_migrate!
13
+ @repos_uri = load_svn_fixture('articles_comments')
14
+ end
15
+
16
+ before(:each) do
17
+ MockSyncModel.all.each { |m| m.destroy }
18
+ DmSvn::Model.all.each { |m| m.destroy }
19
+ @ws_model = DmSvn::Model.create(:name => 'MockSyncModel', :revision => 0)
20
+ @ws_model.config = DmSvn::Config.new
21
+ @ws_model.config.uri = @repos_uri
22
+ @sync = DmSvn::Svn::Sync.new(@ws_model)
23
+ end
24
+
25
+ # This is a generic "it should just work" test
26
+ it "should update database" do
27
+ @sync.run
28
+ MockSyncModel.count.should == 4
29
+
30
+ comp = MockSyncModel.first(:svn_name => "computations")
31
+ comp.body.should == 'Computers do not like salsa very much.'
32
+ comp.svn_updated_rev.to_i.should == 7
33
+ comp.svn_created_rev.to_i.should == 7
34
+
35
+ phil = MockSyncModel.first(:svn_name => "philosophy")
36
+ phil.svn_updated_rev.to_i.should == 2
37
+ phil.svn_created_rev.to_i.should == 2
38
+
39
+ pub = MockSyncModel.first(:svn_name => "just_published")
40
+ published_time = Time.parse(pub.published_at.strftime("%Y-%m-%d %H:%M:%S"))
41
+ published_time.should be_close(Time.now - 3600, 100)
42
+ pub.svn_created_by.should == "author"
43
+ pub.title.should == "Private Thoughts"
44
+ pub.svn_updated_rev.to_i.should == 7
45
+ pub.svn_created_rev.to_i.should == 3
46
+
47
+ MockSyncModel.first(:svn_name => "computers.txt").should be_nil
48
+ end
49
+
50
+ it "should update DmSvn::Model entry" do
51
+ @sync.run
52
+ DmSvn::Model.get(@ws_model.id).revision.should == 9
53
+ end
54
+
55
+ it "should return false if already at the youngest revision" do
56
+ @sync.run.should be_true
57
+ @ws_model = DmSvn::Model.get(@ws_model.id)
58
+ @ws_model.config = DmSvn::Config.new
59
+ @ws_model.config.uri = @repos_uri
60
+ @sync = DmSvn::Svn::Sync.new(@ws_model)
61
+ @sync.run.should be_false
62
+ end
63
+ end
64
+
65
+ describe "#run (categorized)" do
66
+ before(:all) do
67
+ DmSvn::Model.auto_migrate!
68
+ MockCategory.auto_migrate!
69
+ MockCategorizedArticle.auto_migrate!
70
+ @repos_uri = load_svn_fixture('articles_comments')[0..-10]
71
+ end
72
+
73
+ before(:each) do
74
+ MockCategory.all.each { |m| m.destroy }
75
+ MockCategorizedArticle.all.each { |m| m.destroy }
76
+ DmSvn::Model.all.each { |m| m.destroy }
77
+ @ws_model = DmSvn::Model.create(:name => 'MockCategorizedArticle', :revision => 0)
78
+ @ws_model.config = DmSvn::Config.new
79
+ @ws_model.config.uri = @repos_uri
80
+ @sync = DmSvn::Svn::Sync.new(@ws_model)
81
+ end
82
+
83
+ it "should update database, when categorized" do
84
+ @sync.run
85
+
86
+ MockCategory.count.should == 2
87
+ MockCategorizedArticle.count.should == 6
88
+
89
+ comp = MockCategorizedArticle.first(:svn_name => "computations")
90
+ comp.body.should == 'Computers do not like salsa very much.'
91
+ comp.svn_updated_rev.to_i.should == 7
92
+ comp.svn_created_rev.to_i.should == 7
93
+
94
+ phil = MockCategorizedArticle.first(:svn_name => "philosophy")
95
+ phil.svn_updated_rev.to_i.should == 2
96
+ phil.svn_created_rev.to_i.should == 2
97
+
98
+ MockCategorizedArticle.first(:svn_name => "computers.txt").should be_nil
99
+
100
+ articles = MockCategory.first(:svn_name => "articles")
101
+ articles.mock_categorized_articles.length.should == 4
102
+ comp.mock_category.id.should == articles.id
103
+ articles.title.should == "Lots of Articles"
104
+
105
+ comments = MockCategory.first(:svn_name => "comments")
106
+ comments.mock_categorized_articles.length.should == 2
107
+ end
108
+
109
+ end
110
+
111
+ end