traipse 0.5.0 → 0.6.0

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/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