[DRE-commits] [ruby-hamster] 01/04: Imported Upstream version 3.0.0

Hanno Zulla hanno-guest at moszumanska.debian.org
Wed Feb 24 11:09:21 UTC 2016


This is an automated email from the git hooks/post-receive script.

hanno-guest pushed a commit to branch master
in repository ruby-hamster.

commit ad04f8aa65015c49ffaef0b5d758c05af7fdbf45
Author: Hanno Zulla <hanno.zulla at epublica.de>
Date:   Wed Feb 24 12:01:15 2016 +0100

    Imported Upstream version 3.0.0
---
 LICENSE                                      | 23 ++++++++
 lib/hamster/associable.rb                    | 22 +++++++
 lib/hamster/enumerable.rb                    |  9 +++
 lib/hamster/hash.rb                          | 85 ++++++++++++++++++++++++++--
 lib/hamster/list.rb                          |  6 +-
 lib/hamster/version.rb                       |  2 +-
 metadata.yml                                 | 25 ++++++--
 spec/lib/hamster/hash/dig_spec.rb            | 32 +++++++++++
 spec/lib/hamster/hash/fetch_values_spec.rb   | 22 +++++++
 spec/lib/hamster/hash/subset_spec.rb         | 42 ++++++++++++++
 spec/lib/hamster/hash/superset_spec.rb       | 42 ++++++++++++++
 spec/lib/hamster/hash/to_proc_spec.rb        | 39 +++++++++++++
 spec/lib/hamster/hash/values_at_spec.rb      | 34 ++++++++---
 spec/lib/hamster/list/multithreading_spec.rb |  2 +-
 spec/lib/hamster/set/grep_spec.rb            | 35 ++++++------
 spec/lib/hamster/set/grep_v_spec.rb          | 59 +++++++++++++++++++
 spec/lib/hamster/vector/dig_spec.rb          | 28 +++++++++
 17 files changed, 469 insertions(+), 38 deletions(-)

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..690a1f8
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,23 @@
+Licensing
+=========
+
+Copyright (c) 2009-2014 Simon Harris
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/lib/hamster/associable.rb b/lib/hamster/associable.rb
index ee2fa82..d960af5 100644
--- a/lib/hamster/associable.rb
+++ b/lib/hamster/associable.rb
@@ -6,6 +6,7 @@ module Hamster
   #
   # * `fetch(index, default = (missing_default = true))`
   # * `put(index, item = yield(get(index)))`
+  # * `get(key)`
   #
   # See {Vector#fetch}, {Vector#put}, {Hash#fetch}, and {Hash#put} for examples.
   module Associable
@@ -45,5 +46,26 @@ module Hamster
       end
       put(key, new_value)
     end
+
+    # Return the value of successively indexing into a collection.
+    # If any of the keys is not present in the collection, return `nil`.
+    # keys that the Hamster type doesn't understand, raises an argument error
+    #
+    # @example
+    #   h = Hamster::Hash[:a => 9, :b => Hamster::Vector['a', 'b'], :e => nil]
+    #   h.dig(:b, 0)    # => "a"
+    #   h.dig(:b, 5)    # => nil
+    #   h.dig(:b, 0, 0) # => nil
+    #   h.dig(:b, :a)   # ArgumentError
+    # @params keys to fetch from the collection
+    # @return [Object]
+    def dig(key, *rest)
+      value = get(key)
+      if rest.empty? || value.nil?
+        value
+      elsif value.respond_to?(:dig)
+        value.dig(*rest)
+      end
+    end
   end
 end
diff --git a/lib/hamster/enumerable.rb b/lib/hamster/enumerable.rb
index 0b98eab..e3faace 100644
--- a/lib/hamster/enumerable.rb
+++ b/lib/hamster/enumerable.rb
@@ -29,6 +29,15 @@ module Hamster
       result
     end
 
