eapi 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.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +57 -0
- data/.rspec +2 -0
- data/.travis.yml +15 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +11 -0
- data/eapi.gemspec +34 -0
- data/lib/eapi.rb +16 -0
- data/lib/eapi/common.rb +48 -0
- data/lib/eapi/errors.rb +6 -0
- data/lib/eapi/methods.rb +9 -0
- data/lib/eapi/methods/accessor.rb +55 -0
- data/lib/eapi/methods/names.rb +34 -0
- data/lib/eapi/methods/properties.rb +157 -0
- data/lib/eapi/methods/types.rb +35 -0
- data/lib/eapi/multiple.rb +13 -0
- data/lib/eapi/version.rb +3 -0
- data/spec/eapi_basic_spec.rb +39 -0
- data/spec/eapi_list_spec.rb +92 -0
- data/spec/eapi_to_h_spec.rb +42 -0
- data/spec/eapi_validations_spec.rb +80 -0
- data/spec/spec_helper.rb +12 -0
- metadata +243 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b1e95dc0187bc0b633dd39f04862c3f57f1c412f
|
4
|
+
data.tar.gz: 35a9ef27b0186c91592e4a7d1bee6d43a717e13e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e68a34cf0a19910cda0eebdd3e855bcf3fe70fa4ab34de5c3e6f0c6bc7b67b25493f8d0a8acdf77a54fb25bffe06c841d889331abefaee245614668560d38508
|
7
|
+
data.tar.gz: 3f0961bb4964307784f5e251640b39c52ee6e488592462712b41c3b0996e75f327b9726454ec1d340dc3ce27b24a8089475201fa39946b108a7869260988a53c
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.gitignore
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
.idea
|
2
|
+
|
3
|
+
*.gem
|
4
|
+
*.rbc
|
5
|
+
/.config
|
6
|
+
/coverage/
|
7
|
+
/InstalledFiles
|
8
|
+
/pkg/
|
9
|
+
/spec/reports/
|
10
|
+
/test/tmp/
|
11
|
+
/test/version_tmp/
|
12
|
+
/tmp/
|
13
|
+
.bundle
|
14
|
+
.config
|
15
|
+
.yardoc
|
16
|
+
Gemfile.lock
|
17
|
+
InstalledFiles
|
18
|
+
_yardoc
|
19
|
+
coverage
|
20
|
+
doc/
|
21
|
+
lib/bundler/man
|
22
|
+
pkg
|
23
|
+
rdoc
|
24
|
+
spec/reports
|
25
|
+
test/tmp
|
26
|
+
test/version_tmp
|
27
|
+
tmp
|
28
|
+
*.bundle
|
29
|
+
*.so
|
30
|
+
*.o
|
31
|
+
*.a
|
32
|
+
mkmf.log
|
33
|
+
|
34
|
+
|
35
|
+
## Specific to RubyMotion:
|
36
|
+
.dat*
|
37
|
+
.repl_history
|
38
|
+
build/
|
39
|
+
|
40
|
+
## Documentation cache and generated files:
|
41
|
+
/.yardoc/
|
42
|
+
/_yardoc/
|
43
|
+
/doc/
|
44
|
+
/rdoc/
|
45
|
+
|
46
|
+
## Environment normalisation:
|
47
|
+
/.bundle/
|
48
|
+
/lib/bundler/man/
|
49
|
+
|
50
|
+
# for a library or gem, you might want to ignore these files since the code is
|
51
|
+
# intended to run in multiple environments; otherwise, check them in:
|
52
|
+
# Gemfile.lock
|
53
|
+
# .ruby-version
|
54
|
+
# .ruby-gemset
|
55
|
+
|
56
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
57
|
+
.rvmrc
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Eduardo Turiño
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Eapi (Elastic API)
|
2
|
+
|
3
|
+
ruby gem for building complex structures that will end up in hashes (initially devised for ElasticSearch search requests)
|
4
|
+
|
5
|
+
[](https://coveralls.io/r/eturino/eapi)
|
6
|
+
[](https://travis-ci.org/eturino/eapi)
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'eapi'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install eapi
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
TODO: Write usage instructions here
|
25
|
+
|
26
|
+
## Contributing
|
27
|
+
|
28
|
+
1. Fork it ( https://github.com/eturino/eapi/fork )
|
29
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
30
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
31
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
32
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/eapi.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'eapi/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "eapi"
|
8
|
+
spec.version = Eapi::VERSION
|
9
|
+
spec.authors = ["Eduardo Turiño"]
|
10
|
+
spec.email = ["eturino@eturino.com"]
|
11
|
+
spec.summary = %q{ruby gem for building complex structures that will end up in hashes (initially devised for ElasticSearch search requests)}
|
12
|
+
#spec.description = %q{TODO: Write a longer description. Optional.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "rspec-nc"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
spec.add_development_dependency "pry-nav"
|
27
|
+
spec.add_development_dependency "pry-rescue"
|
28
|
+
spec.add_development_dependency "pry-stack_explorer"
|
29
|
+
spec.add_development_dependency "pry-doc"
|
30
|
+
spec.add_development_dependency "coveralls"
|
31
|
+
|
32
|
+
spec.add_dependency 'activesupport', '~> 4'
|
33
|
+
spec.add_dependency 'activemodel', '~> 4'
|
34
|
+
end
|
data/lib/eapi.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
require 'active_model'
|
3
|
+
|
4
|
+
require 'eapi/version'
|
5
|
+
require 'eapi/errors'
|
6
|
+
require 'eapi/multiple'
|
7
|
+
require 'eapi/methods'
|
8
|
+
require 'eapi/common'
|
9
|
+
|
10
|
+
|
11
|
+
module Eapi
|
12
|
+
def self.method_missing(method, *args, &block)
|
13
|
+
klass = const_get("Eapi::#{method}")
|
14
|
+
klass.new *args, &block
|
15
|
+
end
|
16
|
+
end
|
data/lib/eapi/common.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Eapi
|
2
|
+
module Common
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
include ActiveModel::Validations
|
6
|
+
include Eapi::Methods::Properties::InstanceMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(** properties)
|
10
|
+
properties.each do |k, v|
|
11
|
+
normal_setter = "#{k}="
|
12
|
+
#TODO: what to do with unrecognised properties
|
13
|
+
send normal_setter, v if respond_to? normal_setter
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_missing(method, *args)
|
18
|
+
catch(:response) do
|
19
|
+
Eapi::Methods::Types.check_asking_type method, self
|
20
|
+
|
21
|
+
# if nothing catch -> continue super
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_h
|
27
|
+
raise Eapi::Errors::InvalidElementError, "errors: #{errors.full_messages}, self: #{self.inspect}" unless valid?
|
28
|
+
|
29
|
+
create_hash
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_hash
|
33
|
+
{}.tap do |hash|
|
34
|
+
self.class.properties.each do |prop|
|
35
|
+
stored = get(prop)
|
36
|
+
val = (stored.present? && stored.respond_to?(:to_h)) ? stored.to_h : stored
|
37
|
+
hash[prop] = val unless val.nil?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module ClassMethods
|
43
|
+
include Eapi::Methods::Accessor
|
44
|
+
include Eapi::Methods::Types::ClassMethods
|
45
|
+
include Eapi::Methods::Properties::ClassMethods
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/eapi/errors.rb
ADDED
data/lib/eapi/methods.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module Eapi
|
2
|
+
module Methods
|
3
|
+
|
4
|
+
module Accessor
|
5
|
+
def define_multiple_accessor(field)
|
6
|
+
init = Eapi::Methods::Names.init field
|
7
|
+
fluent_adder = Eapi::Methods::Names.add field
|
8
|
+
fluent_setter = Eapi::Methods::Names.fluent_setter field
|
9
|
+
getter = Eapi::Methods::Names.getter field
|
10
|
+
|
11
|
+
define_method fluent_adder do |value|
|
12
|
+
current = send(getter) || send(init)
|
13
|
+
current << value
|
14
|
+
send(fluent_setter, current)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def define_init(field, type_class)
|
19
|
+
init = Eapi::Methods::Names.init field
|
20
|
+
instance_var = Eapi::Methods::Names.instance_var field
|
21
|
+
|
22
|
+
define_method init do
|
23
|
+
value = type_class.new
|
24
|
+
instance_variable_set instance_var, value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def define_accessors(field)
|
29
|
+
normal_setter = Eapi::Methods::Names.setter field
|
30
|
+
fluent_setter = Eapi::Methods::Names.fluent_setter field
|
31
|
+
getter = Eapi::Methods::Names.getter field
|
32
|
+
instance_var = Eapi::Methods::Names.instance_var field
|
33
|
+
|
34
|
+
define_method normal_setter do |value|
|
35
|
+
instance_variable_set instance_var, value
|
36
|
+
end
|
37
|
+
|
38
|
+
# fluent setter that calls the normal setter and returns self
|
39
|
+
define_method fluent_setter do |value|
|
40
|
+
send normal_setter, value
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
# special getter => if no arguments it is a getter, if arguments it calls the fluent setter
|
45
|
+
define_method getter do |*args|
|
46
|
+
if args.empty?
|
47
|
+
instance_variable_get instance_var
|
48
|
+
else
|
49
|
+
send fluent_setter, *args
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Eapi
|
2
|
+
module Methods
|
3
|
+
|
4
|
+
module Names
|
5
|
+
def self.init(field)
|
6
|
+
"init_#{field}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.clear(field)
|
10
|
+
"clear_#{field}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.add(field)
|
14
|
+
"add_#{field}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.getter(field)
|
18
|
+
"#{field}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.setter(field)
|
22
|
+
"#{field}="
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.fluent_setter(field)
|
26
|
+
"set_#{field}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.instance_var(field)
|
30
|
+
"@#{field}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
module Eapi
|
2
|
+
module Methods
|
3
|
+
|
4
|
+
module Properties
|
5
|
+
module InstanceMethods
|
6
|
+
def get(field)
|
7
|
+
getter = Eapi::Methods::Names.getter field
|
8
|
+
send(getter)
|
9
|
+
end
|
10
|
+
|
11
|
+
def set(field, value)
|
12
|
+
setter = Eapi::Methods::Names.fluent_setter field
|
13
|
+
send(setter, value)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
def property(field, definition = {})
|
19
|
+
fs = field.to_sym
|
20
|
+
define_accessors fs
|
21
|
+
run_definition fs, definition
|
22
|
+
store_definition fs, definition
|
23
|
+
end
|
24
|
+
|
25
|
+
def properties
|
26
|
+
@_definitions.keys
|
27
|
+
end
|
28
|
+
|
29
|
+
def definition_for(field)
|
30
|
+
@_definitions ||= {}
|
31
|
+
@_definitions.fetch(field.to_sym, {}).dup
|
32
|
+
end
|
33
|
+
|
34
|
+
def store_definition(field, definition)
|
35
|
+
@_definitions ||= {}
|
36
|
+
@_definitions[field] = definition
|
37
|
+
end
|
38
|
+
|
39
|
+
def run_definition(field, definition)
|
40
|
+
DefinitionRunner.new(self, field, definition).run
|
41
|
+
end
|
42
|
+
|
43
|
+
private :run_definition
|
44
|
+
private :store_definition
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class DefinitionRunner < Struct.new(:klass, :field, :definition)
|
49
|
+
def run
|
50
|
+
run_multiple_accessor
|
51
|
+
run_init
|
52
|
+
run_validations
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
def run_validations
|
57
|
+
run_required
|
58
|
+
run_validate_type
|
59
|
+
run_validate_with
|
60
|
+
run_validate_type_element
|
61
|
+
run_validate_element_with
|
62
|
+
end
|
63
|
+
|
64
|
+
def run_validate_type
|
65
|
+
if type
|
66
|
+
klass.send :validates_each, field do |record, attr, value|
|
67
|
+
return if value.nil? && !required
|
68
|
+
|
69
|
+
record.errors.add(attr, "must be a #{type}") unless value.kind_of?(type)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def run_validate_element_with
|
75
|
+
if multiple && validate_element_with
|
76
|
+
validates_each field do |record, attr, value|
|
77
|
+
if value.respond_to?(:each)
|
78
|
+
value.each do |v|
|
79
|
+
validate_element_with.call(record, attr, v)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def run_validate_type_element
|
87
|
+
if multiple && type_element
|
88
|
+
validates_each field do |record, attr, value|
|
89
|
+
if value.respond_to?(:each)
|
90
|
+
value.each do |v|
|
91
|
+
record.errors.add(attr, "element must be a #{type}") unless v.kind_of?(type)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def run_validate_with
|
99
|
+
if validate_with
|
100
|
+
klass.send :validates_each, field do |record, attr, value|
|
101
|
+
validate_with.call(record, attr, value)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def run_required
|
107
|
+
if required
|
108
|
+
klass.send :validates_presence_of, field
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def run_init
|
113
|
+
if type || multiple
|
114
|
+
klass.send :define_init, field, type || Array
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def run_multiple_accessor
|
119
|
+
if multiple
|
120
|
+
klass.send :define_multiple_accessor, field
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def type_multiple?(type)
|
125
|
+
return false if type.nil?
|
126
|
+
return true if type == Array || type == Set
|
127
|
+
|
128
|
+
type.respond_to?(:is_multiple?) && type.is_multiple?
|
129
|
+
end
|
130
|
+
|
131
|
+
def validate_element_with
|
132
|
+
definition.fetch(:validate_element_with, nil)
|
133
|
+
end
|
134
|
+
|
135
|
+
def multiple
|
136
|
+
definition.fetch(:multiple, false) || type_multiple?(type)
|
137
|
+
end
|
138
|
+
|
139
|
+
def required
|
140
|
+
definition.fetch(:required, false)
|
141
|
+
end
|
142
|
+
|
143
|
+
def validate_with
|
144
|
+
definition.fetch(:validate_with, nil)
|
145
|
+
end
|
146
|
+
|
147
|
+
def type_element
|
148
|
+
definition.fetch(:type_element, nil)
|
149
|
+
end
|
150
|
+
|
151
|
+
def type
|
152
|
+
definition.fetch(:type, nil)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Eapi
|
2
|
+
module Methods
|
3
|
+
|
4
|
+
module Types
|
5
|
+
def self.type_question_method(method)
|
6
|
+
ms = method.to_s
|
7
|
+
if ms.start_with?('is_a_') && ms.end_with?('?')
|
8
|
+
ms.sub('is_a_', '').sub('?', '')
|
9
|
+
else
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.check_asking_type(method, obj)
|
15
|
+
type = Types.type_question_method method
|
16
|
+
if type
|
17
|
+
throw :response, obj.class.is?(type)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
def is?(type)
|
24
|
+
@i_am_a && @i_am_a.include?(type.to_sym)
|
25
|
+
end
|
26
|
+
|
27
|
+
def is(*types)
|
28
|
+
@i_am_a ||= []
|
29
|
+
@i_am_a.concat(types.map(&:to_sym))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/eapi/version.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Eapi do
|
4
|
+
|
5
|
+
context 'basic behaviour' do
|
6
|
+
class Eapi::MyTestKlass
|
7
|
+
include Eapi::Common
|
8
|
+
|
9
|
+
property :something
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#something (fluent setter/getter)' do
|
13
|
+
describe '#something as getter' do
|
14
|
+
it 'return the value' do
|
15
|
+
eapi = Eapi::MyTestKlass.new something: :hey
|
16
|
+
expect(eapi.something).to eq :hey
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#something("val")' do
|
21
|
+
it 'set the value and return self' do
|
22
|
+
eapi = Eapi::MyTestKlass.new something: :hey
|
23
|
+
res = eapi.something :other
|
24
|
+
expect(eapi).to be res
|
25
|
+
expect(eapi.something).to eq :other
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'Eapi.MyTestKlass(...)' do
|
31
|
+
it 'calls EapiTestClass.new' do
|
32
|
+
eapi = Eapi.MyTestKlass(something: :hey)
|
33
|
+
expect(eapi).to be_a Eapi::MyTestKlass
|
34
|
+
expect(eapi.something).to eq :hey
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Eapi do
|
4
|
+
|
5
|
+
context 'list' do
|
6
|
+
class Eapi::MyTestClassValMult
|
7
|
+
include Eapi::Common
|
8
|
+
|
9
|
+
property :something, multiple: true
|
10
|
+
end
|
11
|
+
|
12
|
+
it '#add_something' do
|
13
|
+
eapi = Eapi::MyTestClassValMult.new something: [1, 2]
|
14
|
+
res = eapi.add_something 3
|
15
|
+
expect(res).to be eapi
|
16
|
+
expect(eapi.something).to eq [1, 2, 3]
|
17
|
+
end
|
18
|
+
|
19
|
+
it '#init_something called on first add if element is nil' do
|
20
|
+
eapi = Eapi::MyTestClassValMult.new
|
21
|
+
res = eapi.add_something :a
|
22
|
+
expect(res).to be eapi
|
23
|
+
expect(eapi.something.to_a).to eq [:a]
|
24
|
+
end
|
25
|
+
|
26
|
+
class Eapi::MyTestClassValMultImpl
|
27
|
+
include Eapi::Common
|
28
|
+
|
29
|
+
property :something, type: Set
|
30
|
+
end
|
31
|
+
|
32
|
+
class MyMultiple
|
33
|
+
def self.is_multiple?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def <<(x)
|
38
|
+
@elements ||= []
|
39
|
+
@elements << x
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_a
|
43
|
+
@elements.to_a
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Eapi::MyTestClassValMultImpl2
|
48
|
+
include Eapi::Common
|
49
|
+
|
50
|
+
property :something, type: MyMultiple
|
51
|
+
end
|
52
|
+
|
53
|
+
class MyMultipleEapi
|
54
|
+
include Eapi::Multiple
|
55
|
+
|
56
|
+
def <<(x)
|
57
|
+
@elements ||= []
|
58
|
+
@elements << x
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_a
|
62
|
+
@elements.to_a
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Eapi::MyTestClassValMultImpl3
|
67
|
+
include Eapi::Common
|
68
|
+
|
69
|
+
property :something, type: MyMultipleEapi
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'if type is Array or Set, or responds true to is_multiple?, it is multiple implicitly + uses that class to initialize the property when adding' do
|
73
|
+
[
|
74
|
+
[Eapi::MyTestClassValMult, Array],
|
75
|
+
[Eapi::MyTestClassValMultImpl, Set],
|
76
|
+
[Eapi::MyTestClassValMultImpl2, MyMultiple],
|
77
|
+
[Eapi::MyTestClassValMultImpl3, MyMultipleEapi],
|
78
|
+
].each do |(eapi_class, type_class)|
|
79
|
+
eapi = eapi_class.new
|
80
|
+
res = eapi.add_something :a
|
81
|
+
expect(res).to be eapi
|
82
|
+
expect(eapi.something.to_a).to eq [:a]
|
83
|
+
expect(eapi.something).to be_a_kind_of type_class
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'validate elements' do
|
88
|
+
skip 'test TBD'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Eapi do
|
4
|
+
|
5
|
+
context '#to_h' do
|
6
|
+
class Eapi::MyTestClassToH
|
7
|
+
include Eapi::Common
|
8
|
+
|
9
|
+
property :something, required: true
|
10
|
+
property :other
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'raise error if invalid' do
|
14
|
+
eapi = Eapi::MyTestClassToH.new
|
15
|
+
expect { eapi.to_h }.to raise_error do |error|
|
16
|
+
expect(error).to be_a_kind_of Eapi::Errors::InvalidElementError
|
17
|
+
expect(error.message).to be_start_with "errors: [\"Something can't be blank\"], self: #<Eapi::MyTestClassToH"
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'create a hash with elements (calling to_h to each element), avoiding nils' do
|
23
|
+
eapi = Eapi::MyTestClassToH.new
|
24
|
+
eapi.something 'hi'
|
25
|
+
expected = {something: 'hi'}
|
26
|
+
expect(eapi.to_h).to eq expected
|
27
|
+
|
28
|
+
class MyTestObject
|
29
|
+
def to_h
|
30
|
+
'hello'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
element = MyTestObject.new
|
35
|
+
eapi = Eapi::MyTestClassToH.new
|
36
|
+
eapi.something(element).other(true)
|
37
|
+
expected = {something: 'hello', other: true}
|
38
|
+
|
39
|
+
expect(eapi.to_h).to eq expected
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Eapi do
|
4
|
+
|
5
|
+
context 'validations' do
|
6
|
+
describe '#valid?' do
|
7
|
+
it 'true if no validations' do
|
8
|
+
class Eapi::MyTestClassVal
|
9
|
+
include Eapi::Common
|
10
|
+
|
11
|
+
property :something
|
12
|
+
end
|
13
|
+
|
14
|
+
eapi = Eapi::MyTestClassVal.new something: :hey
|
15
|
+
expect(eapi).to be_valid
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'false if validations not met' do
|
19
|
+
class Eapi::MyTestClassVal2
|
20
|
+
include Eapi::Common
|
21
|
+
|
22
|
+
property :something
|
23
|
+
|
24
|
+
validates_presence_of :something
|
25
|
+
end
|
26
|
+
|
27
|
+
eapi = Eapi::MyTestClassVal2.new
|
28
|
+
expect(eapi).not_to be_valid
|
29
|
+
expect(eapi.errors.full_messages).to eq ["Something can't be blank"]
|
30
|
+
expect(eapi.errors.messages).to eq({something: ["can't be blank"]})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'if required, same as validate presence' do
|
35
|
+
class Eapi::MyTestClassVal3
|
36
|
+
include Eapi::Common
|
37
|
+
|
38
|
+
property :something, required: true
|
39
|
+
end
|
40
|
+
|
41
|
+
eapi = Eapi::MyTestClassVal3.new
|
42
|
+
expect(eapi).not_to be_valid
|
43
|
+
expect(eapi.errors.full_messages).to eq ["Something can't be blank"]
|
44
|
+
expect(eapi.errors.messages).to eq({something: ["can't be blank"]})
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'if type specified with a class, validates it' do
|
48
|
+
class Eapi::MyTestClassVal3
|
49
|
+
include Eapi::Common
|
50
|
+
|
51
|
+
property :something, type: Hash
|
52
|
+
end
|
53
|
+
|
54
|
+
eapi = Eapi::MyTestClassVal3.new something: 1
|
55
|
+
expect(eapi).not_to be_valid
|
56
|
+
expect(eapi.errors.full_messages).to eq ["Something must be a Hash"]
|
57
|
+
expect(eapi.errors.messages).to eq({something: ["must be a Hash"]})
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'if validate_with: specified with a class, uses it to validate the property' do
|
61
|
+
class Eapi::MyTestClassVal4
|
62
|
+
include Eapi::Common
|
63
|
+
|
64
|
+
property :something, validate_with: ->(record, attr, value) do
|
65
|
+
record.errors.add(attr, "must pass my custom validation") unless value == :valid_val
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
eapi = Eapi::MyTestClassVal4.new something: 1
|
70
|
+
|
71
|
+
expect(eapi).not_to be_valid
|
72
|
+
expect(eapi.errors.full_messages).to eq ["Something must pass my custom validation"]
|
73
|
+
expect(eapi.errors.messages).to eq({something: ["must pass my custom validation"]})
|
74
|
+
|
75
|
+
eapi.something :valid_val
|
76
|
+
expect(eapi).to be_valid
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,243 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eapi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eduardo Turiño
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-nc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry-nav
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry-rescue
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry-stack_explorer
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry-doc
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: coveralls
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: activesupport
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '4'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '4'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: activemodel
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '4'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '4'
|
181
|
+
description:
|
182
|
+
email:
|
183
|
+
- eturino@eturino.com
|
184
|
+
executables: []
|
185
|
+
extensions: []
|
186
|
+
extra_rdoc_files: []
|
187
|
+
files:
|
188
|
+
- ".coveralls.yml"
|
189
|
+
- ".gitignore"
|
190
|
+
- ".rspec"
|
191
|
+
- ".travis.yml"
|
192
|
+
- Gemfile
|
193
|
+
- LICENSE.txt
|
194
|
+
- README.md
|
195
|
+
- Rakefile
|
196
|
+
- eapi.gemspec
|
197
|
+
- lib/eapi.rb
|
198
|
+
- lib/eapi/common.rb
|
199
|
+
- lib/eapi/errors.rb
|
200
|
+
- lib/eapi/methods.rb
|
201
|
+
- lib/eapi/methods/accessor.rb
|
202
|
+
- lib/eapi/methods/names.rb
|
203
|
+
- lib/eapi/methods/properties.rb
|
204
|
+
- lib/eapi/methods/types.rb
|
205
|
+
- lib/eapi/multiple.rb
|
206
|
+
- lib/eapi/version.rb
|
207
|
+
- spec/eapi_basic_spec.rb
|
208
|
+
- spec/eapi_list_spec.rb
|
209
|
+
- spec/eapi_to_h_spec.rb
|
210
|
+
- spec/eapi_validations_spec.rb
|
211
|
+
- spec/spec_helper.rb
|
212
|
+
homepage: ''
|
213
|
+
licenses:
|
214
|
+
- MIT
|
215
|
+
metadata: {}
|
216
|
+
post_install_message:
|
217
|
+
rdoc_options: []
|
218
|
+
require_paths:
|
219
|
+
- lib
|
220
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
221
|
+
requirements:
|
222
|
+
- - ">="
|
223
|
+
- !ruby/object:Gem::Version
|
224
|
+
version: '0'
|
225
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
requirements: []
|
231
|
+
rubyforge_project:
|
232
|
+
rubygems_version: 2.2.2
|
233
|
+
signing_key:
|
234
|
+
specification_version: 4
|
235
|
+
summary: ruby gem for building complex structures that will end up in hashes (initially
|
236
|
+
devised for ElasticSearch search requests)
|
237
|
+
test_files:
|
238
|
+
- spec/eapi_basic_spec.rb
|
239
|
+
- spec/eapi_list_spec.rb
|
240
|
+
- spec/eapi_to_h_spec.rb
|
241
|
+
- spec/eapi_validations_spec.rb
|
242
|
+
- spec/spec_helper.rb
|
243
|
+
has_rdoc:
|