soup 1.0.3 → 1.0.4

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/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