+    # Search the collection for elements which are not `#===` to `item`. Yield
+    # them to the optional code block if provided, and return them as a new
+    # collection.
+    def grep_v(pattern, &block)
+      result = select { |item| !(pattern === item) }
+      result = result.map(&block) if block_given?
+      result
+    end
+
     # Yield all integers from 0 up to, but not including, the number of items in
     # this collection. For collections which provide indexed access, these are all
     # the valid, non-negative indices into the collection.
diff --git a/lib/hamster/hash.rb b/lib/hamster/hash.rb
index 466456e..15a944e 100644
--- a/lib/hamster/hash.rb
+++ b/lib/hamster/hash.rb
@@ -559,17 +559,34 @@ module Hamster
     end
 
     # Return a {Vector} of the values which correspond to the `wanted` keys.
-    # If any of the `wanted` keys are not present in this `Hash`, they will be skipped.
+    # If any of the `wanted` keys are not present in this `Hash`, `nil` will be
+    # placed instead, or the result of the default proc (if one is defined),
+    # similar to the behavior of {#get}.
     #
     # @example
     #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
-    #   h.values_at("B", "A", "D")  # => Hamster::Vector[2, 1]
+    #   h.values_at("B", "A", "D")  # => Hamster::Vector[2, 1, nil]
     #
     # @param wanted [Array] The keys to retrieve
     # @return [Vector]
     def values_at(*wanted)
-      array = []
-      wanted.each { |key| array << get(key) if key?(key) }
+      array = wanted.map { |key| get(key) }
+      Vector.new(array.freeze)
+    end
+
+    # Return a {Vector} of the values which correspond to the `wanted` keys.
+    # If any of the `wanted` keys are not present in this `Hash`, raise `KeyError`
+    # exception.
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.fetch_values("C", "A")  # => Hamster::Vector[3, 1]
+    #   h.fetch_values("C", "Z")  # => KeyError: key not found: "Z"
+    #
+    # @param wanted [Array] The keys to retrieve
+    # @return [Vector]
+    def fetch_values(*wanted)
+      array = wanted.map { |key| fetch(key) }
       Vector.new(array.freeze)
     end
 
@@ -723,6 +740,50 @@ module Hamster
       self.eql?(other) || (other.respond_to?(:to_hash) && to_hash.eql?(other.to_hash))
     end
 
+    # Return true if this `Hash` is a proper superset of `other`, which means
+    # all `other`'s keys are contained in this `Hash` with the identical
+    # values, and the two hashes are not identical.
+    #
+    # @param other [Hamster::Hash] The object to compare with
+    # @return [Boolean]
+    def >(other)
+      self != other && self >= other
+    end
+
+    # Return true if this `Hash` is a superset of `other`, which means all
+    # `other`'s keys are contained in this `Hash` with the identical values.
+    #
+    # @param other [Hamster::Hash] The object to compare with
+    # @return [Boolean]
+    def >=(other)
+      other.each do |key, value|
+        if self[key] != value
+          return false
+        end
+      end
+      true
+    end
+
+    # Return true if this `Hash` is a proper subset of `other`, which means all
+    # its keys are contained in `other` with the identical values, and the two
+    # hashes are not identical.
+    #
+    # @param other [Hamster::Hash] The object to compare with
+    # @return [Boolean]
+    def <(other)
+      other > self
+    end
+
+    # Return true if this `Hash` is a subset of `other`, which means all its
+    # keys are contained in `other` with the identical values, and the two
+    # hashes are not identical.
+    #
+    # @param other [Hamster::Hash] The object to compare with
+    # @return [Boolean]
+    def <=(other)
+      other >= self
+    end
+
     # See `Object#hash`.
     # @return [Integer]
     def hash
@@ -782,6 +843,22 @@ module Hamster
     end
     alias :to_h :to_hash
 
