soup 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -21,7 +21,7 @@ spec = Gem::Specification.new do |s|
21
21
 
22
22
  # Change these as appropriate
23
23
  s.name = "soup"
24
- s.version = "1.0.3"
24
+ s.version = "1.0.4"
25
25
  s.summary = "A super-simple data store"
26
26
  s.author = "James Adam"
27
27
  s.email = "james@lazyatom.com"
@@ -41,7 +41,7 @@ spec = Gem::Specification.new do |s|
41
41
  # s.add_dependency("some_other_gem", "~> 0.1.0")
42
42
 
43
43
  # If your tests use any gems, include them here
44
- s.add_development_dependency("shoulda")
44
+ s.add_development_dependency("kintama")
45
45
  end
46
46
 
47
47
  # This task actually builds the gem. We also regenerate a static
@@ -10,12 +10,12 @@ class Soup
10
10
  end
11
11
 
12
12
  def names
13
- Dir[path_for("*")].map { |s| File.basename(s, ".snip") }
13
+ Dir[File.join(@base_path, "*")].map { |s| File.basename(s).split(".").first }
14
14
  end
15
15
 
16
16
  def load_snip(name)
17
- path = path_for(name)
18
- if File.exist?(path)
17
+ path = Dir[File.join(@base_path, "*")].find { |s| File.basename(s).split(".").first == name }
18
+ if path
19
19
  file = File.new(path)
20
20
  data = file.read
21
21
  default_attributes = {:name => name, :updated_at => file.mtime, :created_at => file.mtime}
@@ -27,6 +27,8 @@ class Soup
27
27
  attributes = default_attributes
28
28
  end
29
29
  attributes.update(:content => content) if content && content.length > 0
30
+ extension = File.extname(path).gsub(/^\./, '')
31
+ attributes.update(:extension => extension) if extension != "snip"
30
32
  Snip.new(attributes, self)
31
33
  else
32
34
  nil
@@ -34,7 +36,7 @@ class Soup
34
36
  end
35
37
 
36
38
  def save_snip(attributes)
37
- File.open(path_for(attributes[:name]), 'w') do |f|
39
+ File.open(path_for(attributes[:name], attributes[:extension]), 'w') do |f|
38
40
  attributes_without_content = attributes.dup
39
41
  f.write attributes_without_content.delete(:content)
40
42
  f.write attributes_without_content.to_yaml.gsub(/^---\s/, "\n") if attributes_without_content.any?
@@ -54,12 +56,14 @@ class Soup
54
56
 
55
57
  private
56
58
 
57
- def path_for(name)
58
- File.join(@base_path, name + ".snip")
59
+ def path_for(name, extension=nil)
60
+ snip_extension = ".snip"
61
+ snip_extension += ".#{extension}" if extension
62
+ File.join(@base_path, name + snip_extension)
59
63
  end
60
64
 
61
65
  def all_snips
62
- Dir[path_for("*")].map do |key|
66
+ Dir[File.join(@base_path, "*")].map do |key|
63
67
  load_snip(File.basename(key, ".snip"))
64
68
  end
65
69
  end
@@ -2,15 +2,13 @@ require "test_helper"
2
2
  require "ftools"
3
3
  require "time"
4
4
 
5
- class FileBackendTest < Test::Unit::TestCase
6
- context "The file-based backend" do
7
- setup do
8
- @base_path = File.join(File.dirname(__FILE__), *%w[.. tmp soup])
9
- @soup = Soup.new(Soup::Backends::FileBackend.new(@base_path))
10
- end
5
+ context "The file-based backend" do
6
+ setup do
7
+ @soup = Soup.new(Soup::Backends::FileBackend.new(@base_path))
8
+ end
11
9
 
12
- should "parse attributes from lines starting with colon" do
13
- write_snip "snip", %{
10
+ should "parse attributes from lines starting with colon" do
11
+ write_snip "snip", %{
14
12
  Here is the content
15
13
  of the snip
16
14
 
@@ -20,49 +18,57 @@ of the snip
20
18
  stuff
21
19
  things
22
20
  :blah: yes
23
- }
21
+ }
24
22
 
25
- snip = @soup["snip"]
26
- assert_equal "Here is the content\nof the snip", snip.content
27
- assert_equal "thing", snip.name
28
- end
23
+ snip = @soup["snip"]
24
+ assert_equal "Here is the content\nof the snip", snip.content
25
+ assert_equal "thing", snip.name
26
+ end
29
27
 
