traipse 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/traipse.rb +37 -0
- data/lib/traipse/version.rb +1 -1
- data/test/traipse_test.rb +89 -0
- metadata +5 -3
data/lib/traipse.rb
CHANGED
@@ -10,6 +10,10 @@ module Traipse
|
|
10
10
|
return _find( object, path.split( SEPARATOR ) )
|
11
11
|
end
|
12
12
|
|
13
|
+
def self.find_with_keys( object, path )
|
14
|
+
_find_with_keys( object, path.split( SEPARATOR ) )
|
15
|
+
end
|
16
|
+
|
13
17
|
def self._find( object, path, results=[] ) # :nodoc:
|
14
18
|
key, *rest = path
|
15
19
|
|
@@ -43,4 +47,37 @@ module Traipse
|
|
43
47
|
return results
|
44
48
|
end
|
45
49
|
|
50
|
+
def self._find_with_keys( object, path, full_path=[], results={} ) # :nodoc:
|
51
|
+
key, *rest = path
|
52
|
+
full_path << key unless key == "*"
|
53
|
+
|
54
|
+
# Handle wildcard hash keys
|
55
|
+
if key == '*'
|
56
|
+
object.keys.each do |subkey|
|
57
|
+
results.merge! _find_with_keys( object, [ subkey, *rest ], full_path.dup )
|
58
|
+
end
|
59
|
+
return results.reject { |k,v| v.nil? }
|
60
|
+
end
|
61
|
+
|
62
|
+
# This is the end of the line, megatron.
|
63
|
+
return { full_path.join(".") => object[key] } if rest.empty?
|
64
|
+
|
65
|
+
# Traverse hashes and arrays
|
66
|
+
case object[ key ]
|
67
|
+
when Hash
|
68
|
+
return _find_with_keys( object[ key ], rest, full_path )
|
69
|
+
when Array
|
70
|
+
if rest.first =~ /^\d+$/
|
71
|
+
index = rest.shift.to_i
|
72
|
+
results.merge! _find_with_keys( object[key][index], rest, full_path + [index] )
|
73
|
+
else
|
74
|
+
object[ key ].each_with_index do |obj, index|
|
75
|
+
results.merge! _find_with_keys( obj, rest, full_path + [index] )
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
return results
|
81
|
+
end
|
82
|
+
|
46
83
|
end
|
data/lib/traipse/version.rb
CHANGED
@@ -0,0 +1,89 @@
|
|
1
|
+
require "../lib/traipse"
|
2
|
+
require "test/unit"
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
class TraipseTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
DATA = {
|
9
|
+
"name" => "Percival",
|
10
|
+
"board" => {
|
11
|
+
"name" => "cats"
|
12
|
+
},
|
13
|
+
"categories" => [
|
14
|
+
{ "name" => "animals" },
|
15
|
+
{ "name" => "kitties" },
|
16
|
+
{ "name" => "robots" },
|
17
|
+
],
|
18
|
+
"products" => {
|
19
|
+
"shoes" => {
|
20
|
+
"brands" => [
|
21
|
+
{ "name" => "converse" },
|
22
|
+
{ "name" => "adidas" },
|
23
|
+
{ "name" => "nike" }
|
24
|
+
]
|
25
|
+
},
|
26
|
+
"apparel" => {
|
27
|
+
"brands" => [
|
28
|
+
{ "name" => "Calvin Klein" },
|
29
|
+
{ "name" => "Diesel" },
|
30
|
+
{ "name" => "Betsey Johnson" },
|
31
|
+
{ "name" => [ "Marc", "Ecko" ] },
|
32
|
+
{ "caltrops" => 'Yes Please' }
|
33
|
+
]
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
def test_can_find_top_level_values
|
39
|
+
assert_equal ['Percival'], Traipse.find( DATA, 'name' )
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_can_return_key_names_too
|
43
|
+
matches = Traipse.find_with_keys( DATA, 'name' )
|
44
|
+
assert_equal matches.keys, ["name"]
|
45
|
+
assert_equal matches.values, ["Percival"]
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_can_get_to_nested_values
|
49
|
+
matches = Traipse.find_with_keys( DATA, 'board.name' )
|
50
|
+
assert_equal matches.keys, ["board.name"]
|
51
|
+
assert_equal matches.values, ["cats"]
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_can_traverse_arrays
|
55
|
+
matches = Traipse.find_with_keys( DATA, 'categories.name' )
|
56
|
+
assert_equal ["categories.0.name", "categories.1.name", "categories.2.name"], matches.keys
|
57
|
+
assert_equal ["animals", "kitties", "robots"], matches.values
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_can_traverse_arrays_to_get_to_nested_values
|
61
|
+
matches = Traipse.find_with_keys( DATA, 'products.shoes.brands.name' )
|
62
|
+
assert_equal ["products.shoes.brands.0.name", "products.shoes.brands.1.name", "products.shoes.brands.2.name"], matches.keys
|
63
|
+
assert_equal [ "converse", "adidas", "nike" ], matches.values
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_can_handle_key_wildcards
|
67
|
+
matches = Traipse.find_with_keys( DATA, 'products.*.brands.name' )
|
68
|
+
assert_equal [ "converse", "adidas", "nike", "Calvin Klein", "Diesel", "Betsey Johnson", [ "Marc", "Ecko" ] ], matches.values
|
69
|
+
assert_equal "products.shoes.brands.0.name", matches.keys.first
|
70
|
+
assert_equal "products.apparel.brands.3.name", matches.keys.last
|
71
|
+
|
72
|
+
matches = Traipse.find_with_keys( DATA, '*.name' )
|
73
|
+
assert_equal [ "cats", "animals", "kitties", "robots" ], matches.values
|
74
|
+
assert_equal "board.name", matches.keys.first
|
75
|
+
assert_equal "categories.2.name", matches.keys.last
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_can_do_multiple_wildcards
|
79
|
+
matches = Traipse.find_with_keys( DATA, "products.*.brands.*" )
|
80
|
+
assert_equal [ "converse", "adidas", "nike", "Calvin Klein", "Diesel", "Betsey Johnson", [ "Marc", "Ecko" ], 'Yes Please' ], matches.values
|
81
|
+
assert_equal "products.shoes.brands.0.name", matches.keys.first
|
82
|
+
assert_equal "products.apparel.brands.4.caltrops", matches.keys.last
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_can_match_array_indexed_paths
|
86
|
+
assert_equal [ "Marc", "Ecko" ], Traipse.find_with_keys( DATA, "products.apparel.brands.3.name").values.first
|
87
|
+
assert_equal 'Yes Please', Traipse.find_with_keys( DATA, "products.apparel.brands.4.caltrops").values.first
|
88
|
+
end
|
89
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: traipse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-15 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! 'Traipse is a library that allows you to address a data structure of
|
15
15
|
Hashes & Arrays using a dot notated string & wildcards. ex: ''categories.*.name''.
|
@@ -28,6 +28,7 @@ files:
|
|
28
28
|
- lib/traipse/version.rb
|
29
29
|
- spec/spec_helper.rb
|
30
30
|
- spec/traipse_spec.rb
|
31
|
+
- test/traipse_test.rb
|
31
32
|
- traipse.gemspec
|
32
33
|
homepage: https://github.com/makenai/traipse
|
33
34
|
licenses: []
|
@@ -49,10 +50,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
50
|
version: '0'
|
50
51
|
requirements: []
|
51
52
|
rubyforge_project: traipse
|
52
|
-
rubygems_version: 1.8.
|
53
|
+
rubygems_version: 1.8.24
|
53
54
|
signing_key:
|
54
55
|
specification_version: 3
|
55
56
|
summary: Traverse data structures with a dot notated string.
|
56
57
|
test_files:
|
57
58
|
- spec/spec_helper.rb
|
58
59
|
- spec/traipse_spec.rb
|
60
|
+
- test/traipse_test.rb
|