+    # Return a Proc which accepts a key as an argument and returns the value.
+    # The Proc behaves like {#get} (when the key is missing, it returns nil or
+    # result of the default proc).
+    #
+    # @example
+    #   h = Hamster::Hash["A" => 1, "B" => 2, "C" => 3]
+    #   h.to_proc.call("B")
+    #   # => 2
+    #   ["A", "C", "X"].map(&h)   # The & is short for .to_proc in Ruby
+    #   # => [1, 3, nil]
+    #
+    # @return [Proc]
+    def to_proc
+      lambda { |key| get(key) }
+    end
+
     # @return [::Hash]
     # @private
     def marshal_dump
diff --git a/lib/hamster/list.rb b/lib/hamster/list.rb
index a79564a..a3fa903 100644
--- a/lib/hamster/list.rb
+++ b/lib/hamster/list.rb
@@ -1311,7 +1311,7 @@ module Hamster
     def initialize(&block)
       @head   = block # doubles as storage for block while yet unrealized
       @tail   = nil
-      @atomic = Concurrent::Atomic.new(0) # haven't yet run block
+      @atomic = Concurrent::AtomicReference.new(0) # haven't yet run block
       @size   = nil
     end
 
@@ -1591,5 +1591,5 @@ module Hamster
         true
       end
     end
-  end
-end.freeze
+  end.freeze
+end
diff --git a/lib/hamster/version.rb b/lib/hamster/version.rb
index 4118a35..8e910fb 100644
--- a/lib/hamster/version.rb
+++ b/lib/hamster/version.rb
@@ -1,5 +1,5 @@
 module Hamster
   # Current released gem version. Note that master will often have the same
   # value as a release gem but with different code.
-  VERSION = "2.0.0"
+  VERSION = "3.0.0"
 end
diff --git a/metadata.yml b/metadata.yml
index 3297438..3878c92 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,14 +1,14 @@
 --- !ruby/object:Gem::Specification
 name: hamster
 version: !ruby/object:Gem::Version
-  version: 2.0.0
+  version: 3.0.0
 platform: ruby
 authors:
 - Simon Harris
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2015-10-28 00:00:00.000000000 Z
+date: 2016-02-20 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: concurrent-ruby
@@ -16,14 +16,14 @@ dependencies:
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '0.8'
+        version: '1.0'
   type: :runtime
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: '0.8'
+        version: '1.0'
 - !ruby/object:Gem::Dependency
   name: bundler
   requirement: !ruby/object:Gem::Requirement
@@ -143,6 +143,7 @@ executables: []
 extensions: []
 extra_rdoc_files: []
 files:
+- LICENSE
 - lib/hamster.rb
 - lib/hamster/associable.rb
 - lib/hamster/core_ext.rb
@@ -203,12 +204,14 @@ files:
 - spec/lib/hamster/hash/copying_spec.rb
 - spec/lib/hamster/hash/default_proc_spec.rb
 - spec/lib/hamster/hash/delete_spec.rb
+- spec/lib/hamster/hash/dig_spec.rb
 - spec/lib/hamster/hash/each_spec.rb
 - spec/lib/hamster/hash/each_with_index_spec.rb
 - spec/lib/hamster/hash/empty_spec.rb
 - spec/lib/hamster/hash/eql_spec.rb
 - spec/lib/hamster/hash/except_spec.rb
 - spec/lib/hamster/hash/fetch_spec.rb
+- spec/lib/hamster/hash/fetch_values_spec.rb
 - spec/lib/hamster/hash/find_spec.rb
 - spec/lib/hamster/hash/flat_map_spec.rb
 - spec/lib/hamster/hash/flatten_spec.rb
@@ -239,9 +242,12 @@ files:
 - spec/lib/hamster/hash/slice_spec.rb
 - spec/lib/hamster/hash/sort_spec.rb
 - spec/lib/hamster/hash/store_spec.rb