30
- should "write a snip in the simple format" do
31
- @soup << {:content => "Here is the content", :name => "dave"}
28
+ should "write a snip in the simple format" do
29
+ @soup << {:content => "Here is the content", :name => "dave"}
30
+ assert_equal %{Here is the content\n\n:name: dave\n}, File.read(path_for("dave"))
31
+ end
32
32
 
33
- assert_equal %{Here is the content\n\n:name: dave\n}, File.read(path_for("dave"))
34
- end
33
+ should "not require snip attributes to give content" do
34
+ write_snip "test", "snip content"
35
+ assert_equal "snip content", @soup["test"].content
36
+ end
35
37
 
36
- should "take name from filename if not supplied" do
37
- write_snip "blahface", "The snip content"
38
- assert_equal "blahface", @soup["blahface"].name
39
- end
38
+ should "take updated_at and created_at from file timestamps if not supplied" do
39
+ @soup << {:name => "snip", :content => "whatever"}
40
+ time = Time.parse("2010-11-04 14:56")
41
+ File.utime(time, time, path_for("snip"))
42
+ end
40
43
 
41
- should "not require snip attributes to give content" do
42
- write_snip "test", "snip content"
43
- assert_equal "snip content", @soup["test"].content
44
- end
44
+ should "take name from filename if not supplied" do
45
+ write_snip "blahface", "The snip content"
46
+ assert_equal "blahface", @soup["blahface"].name
47
+ end
45
48
 
46
- should "take updated_at and created_at from file timestamps if not supplied" do
47
- @soup << {:name => "snip", :content => "whatever"}
48
- time = Time.parse("2010-11-04 14:56")
49
- File.utime(time, time, path_for("snip"))
49
+ should "take updated_at and created_at from file timestamps if not supplied" do
50
+ @soup << {:name => "snip", :content => "whatever"}
51
+ time = Time.parse("2010-11-04 14:56")
52
+ File.utime(time, time, path_for("snip"))
50
53
 
51
- snip = @soup["snip"]
52
- assert_equal time, snip.updated_at
53
- assert_equal time, snip.created_at
54
- end
54
+ snip = @soup["snip"]
55
+ assert_equal time, snip.updated_at
56
+ assert_equal time, snip.created_at
57
+ end
55
58
 
56
- should "take created_at from attributes if supplied" do
57
- created_at = Time.parse("2010-11-04 14:56")
58
- @soup << {:name => "snip", :content => "whatever", :created_at => created_at}
59
+ should "take created_at from attributes if supplied" do
60
+ created_at = Time.parse("2010-11-04 14:56")
61
+ @soup << {:name => "snip", :content => "whatever", :created_at => created_at}
59
62
 
60
- snip = @soup["snip"]
61
- assert_equal created_at.to_i, snip.created_at.to_i
62
- end
63
+ snip = @soup["snip"]
64
+ assert_equal created_at.to_i, snip.created_at.to_i
63
65
  end
64
66
 
65
- private
67
+ should "set the extension attribute if one is present" do
68
+ File.open(File.join(@base_path, "test_snip.snip.markdown"), "w") { |f| f.write "This is the content" }
69
+ snip = @soup["test_snip"]
70
+ assert_equal "markdown", snip.extension
71
+ end
66
72
 
67
73
  def path_for(name)
68
74
  File.join(@base_path, name + ".snip")
@@ -1,76 +1,73 @@
1
1
  require "test_helper"
2
2
 
3
- class MultiSoupBackendTest < Test::Unit::TestCase
4
- context "A Soup with multiple backends" do
5
- setup do
6
- @base_path = File.join(File.dirname(__FILE__), *%w[.. tmp soup])
7
- @basic_soup_backend_one = Soup::Backends::YAMLBackend.new(File.join(@base_path, "soup_one"))
8
- @basic_soup_backend_two = Soup::Backends::FileBackend.new(File.join(@base_path, "soup_two"))
9
- @soup_one = Soup.new(@basic_soup_backend_one)
10
- @soup_two = Soup.new(@basic_soup_backend_two)
11
- multi_soup_backend = Soup::Backends::MultiSoup.new(@basic_soup_backend_one, @basic_soup_backend_two)
12
- @soup = Soup.new(multi_soup_backend)
13
- end
14
-
15
- teardown do
16
- FileUtils.rm_rf(@base_path)
17
- end
3
+ context "A Soup with multiple backends" do
4
+ setup do
5
+ @basic_soup_backend_one = Soup::Backends::YAMLBackend.new(File.join(@base_path, "soup_one"))
6
+ @basic_soup_backend_two = Soup::Backends::FileBackend.new(File.join(@base_path, "soup_two"))
7
+ @soup_one = Soup.new(@basic_soup_backend_one)
8
+ @soup_two = Soup.new(@basic_soup_backend_two)
9
+ multi_soup_backend = Soup::Backends::MultiSoup.new(@basic_soup_backend_one, @basic_soup_backend_two)
10
+ @soup = Soup.new(multi_soup_backend)
11
+ end
18
12
 
