flat_hash 0.0.2 → 0.1.0
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.
- 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
|