+- spec/lib/hamster/hash/subset_spec.rb
+- spec/lib/hamster/hash/superset_spec.rb
 - spec/lib/hamster/hash/take_spec.rb
 - spec/lib/hamster/hash/to_a_spec.rb
 - spec/lib/hamster/hash/to_hash_spec.rb
+- spec/lib/hamster/hash/to_proc_spec.rb
 - spec/lib/hamster/hash/values_at_spec.rb
 - spec/lib/hamster/hash/values_spec.rb
 - spec/lib/hamster/immutable/copying_spec.rb
@@ -355,6 +361,7 @@ files:
 - spec/lib/hamster/set/first_spec.rb
 - spec/lib/hamster/set/flatten_spec.rb
 - spec/lib/hamster/set/grep_spec.rb
+- spec/lib/hamster/set/grep_v_spec.rb
 - spec/lib/hamster/set/group_by_spec.rb
 - spec/lib/hamster/set/hash_spec.rb
 - spec/lib/hamster/set/immutable_spec.rb
@@ -445,6 +452,7 @@ files:
 - spec/lib/hamster/vector/count_spec.rb
 - spec/lib/hamster/vector/delete_at_spec.rb
 - spec/lib/hamster/vector/delete_spec.rb
+- spec/lib/hamster/vector/dig_spec.rb
 - spec/lib/hamster/vector/drop_spec.rb
 - spec/lib/hamster/vector/drop_while_spec.rb
 - spec/lib/hamster/vector/each_index_spec.rb
@@ -526,7 +534,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
       version: '0'
 requirements: []
 rubyforge_project: 
-rubygems_version: 2.4.3
+rubygems_version: 2.4.8
 signing_key: 
 specification_version: 4
 summary: Efficient, immutable, thread-safe collection classes for Ruby
@@ -569,12 +577,14 @@ test_files:
 - spec/lib/hamster/hash/copying_spec.rb
 - spec/lib/hamster/hash/default_proc_spec.rb
 - spec/lib/hamster/hash/delete_spec.rb
+- spec/lib/hamster/hash/dig_spec.rb
 - spec/lib/hamster/hash/each_spec.rb
 - spec/lib/hamster/hash/each_with_index_spec.rb
 - spec/lib/hamster/hash/empty_spec.rb
 - spec/lib/hamster/hash/eql_spec.rb
 - spec/lib/hamster/hash/except_spec.rb
 - spec/lib/hamster/hash/fetch_spec.rb
+- spec/lib/hamster/hash/fetch_values_spec.rb
 - spec/lib/hamster/hash/find_spec.rb
 - spec/lib/hamster/hash/flat_map_spec.rb
 - spec/lib/hamster/hash/flatten_spec.rb
@@ -605,9 +615,12 @@ test_files:
 - spec/lib/hamster/hash/slice_spec.rb
 - spec/lib/hamster/hash/sort_spec.rb
 - spec/lib/hamster/hash/store_spec.rb
+- spec/lib/hamster/hash/subset_spec.rb
+- spec/lib/hamster/hash/superset_spec.rb
 - spec/lib/hamster/hash/take_spec.rb
 - spec/lib/hamster/hash/to_a_spec.rb
 - spec/lib/hamster/hash/to_hash_spec.rb
+- spec/lib/hamster/hash/to_proc_spec.rb
 - spec/lib/hamster/hash/values_at_spec.rb
 - spec/lib/hamster/hash/values_spec.rb
 - spec/lib/hamster/immutable/copying_spec.rb
@@ -721,6 +734,7 @@ test_files:
 - spec/lib/hamster/set/first_spec.rb
 - spec/lib/hamster/set/flatten_spec.rb
 - spec/lib/hamster/set/grep_spec.rb
+- spec/lib/hamster/set/grep_v_spec.rb
 - spec/lib/hamster/set/group_by_spec.rb
 - spec/lib/hamster/set/hash_spec.rb
 - spec/lib/hamster/set/immutable_spec.rb