19
- should "return nil when the requested snip is not present in any backend" do
20
- assert_nil @soup["snip"]
21
- end
13
+ teardown do
14
+ FileUtils.rm_rf(@base_path)
15
+ end
22
16
 
23
- should "return a snip if any backend contains it" do
24
- @soup_one << {:name => "snip", :body => "hello"}
25
- assert_equal "hello", @soup["snip"].body
17
+ should "return nil when the requested snip is not present in any backend" do
18
+ assert_nil @soup["snip"]
19
+ end
26
20
 
27
- @soup_two << {:name => "other_snip", :body => "hi!"}
28
- assert_equal "hi!", @soup["other_snip"].body
29
- end
21
+ should "return a snip if any backend contains it" do
22
+ @soup_one << {:name => "snip", :body => "hello"}
23
+ assert_equal "hello", @soup["snip"].body
30
24
 
31
- context "when snips of the same name exist in multiple backends" do
32
- setup do
33
- @soup_one << {:name => "snip", :body => "from soup one"}
34
- @soup_two << {:name => "snip", :body => "from soup two"}
35
- end
25
+ @soup_two << {:name => "other_snip", :body => "hi!"}
26
+ assert_equal "hi!", @soup["other_snip"].body
27
+ end
36
28
 
37
- should "load the snip from the backend with the higher precidence" do
38
- assert_equal "from soup one", @soup["snip"].body
39
- end
29
+ context "when snips of the same name exist in multiple backends" do
30
+ setup do
31
+ @soup_one << {:name => "snip", :body => "from soup one"}
32
+ @soup_two << {:name => "snip", :body => "from soup two"}
40
33
  end
41
34
 
42
- context "when snips with a certain attribute exist in multiple backends" do
43
- setup do
44
- @soup_one << {:name => "snip1", :active => true}
45
- @soup_two << {:name => "snip2", :active => true}
46
- end
35
+ should "load the snip from the backend with the higher precidence" do
36
+ assert_equal "from soup one", @soup["snip"].body
37
+ end
38
+ end
47
39
 
48
- should "find matching snips from all backends" do
49
- assert_equal 2, @soup[:active => true].length
50
- end
40
+ context "when snips with a certain attribute exist in multiple backends" do
41
+ setup do
42
+ @soup_one << {:name => "snip1", :active => true}
43
+ @soup_two << {:name => "snip2", :active => true}
51
44
  end
52
45
 
53
- should "save snips" do
54
- @soup << {:name => "snip", :body => "bad snip"}
55
- @soup.destroy("snip")
56
- assert_nil @soup["snip"]
46
+ should "find matching snips from all backends" do
47
+ assert_equal 2, @soup[:active => true].length
57
48
  end
49
+ end
50
+
51
+ should "save snips" do
52
+ @soup << {:name => "snip", :body => "bad snip"}
53
+ @soup.destroy("snip")
54
+ assert_nil @soup["snip"]
55
+ end
58
56
 
59
- context "when a backend is read-only" do
60
- setup do
61
- readonly_backend = Soup::Backends::ReadOnly.new(@basic_soup_backend_one)
62
- @soup_one = Soup.new(readonly_backend)
63
- @soup_two = Soup.new(@basic_soup_backend_two)
64
- multi_soup_backend = Soup::Backends::MultiSoup.new(readonly_backend, @basic_soup_backend_two)
65
- @soup = Soup.new(multi_soup_backend)
66
- end
57
+ context "when a backend is read-only" do
58
+ setup do
59
+ readonly_backend = Soup::Backends::ReadOnly.new(@basic_soup_backend_one)
60
+ @soup_one = Soup.new(readonly_backend)
61
+ @soup_two = Soup.new(@basic_soup_backend_two)
62
+ multi_soup_backend = Soup::Backends::MultiSoup.new(readonly_backend, @basic_soup_backend_two)
63
+ @soup = Soup.new(multi_soup_backend)
64
+ end
67
65
 
