Skip to content

Commit

Permalink
Merge 4b1eeb2 into 8792711
Browse files Browse the repository at this point in the history
  • Loading branch information
hopsoft committed Jun 16, 2016
2 parents 8792711 + 4b1eeb2 commit d77e849
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
language: ruby
rvm:
- 2.2.0
- 2.3.0
33 changes: 15 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[![Lines of Code](http://img.shields.io/badge/lines_of_code-51-brightgreen.svg?style=flat)](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
[![Lines of Code](http://img.shields.io/badge/lines_of_code-50-brightgreen.svg?style=flat)](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
[![Code Status](http://img.shields.io/codeclimate/github/hopsoft/queryable_hash.svg?style=flat)](https://codeclimate.com/github/hopsoft/queryable_hash)
[![Dependency Status](http://img.shields.io/gemnasium/hopsoft/queryable_hash.svg?style=flat)](https://gemnasium.com/hopsoft/queryable_hash)
[![Build Status](http://img.shields.io/travis/hopsoft/queryable_hash.svg?style=flat)](https://travis-ci.org/hopsoft/queryable_hash)
[![Coverage Status](https://img.shields.io/coveralls/hopsoft/queryable_hash.svg?style=flat)](https://coveralls.io/r/hopsoft/queryable_hash?branch=master)

# QueryableHash

Safely & easily find data in Hashes using dot notation queries.
Find data in Hashes using dot notation queries.

> We use QueryableHash to parse Ruby Hashes built from JSON API data.
> It works especially well when the target data is erratic.
Expand Down Expand Up @@ -44,24 +44,21 @@ data = {

```ruby
queryable = QueryableHash.wrap(data)
queryable.find_first("glossary.gloss_div.gloss_list.gloss_entry.id") #=> "SGML"

# or simply
queryable.find("glossary.gloss_div.gloss_list.gloss_entry.id") #=> "SGML"
queryable.get("glossary.gloss_div.gloss_list.gloss_entry.id") #=> "SGML"
```

### Find first match using multiple queries

```ruby
queryable = QueryableHash.wrap(data)
queryable.find("this.key.does.not.exist", "glossary.gloss_div.gloss_list.gloss_entry.id") #=> "SGML"
queryable.get("this.key.does.not.exist", "glossary.gloss_div.gloss_list.gloss_entry.id") #=> "SGML"
```

### Find all matches

```ruby
queryable = QueryableHash.wrap(data)
queryable.find_all(
queryable.get_all(
"glossary.title",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_term",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_def.para"
Expand All @@ -72,7 +69,7 @@ queryable.find_all(

# or assign the results

title, term, para = queryable.find_all(
title, term, para = queryable.get_all(
"glossary.title",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_term",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_def.para"
Expand All @@ -86,37 +83,37 @@ param #=> "A meta-markup language, used to create markup languages such as DocBo

```ruby
queryable = QueryableHash.wrap(data)
queryable.find_first("this.key.does.not.exist") #=> nil
queryable.get("this.key.does.not.exist") #=> nil
```

### Assign a custom value to represent nil

```ruby
queryable = QueryableHash.wrap(data)
queryable.find_first("this.key.does.not.exist", nil_value: "missing") #=> "missing"
queryable.get("this.key.does.not.exist", nil_value: "missing") #=> "missing"
```

### Raise an error when not found

```ruby
queryable = QueryableHash.wrap(data)
queryable.find("this.key.does.not.exist", raise_when_nil: true) #=> raises QueryableHash::NotFoundError
queryable.get("this.key.does.not.exist", raise_when_nil: true) #=> raises QueryableHash::NotFoundError
```

### Set query options on the instance

```ruby
queryable = QueryableHash.wrap(data, nil_value: "missing")
queryable.find("this.key.does.not.exist") #=> "missing"
queryable.find("neither.does.this.one") #=> "missing"
queryable.find("nor.this.one", nil_value: nil) #=> nil
queryable.get("this.key.does.not.exist") #=> "missing"
queryable.get("neither.does.this.one") #=> "missing"
queryable.get("nor.this.one", nil_value: nil) #=> nil
```

```ruby
queryable = QueryableHash.wrap(data, raise_when_nil: true)
queryable.find("this.key.does.not.exist") #=> raises QueryableHash::NotFoundError
queryable.find("neither.does.this.one") #=> raises QueryableHash::NotFoundError
queryable.find("nor.this.one", raise_when_nil: false) #=> nil
queryable.get("this.key.does.not.exist") #=> raises QueryableHash::NotFoundError
queryable.get("neither.does.this.one") #=> raises QueryableHash::NotFoundError
queryable.get("nor.this.one", raise_when_nil: false) #=> nil
```

---
Expand Down
2 changes: 1 addition & 1 deletion lib/queryable_hash/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module QueryableHash
VERSION = "0.0.4"
VERSION = "1.0.0"
end
8 changes: 3 additions & 5 deletions lib/queryable_hash/wrapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def initialize(hash, nil_value: nil, raise_when_nil: false)
super hash
end

def find_all(*queries, nil_value: nil)
def get_all(*queries, nil_value: nil)
queries.reduce([]) do |memo, query|
context = self
query.split(".").each do |name|
Expand All @@ -22,11 +22,11 @@ def find_all(*queries, nil_value: nil)
end
end

def find_first(*queries, nil_value: nil, raise_when_nil: nil)
def get(*queries, nil_value: nil, raise_when_nil: nil)
nil_value = @nil_value if nil_value.nil?
raise_when_nil = @raise_when_nil if raise_when_nil.nil?

first = find_all(*queries, nil_value: nil_value).find do |result|
first = get_all(*queries, nil_value: nil_value).find do |result|
result != nil_value
end
first ||= nil_value
Expand All @@ -35,8 +35,6 @@ def find_first(*queries, nil_value: nil, raise_when_nil: nil)
first
end

alias_method :find, :find_first

def to_hash
@original_hash
end
Expand Down
3 changes: 1 addition & 2 deletions queryable_hash.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ Gem::Specification.new do |spec|
spec.version = QueryableHash::VERSION
spec.authors = ["Nathan Hopkins"]
spec.email = ["natehop@gmail.com"]
spec.summary = "Safely & easily find data in Hashes using dot notation queries."
spec.description = "Safely & easily find data in Hashes using dot notation queries."
spec.summary = "Find data in Hashes using dot notation queries"
spec.homepage = "https://github.com/hopsoft/queryable_hash"
spec.license = "MIT"

Expand Down
40 changes: 20 additions & 20 deletions test/wrapper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ class QueryableHashTest < PryTest::Test
@queryable = QueryableHash.wrap(@data)
end

test "find_all" do
test "get_all" do
query = "glossary.gloss_div.gloss_list.gloss_entry.id"
assert @queryable.find_all(query) == ["SGML"]
assert @queryable.get_all(query) == ["SGML"]
end

test "find_all with multiple queries" do
title, term, para = @queryable.find_all(
test "get_all with multiple queries" do
title, term, para = @queryable.get_all(
"glossary.title",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_term",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_def.para"
Expand All @@ -44,38 +44,38 @@ class QueryableHashTest < PryTest::Test
assert para == "A meta-markup language, used to create markup languages such as DocBook."
end

test "find_first" do
test "get" do
query = "glossary.gloss_div.gloss_list.gloss_entry.id"
assert @queryable.find_first(query) == "SGML"
assert @queryable.get(query) == "SGML"
end

test "find_first with multiple queries" do
result = @queryable.find_first(
test "get with multiple queries" do
result = @queryable.get(
"glossary.title",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_term",
"glossary.gloss_div.gloss_list.gloss_entry.gloss_def.para"
)
assert result == "example glossary"
end

test "find_first with missing key" do
test "get with missing key" do
query = "this.key.does.not.exist"
assert @queryable.find_first(query).nil?
assert @queryable.get(query).nil?
end

test "find_first with missing key and nil_value" do
test "get with missing key and nil_value" do
query = "nate.this.key.does.not.exist"
assert @queryable.find_first(query, nil_value: "missing") == "missing"
assert @queryable.get(query, nil_value: "missing") == "missing"
end

test "find_first with missing key and nil_value set by instance" do
test "get with missing key and nil_value set by instance" do
query = "nate.this.key.does.not.exist"
queryable = QueryableHash.wrap(@data, nil_value: "missing")
assert queryable.find_first(query) == "missing"
assert queryable.get(query) == "missing"
end

test "find_first with multiple queries some invalid" do
term = @queryable.find_first(
test "get with multiple queries some invalid" do
term = @queryable.get(
"glossary.div.list.entry.term",
"glossary.gloss_div.list.entry.term",
"glossary.gloss_div.gloss_list.entry.term",
Expand All @@ -85,21 +85,21 @@ class QueryableHashTest < PryTest::Test
assert term == "Standard Generalized Markup Language"
end

test "find_first with raise_when_nil" do
test "get with raise_when_nil" do
query = "nate.this.key.does.not.exist"
begin
@queryable.find_first(query, raise_when_nil: true)
@queryable.get(query, raise_when_nil: true)
rescue NotFoundError => e
end

assert e
end

test "find_first with raise_when_nil set by instance" do
test "get with raise_when_nil set by instance" do
query = "nate.this.key.does.not.exist"
begin
queryable = QueryableHash.wrap(@data, raise_when_nil: true)
queryable.find_first(query)
queryable.get(query)
rescue NotFoundError => e
end
assert e
Expand Down

0 comments on commit d77e849

Please sign in to comment.