@@ -811,6 +825,7 @@ test_files:
 - spec/lib/hamster/vector/count_spec.rb
 - spec/lib/hamster/vector/delete_at_spec.rb
 - spec/lib/hamster/vector/delete_spec.rb
+- spec/lib/hamster/vector/dig_spec.rb
 - spec/lib/hamster/vector/drop_spec.rb
 - spec/lib/hamster/vector/drop_while_spec.rb
 - spec/lib/hamster/vector/each_index_spec.rb
diff --git a/spec/lib/hamster/hash/dig_spec.rb b/spec/lib/hamster/hash/dig_spec.rb
new file mode 100644
index 0000000..0e5d204
--- /dev/null
+++ b/spec/lib/hamster/hash/dig_spec.rb
@@ -0,0 +1,32 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#dig" do
+    let(:h) { H[:a => 9, :b => H[:c => 'a', :d => 4], :e => nil] }
+    it "returns the value with one argument to dig" do
+      expect(h.dig(:a)).to eq(9)
+    end
+
+    it "returns the value in nested hashes" do
+      expect(h.dig(:b, :c)).to eq('a')
+    end
+
+    it "returns nil if the key is not present" do
+      expect(h.dig(:f, :foo)).to eq(nil)
+    end
+
+    it "returns nil if you dig out the end of the hash" do
+      expect(h.dig(:f, :foo, :bar)).to eq(nil)
+    end
+
+    it "returns nil if a value does not support dig" do
+      expect(h.dig(:a, :foo)).to eq(nil)
+    end
+
+    it "returns the correct value when there is a default proc" do
+      default_hash = H.new { |k| "#{k}-default" }
+      expect(default_hash.dig(:a)).to eq("a-default")
+    end
+  end
+end
diff --git a/spec/lib/hamster/hash/fetch_values_spec.rb b/spec/lib/hamster/hash/fetch_values_spec.rb
new file mode 100644
index 0000000..c697569
--- /dev/null
+++ b/spec/lib/hamster/hash/fetch_values_spec.rb
@@ -0,0 +1,22 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#fetch_values" do
+    context "when the all the requests keys exist" do
+      it "returns a vector of values for the given keys" do
+        h = H[:a => 9, :b => 'a', :c => -10, :d => nil]
+        h.fetch_values.should be_kind_of(Hamster::Vector)
+        h.fetch_values.should eql(V.empty)
+        h.fetch_values(:a, :d, :b).should be_kind_of(Hamster::Vector)
+        h.fetch_values(:a, :d, :b).should eql(V[9, nil, 'a'])
+      end
+    end
+
+    context "when the key does not exist" do
+      it "raises a KeyError" do
+        -> { H["A" => "aye", "C" => "Cee"].fetch_values("A", "B") }.should raise_error(KeyError)
+      end
+    end
+  end
+end
diff --git a/spec/lib/hamster/hash/subset_spec.rb b/spec/lib/hamster/hash/subset_spec.rb
new file mode 100644
index 0000000..499895c
--- /dev/null
+++ b/spec/lib/hamster/hash/subset_spec.rb
@@ -0,0 +1,42 @@
+require "spec_helper"
+require "hamster/hash"
+
+RSpec.describe Hamster::Hash do
+  describe "#<=" do
+    [
+      [{}, {}, true],
+      [{"A" => 1}, {}, false],
+      [{}, {"A" => 1}, true],
+      [{"A" => 1}, {"A" => 1}, true],
+      [{"A" => 1}, {"A" => 2}, false],
+      [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, true],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, false],
+      [{"B" => 0}, {"A" => 1, "B" => 2, "C" => 3}, false],
+    ].each do |a, b, expected|
+      describe "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          expect(H[a] <= H[b]).to eq(expected)
+        end
+      end
+    end
+  end
+
+  describe "#<" do
+    [
+      [{}, {}, false],
+      [{"A" => 1}, {}, false],
+      [{}, {"A" => 1}, true],
+      [{"A" => 1}, {"A" => 1}, false],
+      [{"A" => 1}, {"A" => 2}, false],
+      [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, true],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, false],
+      [{"B" => 0}, {"A" => 1, "B" => 2, "C" => 3}, false],
+    ].each do |a, b, expected|
+      describe "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          expect(H[a] < H[b]).to eq(expected)
+        end
+      end
+    end
+  end
+end
diff --git a/spec/lib/hamster/hash/superset_spec.rb b/spec/lib/hamster/hash/superset_spec.rb
new file mode 100644
index 0000000..8ed749a
--- /dev/null
+++ b/spec/lib/hamster/hash/superset_spec.rb
@@ -0,0 +1,42 @@
+require "spec_helper"
+require "hamster/hash"
+
+RSpec.describe Hamster::Hash do
+  describe "#>=" do
+    [
+      [{}, {}, true],
+      [{"A" => 1}, {}, true],
+      [{}, {"A" => 1}, false],
+      [{"A" => 1}, {"A" => 1}, true],
+      [{"A" => 1}, {"A" => 2}, false],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, true],
+      [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, false],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 0}, false],
+    ].each do |a, b, expected|
+      describe "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          expect(H[a] >= H[b]).to eq(expected)
+        end
+      end
+    end
+  end
+
+  describe "#>" do
+    [
+      [{}, {}, false],
+      [{"A" => 1}, {}, true],
+      [{}, {"A" => 1}, false],
+      [{"A" => 1}, {"A" => 1}, false],
+      [{"A" => 1}, {"A" => 2}, false],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 2}, true],
+      [{"B" => 2}, {"A" => 1, "B" => 2, "C" => 3}, false],
+      [{"A" => 1, "B" => 2, "C" => 3}, {"B" => 0}, false],
+    ].each do |a, b, expected|
+      describe "for #{a.inspect} and #{b.inspect}" do
+        it "returns #{expected}"  do
+          expect(H[a] > H[b]).to eq(expected)
+        end
+      end
+    end
+  end
+end
diff --git a/spec/lib/hamster/hash/to_proc_spec.rb b/spec/lib/hamster/hash/to_proc_spec.rb
new file mode 100644
index 0000000..60acce4
--- /dev/null
+++ b/spec/lib/hamster/hash/to_proc_spec.rb
@@ -0,0 +1,39 @@
+require "spec_helper"
+require "hamster/hash"
+
+describe Hamster::Hash do
+  describe "#to_proc" do
+    context "on Hash without default proc" do
+      let(:hash) { H.new("A" => "aye") }
+
+      it "returns a Proc instance" do
+        hash.to_proc.should be_kind_of(Proc)
+      end
+
+      it "returns a Proc that returns the value of an existing key" do
+        hash.to_proc.call("A").should == "aye"
+      end
+
+      it "returns a Proc that returns nil for a missing key" do
+        hash.to_proc.call("B").should be_nil
+      end
+    end
+
+    context "on Hash with a default proc" do
+      let(:hash) { H.new("A" => "aye") { |key| "#{key}-VAL" } }
+
+      it "returns a Proc instance" do
+        hash.to_proc.should be_kind_of(Proc)
+      end
+
+      it "returns a Proc that returns the value of an existing key" do
+        hash.to_proc.call("A").should == "aye"
+      end
+
+      it "returns a Proc that returns the result of the hash's default proc for a missing key" do
+        hash.to_proc.call("B").should == "B-VAL"
+        hash.should == H.new("A" => "aye")
+      end
+    end
+  end
+end
diff --git a/spec/lib/hamster/hash/values_at_spec.rb b/spec/lib/hamster/hash/values_at_spec.rb
index f32b3ff..5aee316 100644
--- a/spec/lib/hamster/hash/values_at_spec.rb
+++ b/spec/lib/hamster/hash/values_at_spec.rb
@@ -3,12 +3,32 @@ require "hamster/hash"
 
 describe Hamster::Hash do
   describe "#values_at" do