68
- should "store snips in the writeable backend" do
69
- @soup << {:name => "snip", :body => "hello"}
70
- assert_equal "hello", @soup["snip"].body
71
- assert_nil @soup_one["snip"]
72
- assert_not_nil @soup_two["snip"]
73
- end
66
+ should "store snips in the writeable backend" do
67
+ @soup << {:name => "snip", :body => "hello"}
68
+ assert_equal "hello", @soup["snip"].body
69
+ assert_nil @soup_one["snip"]
70
+ assert_not_nil @soup_two["snip"]
74
71
  end
75
72
  end
76
73
  end
data/test/snip_test.rb CHANGED
@@ -1,41 +1,38 @@
1
1
  require 'test_helper'
2
2
 
3
- class SnipTest < Test::Unit::TestCase
4
- context "A snip" do
5
- setup do
6
- @snip = Soup::Snip.new({:name => "james", :content => "is awesome"}, nil)
7
- end
3
+ context "A snip" do
4
+ setup do
5
+ @snip = Soup::Snip.new({:name => "james", :content => "is awesome"}, nil)
6
+ end
8
7
 
9
- should "be equal to another snip with the same attributes" do
10
- other_snip = Soup::Snip.new({:name => "james", :content => "is awesome"}, nil)
11
- assert other_snip == @snip
12
- end
8
+ should "be equal to another snip with the same attributes" do
9
+ other_snip = Soup::Snip.new({:name => "james", :content => "is awesome"}, nil)
10
+ assert other_snip == @snip
11
+ end
13
12
 
14
- should "not be equal to another snip with differing attributes" do
15
- other_snip = Soup::Snip.new({:name => "james", :content => "is really awesome"}, nil)
16
- assert other_snip != @snip
17
- end
13
+ should "not be equal to another snip with differing attributes" do
14
+ other_snip = Soup::Snip.new({:name => "james", :content => "is really awesome"}, nil)
15
+ assert other_snip != @snip
16
+ end
18
17
 
19
- should "be comparable in arrays" do
20
- other_snip = Soup::Snip.new({:name => "james", :content => "is awesome"}, nil)
21
- assert [@snip] == [other_snip]
22
- end
18
+ should "be comparable in arrays" do
19
+ other_snip = Soup::Snip.new({:name => "james", :content => "is awesome"}, nil)
20
+ assert [@snip] == [other_snip]
21
+ end
23
22
 
24
- context "loaded from the soup" do
25
- setup do
26
- @base_path = File.join(File.dirname(__FILE__), *%w[.. tmp soup])
27
- backend = Soup::Backends::FileBackend.new(@base_path)
28
- @soup = Soup.new(backend)
29
- end
23
+ context "loaded from the soup" do
24
+ setup do
25
+ backend = Soup::Backends::FileBackend.new(@base_path)
26
+ @soup = Soup.new(backend)
27
+ end
30
28
 
31
- teardown do
32
- FileUtils.rm_rf(@base_path)
33
- end
29
+ teardown do
30
+ FileUtils.rm_rf(@base_path)
31
+ end
34
32
 
35
- should "ignore empty content when comparing" do
36
- @soup << {:name => 'test'}
37
- assert_equal Soup::Snip.new({:name => 'test'}, nil), @soup['test']
38
- end
33
+ should "ignore empty content when comparing" do
34
+ @soup << {:name => 'test'}
35
+ assert_equal Soup::Snip.new({:name => 'test'}, nil), @soup['test']
39
36
  end
40
37
  end
41
38
  end
data/test/soup_test.rb CHANGED
@@ -1,71 +1,68 @@
1
1
  require "test_helper"
2
2
 
3
- class SoupTest < Test::Unit::TestCase
4
-
5
- def self.each_backend(&block)
6
- base_path = File.join(File.dirname(__FILE__), *%w[.. tmp soup])
7
- backends = [
8
- yaml_backend = Soup::Backends::YAMLBackend.new(base_path),
9
- file_backend = Soup::Backends::FileBackend.new(base_path),
10
- Soup::Backends::MultiSoup.new(yaml_backend)
11
- ]
12
- backends.each do |backend|
13
- context "The #{backend.class.name} Soup backend" do
14
- setup do
15
- @soup = Soup.new(backend)
16
- end
17
- teardown do
18
- FileUtils.rm_rf(base_path)
19
- end
20
- yield
3
+ def each_backend(&block)
4
+ base_path = File.join(File.dirname(__FILE__), *%w[.. tmp soup])
5
+ backends = [
6
+ yaml_backend = Soup::Backends::YAMLBackend.new(base_path),
7
+ file_backend = Soup::Backends::FileBackend.new(base_path),
8
+ Soup::Backends::MultiSoup.new(yaml_backend)
9
+ ]
10
+ backends.each do |backend|
11
+ describe backend.class do
12
+ setup do
13
+ @soup = Soup.new(backend)
14
+ end
15
+ teardown do
16
+ FileUtils.rm_rf(base_path)
21
17
  end
