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 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
@@ -1,3 +1,3 @@
1
1
  module Traipse
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -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.5.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-04-25 00:00:00.000000000Z
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.17
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