-    it "returns a vector of values for the given keys" do
-      h = H[:a => 9, :b => 'a', :c => -10, :d => nil]
-      h.values_at.should be_kind_of(Hamster::Vector)
-      h.values_at.should eql(V.empty)
-      h.values_at(:a, :d, :b).should be_kind_of(Hamster::Vector)
-      h.values_at(:a, :d, :b).should eql(V[9, nil, 'a'])
+    context "on Hash without default proc" do
+      let(:hash) { H[:a => 9, :b => 'a', :c => -10, :d => nil] }
+
+      it "returns an empty vector when no keys are given" do
+        hash.values_at.should be_kind_of(Hamster::Vector)
+        hash.values_at.should eql(V.empty)
+      end
+
+      it "returns a vector of values for the given keys" do
+        hash.values_at(:a, :d, :b).should be_kind_of(Hamster::Vector)
+        hash.values_at(:a, :d, :b).should eql(V[9, nil, 'a'])
+      end
+
+      it "fills nil when keys are missing" do
+        hash.values_at(:x, :a, :y, :b).should be_kind_of(Hamster::Vector)
+        hash.values_at(:x, :a, :y, :b).should eql(V[nil, 9, nil, 'a'])
+      end
+    end
+
+    context "on Hash with default proc" do
+      let(:hash) { Hamster::Hash.new(:a => 9) { |key| "#{key}-VAL" } }
+
+      it "fills the result of the default proc when keys are missing" do
+        hash.values_at(:x, :a, :y).should be_kind_of(Hamster::Vector)
+        hash.values_at(:x, :a, :y).should eql(V['x-VAL', 9, 'y-VAL'])
+      end
     end
   end