18
+ instance_eval(&block)
22
19
  end
23
20
  end
21
+ end
24
22
 
25
- each_backend do
26
- should "be able to store content" do
27
- @soup << {:name => 'test', :content => "I like stuff, and things"}
28
- assert_equal "I like stuff, and things", @soup['test'].content
29
- end
23
+ each_backend do
24
+ should "be able to store content" do
25
+ @soup << {:name => 'test', :content => "I like stuff, and things"}
26
+ assert_equal "I like stuff, and things", @soup['test'].content
27
+ end
30
28
 
31
- should "return a snip when storing content" do
32
- snip = @soup << {:name => 'test', :content => "I like stuff, and things"}
33
- assert_equal "I like stuff, and things", snip.content
34
- end
29
+ should "return a snip when storing content" do
30
+ snip = @soup << {:name => 'test', :content => "I like stuff, and things"}
31
+ assert_equal "I like stuff, and things", snip.content
32
+ end
35
33
 
36
- context "when sieving the soup" do
37
- setup do
38
- @james = @soup << {:name => 'james', :spirit_guide => 'fox', :colour => 'blue', :powers => 'yes'}
39
- @murray = @soup << {:name => 'murray', :spirit_guide => 'chaffinch', :colour => 'red', :powers => 'yes'}
40
- end
34
+ context "when sieving the soup" do
35
+ setup do
36
+ @james = @soup << {:name => 'james', :spirit_guide => 'fox', :colour => 'blue', :powers => 'yes'}
37
+ @murray = @soup << {:name => 'murray', :spirit_guide => 'chaffinch', :colour => 'red', :powers => 'yes'}
38
+ end
41
39
 
42
- should "find snips by name if the parameter is a string" do
43
- assert_equal @james, @soup['james']
44
- end
40
+ should "find snips by name if the parameter is a string" do
41
+ assert_equal @james, @soup['james']
42
+ end
45
43
 
46
- should "find snips using exact matching of keys and values if the parameter is a hash" do
47
- assert_equal @murray, @soup[:name => 'murray']
48
- end
44
+ should "find snips using exact matching of keys and values if the parameter is a hash" do
45
+ assert_equal @murray, @soup[:name => 'murray']
46
+ end
49
47
 
50
- should "match using all parameters" do
51
- assert_equal [@murray], @soup[:powers => 'yes', :colour => 'red']
52
- end
48
+ should "match using all parameters" do
49
+ assert_equal [@murray], @soup[:powers => 'yes', :colour => 'red']
50
+ end
53
51
 
54
- should "return an array if more than one snip matches" do
55
- assert_equal [@james, @murray], @soup[:powers => 'yes']
56
- end
52
+ should "return an array if more than one snip matches" do
53
+ assert_equal [@james, @murray], @soup[:powers => 'yes']
54
+ end
57
55
 
58
- should "return an empty array if no matching snips exist" do
59
- assert_equal [], @soup[:powers => 'maybe']
60
- end
56
+ should "return an empty array if no matching snips exist" do
57
+ assert_equal [], @soup[:powers => 'maybe']
61
58
  end
59
+ end
62
60
 
63
- should "allow deletion of snips" do
64
- snip = @soup << {:name => 'test', :content => 'content'}
65
- assert_equal snip, @soup['test']
61
+ should "allow deletion of snips" do
62
+ snip = @soup << {:name => 'test', :content => 'content'}
63
+ assert_equal snip, @soup['test']
66
64
 
67
- @soup['test'].destroy
68
- assert @soup['test'].nil?
69
- end
65
+ @soup['test'].destroy
66
+ assert @soup['test'].nil?
70
67
  end
71
- end
68
+ end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,8 @@
1
- require 'test/unit'
2
- require 'shoulda'
3
- require 'soup'
1
+ # require 'rubygems'
2
+ $LOAD_PATH.unshift "/Users/james/Code/lazyatom/jtest/lib"
3
+ require 'kintama'
4
+ require 'soup'
5
+
6
+ Kintama.setup do
7
+ @base_path = File.join(File.dirname(__FILE__), *%w[.. tmp soup])
8
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: soup
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 3
10
- version: 1.0.3
9
+ - 4
10
+ version: 1.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - James Adam
@@ -15,11 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-22 00:00:00 +00:00
18
+ date: 2011-03-01 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: shoulda
22
+ name: kintama
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false