soup 1.0.8 → 1.0.9

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.8"
24
+ s.version = "1.0.9"
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,8 @@ 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("kintama")
44
+ s.add_development_dependency("kintama", ">= 0.1.8")
45
+ s.add_development_dependency("rake")
45
46
  end
46
47
 
47
48
  # This task actually builds the gem. We also regenerate a static
@@ -0,0 +1,25 @@
1
+ class Soup
2
+ module Backends
3
+ class Memory < Base
4
+ def prepare
5
+ @snips = {}
6
+ end
7
+
8
+ def save_snip(attributes)
9
+ @snips[attributes[:name]] = Snip.new(attributes, self)
10
+ end
11
+
12
+ def all_snips
13
+ @snips.values
14
+ end
15
+
16
+ def load_snip(name)
17
+ @snips[name]
18
+ end
19
+
20
+ def destroy(name)
21
+ @snips[name] = nil
22
+ end
23
+ end
24
+ end
25
+ end
@@ -18,6 +18,10 @@ class Soup
18
18
  nil
19
19
  end
20
20
 
21
+ def respond_to?(method)
22
+ super || @backends.inject(false) { |ok, b| ok || b.respond_to?(method) }
23
+ end
24
+
21
25
  def all_snips
22
26
  @backends.map { |b| b.all_snips }.flatten
23
27
  end
@@ -12,6 +12,10 @@ class Soup
12
12
  def method_missing(*args)
13
13
  @backend.__send__(*args) if @backend.respond_to?(args.first)
14
14
  end
15
+
16
+ def respond_to?(method)
17
+ super || @backend.respond_to?(method)
18
+ end
15
19
  end
16
20
  end
17
21
  end
data/lib/soup/backends.rb CHANGED
@@ -11,5 +11,6 @@ class Soup
11
11
  autoload :MultiSoup, 'soup/backends/multi_soup'
12
12
  autoload :ReadOnly, 'soup/backends/read_only'
13
13
  autoload :FileBackend, 'soup/backends/file_backend'
14
+ autoload :Memory, 'soup/backends/memory'
14
15
  end
15
16
  end
data/lib/soup/snip.rb CHANGED
@@ -23,6 +23,10 @@ class Soup
23
23
  other.is_a?(Snip) && matching_attributes(other)
24
24
  end
25
25
 
26
+ def eql?(other)
27
+ self == other
28
+ end
29
+
26
30
  def inspect
27
31
  keys = @attributes.keys.dup
28
32
  keys.delete(:name)
@@ -30,6 +34,10 @@ class Soup
30
34
  "<Snip #{attrs.map { |(key,value)| "#{key}:#{value.inspect}"}.join(" ")}>"
31
35
  end
32
36
 
37
+ def hash
38
+ @attributes.hash
39
+ end
40
+
33
41
  def respond_to?(method)
34
42
  @attributes.keys.include?(method.to_s)
35
43
  end
@@ -0,0 +1,9 @@
1
+ class Soup
2
+ module TestHelper
3
+ def stub_soup(*snips)
4
+ soup = Soup.new(Soup::Backends::Memory.new)
5
+ snips.each { |s| soup << s }
6
+ soup
7
+ end
8
+ end
9
+ end
data/lib/soup.rb CHANGED
@@ -7,10 +7,14 @@ require 'fileutils'
7
7
  class Soup
8
8
  autoload :Backends, 'soup/backends'
9
9
  autoload :Snip, 'soup/snip'
10
+ autoload :TestHelper, 'soup/test_helper'
11
+
12
+ class BackendIncompatibleError < StandardError; end
10
13
 
11
14
  # Get the soup ready!
12
15
  def initialize(backend=nil)
13
16
  @backend = backend || Soup::Backends::FileBackend.new
17
+ check_backend_for_compatibility
14
18
  @backend.prepare
15
19
  end
16
20
 
@@ -50,6 +54,12 @@ class Soup
50
54
 
51
55
  private
52
56
 
57
+ def check_backend_for_compatibility
58
+ methods = [:all_snips, :load_snip, :save_snip, :prepare, :destroy]
59
+ ok = methods.inject(true) { |ok, method| ok && @backend.respond_to?(method) }
60
+ raise BackendIncompatibleError unless ok
61
+ end
62
+
53
63
  def symbolize_keys(hash)
54
64
  hash.inject({}) { |h,(k,v)| h[k.to_sym] = v; h }
55
65
  end
data/test/soup_test.rb CHANGED
@@ -1,11 +1,36 @@
1
1
  require "test_helper"