-end
\ No newline at end of file
+end
diff --git a/spec/lib/hamster/list/multithreading_spec.rb b/spec/lib/hamster/list/multithreading_spec.rb
index 2d935ed..bb4359d 100644
--- a/spec/lib/hamster/list/multithreading_spec.rb
+++ b/spec/lib/hamster/list/multithreading_spec.rb
@@ -4,7 +4,7 @@ require "concurrent/atomics"
 
 describe Hamster::List do
   it "ensures each node of a lazy list will only be realized on ONE thread, even when accessed by multiple threads" do
-    counter = Concurrent::Atomic.new(0)
+    counter = Concurrent::AtomicReference.new(0)
     list = (1..10000).to_list.map { |x| counter.update { |count| count + 1 }; x * 2 }
 
     threads = 10.times.collect do
diff --git a/spec/lib/hamster/set/grep_spec.rb b/spec/lib/hamster/set/grep_spec.rb
index cb8097b..84121d7 100644
--- a/spec/lib/hamster/set/grep_spec.rb
+++ b/spec/lib/hamster/set/grep_spec.rb
@@ -9,50 +9,51 @@ describe Hamster::Set do
 
     shared_examples "check filtered values" do
       it "returns the filtered values" do
-        expect(grep).to eq(filtered)
+        expect(grep).to eq(S[*filtered])
       end
     end
 
-    shared_examples "check different types of inputs" do
-      context "with an empty array" do
+    context "without a block" do
+      let(:block) { nil }
+
+      context "with an empty set" do
         let(:values) { [] }
         let(:filtered) { [] }
 
-        shared_examples "check filtered values"
+        include_examples "check filtered values"
       end
 
-      context "with a single item array" do
+      context "with a single item set" do
         let(:values) { ["A"] }
         let(:filtered) { ["A"] }
 
-        shared_examples "check filtered values"
+        include_examples "check filtered values"
       end
 
-      context "with a single item array that doesn't contain match" do
+      context "with a single item set that doesn't contain match" do
         let(:values) { [1] }
         let(:filtered) { [] }
 
