shokkenki-support 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ module Shokkenki
2
+ module Support
3
+ module Version
4
+ STRING = '0.0.1'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ require 'shokkenki/support/version'
@@ -0,0 +1,9 @@
1
+ require_relative '../hash_term'
2
+
3
+ class Hash
4
+
5
+ def to_shokkenki_term
6
+ Shokkenki::Term::HashTerm.new self
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../number_term'
2
+
3
+ class Numeric
4
+
5
+ def to_shokkenki_term
6
+ Shokkenki::Term::NumberTerm.new self
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../regexp_term'
2
+
3
+ class Regexp
4
+
5
+ def to_shokkenki_term
6
+ Shokkenki::Term::RegexpTerm.new self
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../string_term'
2
+
3
+ class String
4
+
5
+ def to_shokkenki_term
6
+ Shokkenki::Term::StringTerm.new self
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../string_term'
2
+
3
+ class Symbol
4
+
5
+ def to_shokkenki_term
6
+ Shokkenki::Term::StringTerm.new self
7
+ end
8
+
9
+ end
@@ -0,0 +1,5 @@
1
+ require_relative 'core_ext/string'
2
+ require_relative 'core_ext/hash'
3
+ require_relative 'core_ext/regexp'
4
+ require_relative 'core_ext/symbol'
5
+ require_relative 'core_ext/numeric'
@@ -0,0 +1,58 @@
1
+ require_relative 'term'
2
+ require_relative 'core_ext'
3
+
4
+ module Shokkenki
5
+ module Term
6
+ class HashTerm < Term
7
+
8
+ attr_reader :type, :value
9
+
10
+ def self.from_json json
11
+ values = json['value'].inject({}) do |hash, kv|
12
+ key, value = *kv
13
+ hash[key.to_sym] = TermFactory.from_json(value)
14
+ hash
15
+ end
16
+
17
+ new values
18
+ end
19
+
20
+ def initialize values
21
+ @value = values.inject({}) do |mapped, kv|
22
+ k,v = *kv
23
+ mapped[k] = v.to_shokkenki_term
24
+ mapped
25
+ end
26
+
27
+ @type = :hash
28
+ end
29
+
30
+ def to_hash
31
+ mapped_values = @value.inject({}) do |mapped, keyvalue|
32
+ key, value = *keyvalue
33
+ mapped[key] = value.respond_to?(:to_hash) ? value.to_hash : value
34
+ mapped
35
+ end
36
+
37
+ {
38
+ :type => @type,
39
+ :value => mapped_values
40
+ }
41
+ end
42
+
43
+ def example
44
+ @value.inject({}) do |hash, kv|
45
+ key, value = *kv
46
+ hash[key] = value.example
47
+ hash
48
+ end
49
+ end
50
+
51
+ def match? compare
52
+ compare && @value.all? do |key, value|
53
+ value.match? compare.to_hash[key]
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,54 @@
1
+ require 'jsonpath'
2
+
3
+ module Shokkenki
4
+ module Term
5
+ class JsonPathExample
6
+
7
+ ELEMENT_HANDLERS = {
8
+ /^\['(.+)'\]$/ => lambda{ |match, ancestor, value| ancestor[match[1]] = value },
9
+ /\*/ => lambda{ |m, a, v| a['wildcard'] = v },
10
+ /\.\./ => lambda{ |m, a, v| a },
11
+ /\$/ => lambda{ |m, a, v| a }, # ignore root element
12
+ /^\[\d+\]$/ => lambda{ |m, a, v| raise "Numeric element '#{m[0]}' is not supported."},
13
+ /^\[\?.*\]$/ => lambda{ |m, a, v| raise "Filter element '#{m[0]}' is not supported."},
14
+ /^\[.*,.*\]$/ => lambda{ |m, a, v| raise "Union element '#{m[0]}' is not supported."},
15
+ /^\[.*:.*\]$/ => lambda{ |m, a, v| raise "Array slice element '#{m[0]}' is not supported."},
16
+ /^\[.*\(.*\]$/ => lambda{ |m, a, v| raise "Script element '#{m[0]}' is not supported."},
17
+ /.*/ => lambda{ |m, a, v| raise "Unrecognised element '#{m[0]}' is not supported."}
18
+ }
19
+
20
+ def initialize path, term
21
+ @path = path
22
+ @term = term
23
+ end
24
+
25
+ def to_example
26
+ example = {}
27
+ path = JsonPath.new(@path).path
28
+ last = path.pop
29
+
30
+ begin
31
+ leaf = path.inject(example) do |ancestor, element|
32
+ store ancestor, element
33
+ end
34
+
35
+ store leaf, last, @term.example
36
+ rescue Exception => e
37
+ raise "Could not generate example for JSON path '#{@path}': #{e.message}"
38
+ end
39
+
40
+ example
41
+ end
42
+
43
+ private
44
+
45
+ def store ancestor, element, value={}
46
+ pattern, handler = ELEMENT_HANDLERS.find do |p, h|
47
+ p.match element
48
+ end
49
+
50
+ handler.call pattern.match(element), ancestor, value
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,64 @@
1
+ require 'jsonpath'
2
+ require 'active_support/core_ext/hash/deep_merge'
3
+ require 'json'
4
+ require_relative 'json_path_example'
5
+ require_relative 'term'
6
+ require_relative 'core_ext'
7
+
8
+ module Shokkenki
9
+ module Term
10
+ class JsonPathsTerm < Term
11
+
12
+ attr_reader :type, :value
13
+
14
+ def self.from_json json
15
+ values = json['value'].inject({}) do |hash, kv|
16
+ key, value = *kv
17
+ hash[key] = TermFactory.from_json(value)
18
+ hash
19
+ end
20
+
21
+ new values
22
+ end
23
+
24
+ def initialize values
25
+ @value = values.inject({}) do |mapped, kv|
26
+ k, v = *kv
27
+ mapped[k] = v.to_shokkenki_term
28
+ mapped
29
+ end
30
+
31
+ @type = :json_paths
32
+ end
33
+
34
+ def match? compare
35
+ compare && @value.all? do |key, value|
36
+ path = JsonPath.new(key)
37
+ value.match? path.on(compare)
38
+ end
39
+ end
40
+
41
+ def example
42
+ @value.inject({}) do |generated, keyvalue|
43
+ path, term = *keyvalue
44
+ generated.deep_merge! JsonPathExample.new(path, term).to_example
45
+ generated
46
+ end.to_json
47
+ end
48
+
49
+ def to_hash
50
+ mapped_values = @value.inject({}) do |mapped, keyvalue|
51
+ key, value = *keyvalue
52
+ mapped[key] = value.respond_to?(:to_hash) ? value.to_hash : value
53
+ mapped
54
+ end
55
+
56
+ {
57
+ :type => @type,
58
+ :value => mapped_values
59
+ }
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'term'
2
+
3
+ module Shokkenki
4
+ module Term
5
+ class NumberTerm < Term
6
+
7
+ attr_reader :type, :value
8
+
9
+ def self.from_json json
10
+ new json['value']
11
+ end
12
+
13
+ def initialize value
14
+ @value = value
15
+ @type = :number
16
+ end
17
+
18
+ def to_hash
19
+ {
20
+ :type => @type,
21
+ :value => @value
22
+ }
23
+ end
24
+
25
+ def example
26
+ @value
27
+ end
28
+
29
+ def match? compare
30
+ compare && (compare == @value)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'ruby-string-random/lib/strrand'
2
+ require_relative 'term'
3
+
4
+ module Shokkenki
5
+ module Term
6
+ class RegexpTerm < Term
7
+
8
+ attr_reader :type, :value
9
+
10
+ def self.from_json json
11
+ new json['value']
12
+ end
13
+
14
+ def initialize value
15
+ @value = Regexp.new value
16
+ @type = :regexp
17
+ end
18
+
19
+ def to_hash
20
+ {
21
+ :type => @type,
22
+ :value => @value.to_s
23
+ }
24
+ end
25
+
26
+ def example
27
+ StringRandom.random_regex @value.to_s
28
+ end
29
+
30
+ def match? compare
31
+ compare && !@value.match(compare.to_s).nil?
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'term'
2
+
3
+ module Shokkenki
4
+ module Term
5
+ class StringTerm < Term
6
+
7
+ attr_reader :type, :value
8
+
9
+ def self.from_json json
10
+ new json['value']
11
+ end
12
+
13
+ def initialize value
14
+ @value = value.to_s
15
+ @type = :string
16
+ end
17
+
18
+ def to_hash
19
+ {
20
+ :type => @type,
21
+ :value => @value
22
+ }
23
+ end
24
+
25
+ def example
26
+ @value
27
+ end
28
+
29
+ def match? compare
30
+ compare && (compare.strip == @value)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ module Shokkenki
2
+ module Term
3
+ class Term
4
+ def to_shokkenki_term
5
+ self
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,35 @@
1
+ require 'shokkenki/term/string_term'
2
+ require_relative 'hash_term'
3
+ require_relative 'regexp_term'
4
+ require_relative 'number_term'
5
+ require_relative 'json_paths_term'
6
+
7
+ module Shokkenki
8
+ module Term
9
+ class TermFactory
10
+
11
+ def self.factories
12
+ @factories ||= {
13
+ :string => StringTerm,
14
+ :hash => HashTerm,
15
+ :regexp => RegexpTerm,
16
+ :number => NumberTerm,
17
+ :json_paths => JsonPathsTerm
18
+ }
19
+ end
20
+
21
+ def self.factory_for type
22
+ raise 'There is no term type' unless type
23
+ factories[type.to_s.downcase.to_sym] || raise("Term of type '#{type}' is not recognised. Have you registered a factory for it?")
24
+ end
25
+
26
+ def self.register type, factory
27
+ factories[type.to_s.downcase.to_sym] = factory
28
+ end
29
+
30
+ def self.from_json json
31
+ factory_for(json['type']).from_json json
32
+ end
33
+ end
34
+ end
35
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shokkenki-support
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brent Snook
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-11-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: jsonpath
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 10.0.0
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 10.0.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 2.14.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 2.14.0
94
+ description: Shared support for Shokkenki consumers and providers.
95
+ email: brent@fuglylogic.com
96
+ executables: []
97
+ extensions: []
98
+ extra_rdoc_files: []
99
+ files:
100
+ - lib/shokkenki/support.rb
101
+ - lib/shokkenki/support/version.rb
102
+ - lib/shokkenki/term/core_ext.rb
103
+ - lib/shokkenki/term/core_ext/hash.rb
104
+ - lib/shokkenki/term/core_ext/numeric.rb
105
+ - lib/shokkenki/term/core_ext/regexp.rb
106
+ - lib/shokkenki/term/core_ext/string.rb
107
+ - lib/shokkenki/term/core_ext/symbol.rb
108
+ - lib/shokkenki/term/hash_term.rb
109
+ - lib/shokkenki/term/json_path_example.rb
110
+ - lib/shokkenki/term/json_paths_term.rb
111
+ - lib/shokkenki/term/number_term.rb
112
+ - lib/shokkenki/term/regexp_term.rb
113
+ - lib/shokkenki/term/string_term.rb
114
+ - lib/shokkenki/term/term.rb
115
+ - lib/shokkenki/term/term_factory.rb
116
+ homepage: http://github.com/brentsnook/shokkenki-support
117
+ licenses:
118
+ - GPL2
119
+ post_install_message:
120
+ rdoc_options:
121
+ - --charset=UTF-8
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '1.9'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ segments:
137
+ - 0
138
+ hash: 328884102764703687
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 1.8.24
142
+ signing_key:
143
+ specification_version: 3
144
+ summary: shokkenki-support-0.0.1
145
+ test_files: []