2
2
 
3
+ describe Soup do
4
+ context "checking backend compatibility" do
5
+ REQUIRED_METHODS = [:all_snips, :load_snip, :prepare, :save_snip, :destroy]
6
+
7
+ def backend_without(method_name)
8
+ methods = REQUIRED_METHODS - [method_name]
9
+ Class.new do
10
+ methods.each do |method|
11
+ define_method method do
12
+ end
13
+ end
14
+ end.new
15
+ end
16
+
17
+ REQUIRED_METHODS.each do |method|
18
+ should "ensure #{method} is implemented" do
19
+ assert_raises Soup::BackendIncompatibleError do
20
+ Soup.new(backend_without(method))
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
3
27
  def each_backend(&block)
4
28
  base_path = File.join(File.dirname(__FILE__), *%w[.. tmp soup])
5
29
  backends = [
6
30
  yaml_backend = Soup::Backends::YAMLBackend.new(base_path),
7
31
  file_backend = Soup::Backends::FileBackend.new(base_path),
8
- Soup::Backends::MultiSoup.new(yaml_backend)
32
+ Soup::Backends::MultiSoup.new(yaml_backend),
33
+ Soup::Backends::Memory.new
9
34
  ]
10
35
  backends.each do |backend|
11
36
  describe backend.class do
@@ -50,7 +75,7 @@ each_backend do
50
75
  end
51
76
 
52
77
  should "return an array if more than one snip matches" do
53
- assert_equal [@james, @murray], @soup[:powers => 'yes']
78
+ assert_same_elements [@james, @murray].map { |s| s.name }, @soup[:powers => 'yes'].map { |s| s.name }
54
79
  end
55
80
 
56
81
  should "return an empty array if no matching snips exist" do
@@ -0,0 +1,21 @@
1
+ describe Soup::TestHelper do
2
+ include Soup::TestHelper
3
+
4
+ setup do
5
+ @soup = stub_soup({:name => "a", :kind => "x"},
6
+ {:name => "b", :kind => "y"},
7
+ {:name => "c", :kind => "x"})
8
+ end
9
+
10
+ should "allow stubbing of all snips" do
11
+ assert_same_elements %w(a b c), @soup.all_snips.map { |s| s.name }
12
+ end
13
+
14
+ should "stub loading a snip by name" do
15
+ assert_equal "a", @soup["a"].name
16
+ end
17
+
18
+ should "stub loading snips by criteria" do
19
+ assert_same_elements %w(a c), @soup[:kind => "x"].map { |s| s.name }
20
+ end
21
+ 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: 7
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 8
10
- version: 1.0.8
9
+ - 9
10
+ version: 1.0.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - James Adam
@@ -15,13 +15,27 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-12 00:00:00 +01:00
18
+ date: 2011-07-29 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: kintama
22
+ version_requirements: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ hash: 11
28
+ segments:
29
+ - 0
30
+ - 1
31
+ - 8
32
+ version: 0.1.8
33
+ type: :development
23
34
  prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
35
+ requirement: *id001
36
+ name: kintama
37
+ - !ruby/object:Gem::Dependency
38
+ version_requirements: &id002 !ruby/object:Gem::Requirement
25
39
  none: false
26
40
  requirements:
27
41
  - - ">="
@@ -31,7 +45,9 @@ dependencies:
31
45
  - 0
32
46
  version: "0"
33
47
  type: :development
34
- version_requirements: *id001
48
+ prerelease: false
49
+ requirement: *id002
50
+ name: rake
35
51
  description:
36
52
  email: james@lazyatom.com
37
53
  executables: []
@@ -49,14 +65,17 @@ files:
49
65
  - test/snip_test.rb
50
66
  - test/soup_test.rb
51
67
  - test/test_helper.rb
68
+ - test/test_helper_test.rb
52
69
  - lib/soup/backends/base.rb
53
70
  - lib/soup/backends/file_backend.rb
71
+ - lib/soup/backends/memory.rb
54
72
  - lib/soup/backends/multi_soup.rb
55
73
  - lib/soup/backends/read_only.rb
56
74
  - lib/soup/backends/yaml_backend.rb
57
75
  - lib/soup/backends.rb
58
76
  - lib/soup/empty_class.rb
59
77
  - lib/soup/snip.rb
78
+ - lib/soup/test_helper.rb
60
79
  - lib/soup.rb
61
80
  has_rdoc: true
62
81
  homepage: http://lazyatom.com