-        shared_examples "check filtered values"
+        include_examples "check filtered values"
       end
 
-      context "with a multi-item array where one isn't a match" do
+      context "with a multi-item set where one isn't a match" do
         let(:values) { ["A", 2, "C"] }
         let(:filtered) { %w[A C] }
 
-        shared_examples "check filtered values"
+        include_examples "check filtered values"
       end
     end
 
-    context "without a block" do
-      let(:block) { nil }
-
-      include_examples "check different types of inputs"
-    end
-
     describe "with a block" do
       let(:block) { ->(item) { item.downcase }}
 
-      include_examples "check different types of inputs"
+      context "processes each matching item with the block" do
+        let(:values) { ["A", 2, "C"] }
+        let(:filtered) { %w[a c] }
+
+        include_examples "check filtered values"
+      end
     end
   end
 end
diff --git a/spec/lib/hamster/set/grep_v_spec.rb b/spec/lib/hamster/set/grep_v_spec.rb
new file mode 100644
index 0000000..cbe462c
--- /dev/null
+++ b/spec/lib/hamster/set/grep_v_spec.rb
@@ -0,0 +1,59 @@
+require "spec_helper"
+require "hamster/set"
+
+describe Hamster::Set do
+  let(:set) { S[*values] }
+
+  describe "#grep_v" do
+    let(:grep_v) { set.grep_v(String, &block) }
+
+    shared_examples "check filtered values" do
+      it "returns the filtered values" do
+        expect(grep_v).to eq(S[*filtered])
+      end
+    end
+
+    context "without a block" do
+      let(:block) { nil }
+
+      context "with an empty set" do
+        let(:values) { [] }
+        let(:filtered) { [] }
+
+        include_examples "check filtered values"
+      end
+
+      context "with a single item set" do
+        let(:values) { ["A"] }
+        let(:filtered) { [] }
+
+        include_examples "check filtered values"
+      end
+
+      context "with a single item set that doesn't contain match" do
+        let(:values) { [1] }
+        let(:filtered) { [1] }
+
+        include_examples "check filtered values"
+      end
+
+      context "with a multi-item set where one isn't a match" do
+        let(:values) { [2, "C", 4] }
+        let(:filtered) { [2, 4] }
+
+        include_examples "check filtered values"
+      end
+    end
+
+    describe "with a block" do
+      let(:block) { ->(item) { item + 100 }}
+
+      context "resulting items are processed with the block" do
+        let(:values) { [2, "C", 4] }
+        let(:filtered) { [102, 104] }
+
+        include_examples "check filtered values"
+      end
+    end
+  end
+end
diff --git a/spec/lib/hamster/vector/dig_spec.rb b/spec/lib/hamster/vector/dig_spec.rb
new file mode 100644
index 0000000..e457f3b
--- /dev/null
+++ b/spec/lib/hamster/vector/dig_spec.rb
@@ -0,0 +1,28 @@
+require "spec_helper"
+require "hamster/vector"
+
+describe Hamster::Vector do
+  let(:v) { V[1, 2, V[3, 4]] }
+
+  describe "#dig" do
+    it "returns value at the index with one argument" do
+      expect(v.dig(0)).to eq(1)
+    end
+
+    it "returns value at index in nested arrays" do
+      expect(v.dig(2, 0)).to eq(3)
+    end
+
+    it "returns nil when indexing deeper than possible" do
+      expect(v.dig(0, 0)).to eq(nil)
+    end
+
+    it "returns nil if you index past the end of an array" do
+      expect(v.dig(5)).to eq(nil)
+    end
+
+    it "raises a type error when indexing with a key arrays don't understand" do
+      expect{ v.dig(:foo) }.to raise_error(ArgumentError)
+    end
+  end
+end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-hamster.git



More information about the Pkg-ruby-extras-commits mailing list