flat_hash 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/HISTORY.rdoc +3 -0
- data/Rakefile +10 -0
- data/spec/directory_spec.rb +70 -0
- data/spec/git_spec.rb +24 -0
- data/spec/hg_spec.rb +12 -0
- data/spec/repository_spec.rb +79 -0
- data/spec/serialiser_conversion_spec.rb +25 -0
- data/spec/serialiser_spec.rb +85 -0
- data/spec/spec_helper.rb +52 -0
- data/spec/vcs_spec_shared.rb +78 -0
- metadata +21 -52
data/.gemtest
ADDED
File without changes
|
data/HISTORY.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/spec_helper'
|
2
|
+
|
3
|
+
describe FlatHash::Directory do
|
4
|
+
before do
|
5
|
+
@hash = {'key1'=>'value1', 'key2'=>'value2'}
|
6
|
+
@key = 'somekey'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should initially contain no entries" do
|
10
|
+
in_temp_directory do
|
11
|
+
with_directory do |directory|
|
12
|
+
directory.entries.should == []
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should enumerate keys" do
|
18
|
+
in_temp_directory do
|
19
|
+
with_directory do |directory|
|
20
|
+
directory[@key] = @hash
|
21
|
+
directory.entries.should == [@hash]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should add id to hash" do
|
27
|
+
in_temp_directory do
|
28
|
+
with_directory do |directory|
|
29
|
+
directory[@key] = @hash
|
30
|
+
end
|
31
|
+
with_directory do |directory|
|
32
|
+
directory[@key].id.should == @key
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should expose indexers" do
|
38
|
+
in_temp_directory do
|
39
|
+
with_directory do |directory|
|
40
|
+
directory[@key] = @hash
|
41
|
+
end
|
42
|
+
with_directory do |directory|
|
43
|
+
directory[@key].should == @hash
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should allow entries to be appended" do
|
49
|
+
in_temp_directory do
|
50
|
+
with_directory do |directory|
|
51
|
+
directory << FlatHash::Entry.new(@key, @hash)
|
52
|
+
end
|
53
|
+
with_directory do |directory|
|
54
|
+
directory[@key].should == @hash
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should allow entries to be destroyed" do
|
60
|
+
in_temp_directory do
|
61
|
+
with_directory do |directory|
|
62
|
+
directory.entries.should == []
|
63
|
+
directory << FlatHash::Entry.new(@key, @hash)
|
64
|
+
directory[@key].should == @hash
|
65
|
+
directory.destroy(@key)
|
66
|
+
directory.entries.should == []
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/spec/git_spec.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/spec_helper'
|
2
|
+
require 'vcs_spec_shared'
|
3
|
+
|
4
|
+
require 'flat_hash/git'
|
5
|
+
|
6
|
+
describe FlatHash::Hg do
|
7
|
+
it_should_behave_like "a vcs wrapper"
|
8
|
+
|
9
|
+
def vcs_class
|
10
|
+
FlatHash::Git
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should handle checking for nonexistant paths' do
|
14
|
+
in_vcs_working_directory do |vcs|
|
15
|
+
write 'some content', 'a', 'b', 'c', 'file1'
|
16
|
+
vcs.addremovecommit 'added file1 and file2'
|
17
|
+
|
18
|
+
changeset = vcs.changesets.first
|
19
|
+
vcs.contains?(changeset, 'file1').should be_false
|
20
|
+
vcs.contains?(changeset, 'b/c/file1').should be_false
|
21
|
+
vcs.contains?(changeset, 'a/b/c/file1').should be_true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/spec/hg_spec.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/spec_helper'
|
2
|
+
|
3
|
+
describe FlatHash::Repository do
|
4
|
+
it "should raise exception when no vcs repository is detected" do
|
5
|
+
in_temp_directory do
|
6
|
+
with_repository do |repository|
|
7
|
+
repository.should_not be_vcs_supported
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
shared_examples_for "a repository" do
|
14
|
+
it "should have an initially empty history" do
|
15
|
+
in_vcs_working_directory do |vcs|
|
16
|
+
with_repository do |repository|
|
17
|
+
repository.changesets.should == []
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should detect additions' do
|
23
|
+
in_vcs_working_directory do |vcs|
|
24
|
+
with_repository do |repository|
|
25
|
+
repository['entry'] = {'key' => 'value'}
|
26
|
+
vcs.addremovecommit 'first commit'
|
27
|
+
repository.changesets.size.should == 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should detect deletions' do
|
33
|
+
in_vcs_working_directory do |vcs|
|
34
|
+
with_repository do |repository|
|
35
|
+
repository['entry1'] = {'key' => 'value'}
|
36
|
+
vcs.addremovecommit 'added entry1'
|
37
|
+
|
38
|
+
repository['entry2'] = {'key' => 'value'}
|
39
|
+
vcs.addremovecommit 'added entry2'
|
40
|
+
|
41
|
+
repository['entry1'] = {'key' => 'a different value'}
|
42
|
+
vcs.addremovecommit 'updated entry1'
|
43
|
+
|
44
|
+
repository.destroy 'entry1'
|
45
|
+
vcs.addremovecommit 'removed entry1'
|
46
|
+
|
47
|
+
repository.changesets.size.should == 4
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should detect modifications' do
|
53
|
+
in_vcs_working_directory do |vcs|
|
54
|
+
with_repository do |repository|
|
55
|
+
repository['entry'] = {'key' => 'value'}
|
56
|
+
vcs.addremovecommit 'first commit'
|
57
|
+
repository['entry'] = {'key' => 'value2'}
|
58
|
+
vcs.addremovecommit 'next commit'
|
59
|
+
repository.changesets.size.should == 2
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe FlatHash::Repository, 'git' do
|
66
|
+
it_should_behave_like "a repository"
|
67
|
+
|
68
|
+
def vcs_class
|
69
|
+
FlatHash::Git
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe FlatHash::Repository, 'hg' do
|
74
|
+
it_should_behave_like "a repository"
|
75
|
+
|
76
|
+
def vcs_class
|
77
|
+
FlatHash::Hg
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/spec_helper'
|
2
|
+
|
3
|
+
require 'flat_hash/serialiser'
|
4
|
+
|
5
|
+
describe FlatHash::Serialiser, '#yaml' do
|
6
|
+
before do
|
7
|
+
@serialiser = FlatHash::Serialiser.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def read string
|
11
|
+
@serialiser.read StringIO.new(string)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should detect and deserialise yaml persisted hash" do
|
15
|
+
hash = {'key1' => 'value1', 'key2' => 'value2'}
|
16
|
+
read(hash.to_yaml).should == hash
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should detect and deserialise yaml persisted open struct" do
|
20
|
+
ostruct = OpenStruct.new
|
21
|
+
ostruct.keya = 'valuea'
|
22
|
+
ostruct.keyb = 'valueb'
|
23
|
+
read(ostruct.to_yaml).should == {'keya' => 'valuea', 'keyb' => 'valueb'}
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/spec_helper'
|
2
|
+
|
3
|
+
describe FlatHash::Serialiser, '#read' do
|
4
|
+
before do
|
5
|
+
@serialiser = FlatHash::Serialiser.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def read string
|
9
|
+
@serialiser.read StringIO.new(string)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should read an empty hash when stream is empty" do
|
13
|
+
read('').should == {}
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should read a single line and treat it as a key" do
|
17
|
+
read('key').should == {'key' => ''}
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should read a double line and treat it as a key and value" do
|
21
|
+
read(<<EOF).should == {'key' => 'value'}
|
22
|
+
key
|
23
|
+
value
|
24
|
+
EOF
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should read multiple key value pairs delimited by <----->" do
|
28
|
+
read(<<EOF).should == {'key1' => 'value1', 'key2' => 'value2'}
|
29
|
+
key1
|
30
|
+
value1
|
31
|
+
<----->
|
32
|
+
key2
|
33
|
+
value2
|
34
|
+
EOF
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should read multiple line values" do
|
38
|
+
read(<<EOF).should == {'key1' => "value1line1\nvalue1line2", 'key2' => "value2line1\nvalue2line2"}
|
39
|
+
key1
|
40
|
+
value1line1
|
41
|
+
value1line2
|
42
|
+
<----->
|
43
|
+
key2
|
44
|
+
value2line1
|
45
|
+
value2line2
|
46
|
+
EOF
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe FlatHash::Serialiser, '#write' do
|
51
|
+
before do
|
52
|
+
@serialiser = FlatHash::Serialiser.new
|
53
|
+
end
|
54
|
+
|
55
|
+
def write hash
|
56
|
+
io = StringIO.new
|
57
|
+
@serialiser.write(io, hash)
|
58
|
+
io.flush
|
59
|
+
io.string
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should output empty string ' do
|
63
|
+
write({}).should == ''
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should write single key' do
|
67
|
+
write({'key' => 'value'}).should == <<EOF
|
68
|
+
key
|
69
|
+
value
|
70
|
+
EOF
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should write multiple keys delimited by <-----> in order by key' do
|
74
|
+
write({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}).should == <<EOF
|
75
|
+
key1
|
76
|
+
value1
|
77
|
+
<----->
|
78
|
+
key2
|
79
|
+
value2
|
80
|
+
<----->
|
81
|
+
key3
|
82
|
+
value3
|
83
|
+
EOF
|
84
|
+
end
|
85
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
$: << File.dirname(__FILE__)+'/../lib'
|
2
|
+
$: << File.dirname(__FILE__)
|
3
|
+
|
4
|
+
require 'flat_hash'
|
5
|
+
require 'tempfile'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
def in_temp_directory
|
9
|
+
tempfile = Tempfile.new('')
|
10
|
+
tempdir = tempfile.path
|
11
|
+
tempfile.close!
|
12
|
+
begin
|
13
|
+
FileUtils.mkdir_p tempdir
|
14
|
+
Dir.chdir(tempdir) do
|
15
|
+
yield
|
16
|
+
end
|
17
|
+
ensure
|
18
|
+
FileUtils.rm_rf tempdir
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def sh command, options={}
|
23
|
+
lines=[]
|
24
|
+
IO.popen("#{command} 2>&1") {|io| io.each {|l| lines << l.chomp } }
|
25
|
+
raise "\"#{command}\" failed with status #{$?}: #{lines.join("\n")}" unless $?.success?
|
26
|
+
end
|
27
|
+
|
28
|
+
def in_vcs_working_directory
|
29
|
+
vcs = vcs_class.new
|
30
|
+
in_temp_directory do
|
31
|
+
vcs.init
|
32
|
+
yield vcs
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def with_directory
|
37
|
+
yield FlatHash::Directory.new(FlatHash::Serialiser.new, '.cards')
|
38
|
+
end
|
39
|
+
|
40
|
+
def with_repository
|
41
|
+
yield FlatHash::Repository.new(FlatHash::Serialiser.new, '.cards')
|
42
|
+
end
|
43
|
+
|
44
|
+
def write content, *paths
|
45
|
+
path = File.join(*paths)
|
46
|
+
FileUtils.mkdir_p File.dirname(path)
|
47
|
+
File.open(path, 'w') {|file| file.puts content}
|
48
|
+
end
|
49
|
+
|
50
|
+
def delete *paths
|
51
|
+
FileUtils.rm(File.join(*paths))
|
52
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
puts 'loading'
|
2
|
+
|
3
|
+
shared_examples_for "a vcs wrapper" do
|
4
|
+
it "should initially have no changesets" do
|
5
|
+
in_vcs_working_directory do |vcs|
|
6
|
+
vcs.changesets.size.should == 0
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should retrieve single changeset" do
|
11
|
+
in_vcs_working_directory do |vcs|
|
12
|
+
write 'some content', 'file1'
|
13
|
+
vcs.addremovecommit 'first commit'
|
14
|
+
vcs.changesets.size.should == 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should retrieve details of each changeset" do
|
19
|
+
in_vcs_working_directory do |vcs|
|
20
|
+
write 'some content', 'file1'
|
21
|
+
write 'some different content', 'file2'
|
22
|
+
vcs.addremovecommit 'added file1 and file2'
|
23
|
+
|
24
|
+
write 'some new content', 'file1'
|
25
|
+
delete 'file2'
|
26
|
+
vcs.addremovecommit 'modified file1 and removed file2'
|
27
|
+
|
28
|
+
write 'some recreated content', 'file2'
|
29
|
+
vcs.addremovecommit 'recreated file2'
|
30
|
+
|
31
|
+
third, second, first = vcs.changesets
|
32
|
+
|
33
|
+
vcs.changeset(first).instance_eval do
|
34
|
+
id.should == first
|
35
|
+
additions.should == ['file1', 'file2']
|
36
|
+
deletions.should == []
|
37
|
+
modifications.should == []
|
38
|
+
description.should == 'added file1 and file2'
|
39
|
+
end
|
40
|
+
vcs.files_at(first).should == ['file1', 'file2']
|
41
|
+
vcs.content_at('file1',first).should == 'some content'
|
42
|
+
vcs.content_at('file2',first).should == 'some different content'
|
43
|
+
|
44
|
+
vcs.changeset(second).instance_eval do
|
45
|
+
id.should == second
|
46
|
+
additions.should == []
|
47
|
+
deletions.should == ['file2']
|
48
|
+
modifications.should == ['file1']
|
49
|
+
description.should == 'modified file1 and removed file2'
|
50
|
+
end
|
51
|
+
vcs.files_at(second).should == ['file1']
|
52
|
+
vcs.content_at('file1',second).should == 'some new content'
|
53
|
+
|
54
|
+
vcs.changeset(third).instance_eval do
|
55
|
+
id.should == third
|
56
|
+
additions.should == ['file2']
|
57
|
+
deletions.should == []
|
58
|
+
modifications.should == []
|
59
|
+
description.should == 'recreated file2'
|
60
|
+
end
|
61
|
+
vcs.files_at(third).should == ['file1', 'file2']
|
62
|
+
vcs.content_at('file2', third).should == 'some recreated content'
|
63
|
+
|
64
|
+
vcs.changesets('file1').should == [second, first]
|
65
|
+
vcs.changesets('file2').should == [third, second, first]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should handle retrieving files at any directory depth' do
|
70
|
+
in_vcs_working_directory do |vcs|
|
71
|
+
write 'some content', 'a', 'b', 'c', 'file1'
|
72
|
+
vcs.addremovecommit 'added file1 and file2'
|
73
|
+
changeset = vcs.changesets.first
|
74
|
+
vcs.files_at(changeset, 'a/b/c/d').should == []
|
75
|
+
vcs.files_at(changeset, 'a/b/c').should == ['a/b/c/file1']
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flat_hash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 2
|
10
|
-
version: 0.0.2
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Mark Ryall
|
@@ -15,7 +10,7 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date:
|
13
|
+
date: 2011-02-04 00:00:00 +10:00
|
19
14
|
default_executable:
|
20
15
|
dependencies:
|
21
16
|
- !ruby/object:Gem::Dependency
|
@@ -24,14 +19,9 @@ dependencies:
|
|
24
19
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
20
|
none: false
|
26
21
|
requirements:
|
27
|
-
- -
|
22
|
+
- - ~>
|
28
23
|
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
- 2
|
33
|
-
- 0
|
34
|
-
version: 2.2.0
|
24
|
+
version: "2"
|
35
25
|
type: :runtime
|
36
26
|
version_requirements: *id001
|
37
27
|
- !ruby/object:Gem::Dependency
|
@@ -40,14 +30,9 @@ dependencies:
|
|
40
30
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
31
|
none: false
|
42
32
|
requirements:
|
43
|
-
- -
|
33
|
+
- - ~>
|
44
34
|
- !ruby/object:Gem::Version
|
45
|
-
|
46
|
-
segments:
|
47
|
-
- 0
|
48
|
-
- 8
|
49
|
-
- 7
|
50
|
-
version: 0.8.7
|
35
|
+
version: "0.8"
|
51
36
|
type: :development
|
52
37
|
version_requirements: *id002
|
53
38
|
- !ruby/object:Gem::Dependency
|
@@ -56,32 +41,11 @@ dependencies:
|
|
56
41
|
requirement: &id003 !ruby/object:Gem::Requirement
|
57
42
|
none: false
|
58
43
|
requirements:
|
59
|
-
- -
|
44
|
+
- - ~>
|
60
45
|
- !ruby/object:Gem::Version
|
61
|
-
|
62
|
-
segments:
|
63
|
-
- 1
|
64
|
-
- 3
|
65
|
-
- 0
|
66
|
-
version: 1.3.0
|
46
|
+
version: "2"
|
67
47
|
type: :development
|
68
48
|
version_requirements: *id003
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: gemesis
|
71
|
-
prerelease: false
|
72
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
|
-
requirements:
|
75
|
-
- - "="
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
hash: 25
|
78
|
-
segments:
|
79
|
-
- 0
|
80
|
-
- 0
|
81
|
-
- 3
|
82
|
-
version: 0.0.3
|
83
|
-
type: :development
|
84
|
-
version_requirements: *id004
|
85
49
|
description: |
|
86
50
|
Hash serialisation that writes key/value pairs in a predictable order
|
87
51
|
|
@@ -103,8 +67,19 @@ files:
|
|
103
67
|
- lib/flat_hash/serialiser.rb
|
104
68
|
- lib/flat_hash/vcs.rb
|
105
69
|
- lib/flat_hash.rb
|
70
|
+
- spec/directory_spec.rb
|
71
|
+
- spec/git_spec.rb
|
72
|
+
- spec/hg_spec.rb
|
73
|
+
- spec/repository_spec.rb
|
74
|
+
- spec/serialiser_conversion_spec.rb
|
75
|
+
- spec/serialiser_spec.rb
|
76
|
+
- spec/spec_helper.rb
|
77
|
+
- spec/vcs_spec_shared.rb
|
106
78
|
- README.rdoc
|
107
79
|
- MIT-LICENSE
|
80
|
+
- HISTORY.rdoc
|
81
|
+
- Rakefile
|
82
|
+
- .gemtest
|
108
83
|
has_rdoc: true
|
109
84
|
homepage: http://github.com/markryall/flat_hash
|
110
85
|
licenses: []
|
@@ -119,23 +94,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
119
94
|
requirements:
|
120
95
|
- - ">="
|
121
96
|
- !ruby/object:Gem::Version
|
122
|
-
hash: 3
|
123
|
-
segments:
|
124
|
-
- 0
|
125
97
|
version: "0"
|
126
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
99
|
none: false
|
128
100
|
requirements:
|
129
101
|
- - ">="
|
130
102
|
- !ruby/object:Gem::Version
|
131
|
-
hash: 3
|
132
|
-
segments:
|
133
|
-
- 0
|
134
103
|
version: "0"
|
135
104
|
requirements: []
|
136
105
|
|
137
106
|
rubyforge_project:
|
138
|
-
rubygems_version: 1.
|
107
|
+
rubygems_version: 1.5.0
|
139
108
|
signing_key:
|
140
109
|
specification_version: 3
|
141
110
|
summary: trivial but predictable serialisation for hashes
|