skala 0.0.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +17 -9
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +15 -1
- data/README.md +5 -2
- data/Rakefile +4 -0
- data/lib/skala/adapter/operation.rb +9 -0
- data/lib/skala/adapter.rb +12 -0
- data/lib/skala/i18n/deep_merger.rb +45 -0
- data/lib/skala/i18n.rb +42 -0
- data/lib/skala/transformation/step.rb +24 -0
- data/lib/skala/transformation.rb +54 -0
- data/lib/skala/version.rb +1 -1
- data/lib/skala.rb +3 -1
- data/skala.gemspec +11 -4
- data/spec/assets/locales/de.yml +14 -0
- data/spec/assets/locales/en.yml +9 -0
- data/spec/assets/transformation/some_class.rb +2 -0
- data/spec/skala/adapter/operation_spec.rb +19 -0
- data/spec/skala/adapter_spec.rb +30 -0
- data/spec/skala/i18n/deep_merger_spec.rb +35 -0
- data/spec/skala/i18n_spec.rb +92 -0
- data/spec/skala/transformation/step_spec.rb +36 -0
- data/spec/skala/transformation_spec.rb +80 -0
- data/spec/skala_spec.rb +2 -0
- data/spec/spec_helper.rb +52 -0
- metadata +136 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4cd834fb20b0e4148938d42dd92abecb54e49b8f
|
4
|
+
data.tar.gz: d9c1fc1820efddffa3777811aa8eeffc6034ae5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56346c0e4261433885405a632b7efc29b2561a6ac58ee7eb7e8cacc1118f62b9142217465696ccae3f36e7922776a98a219d1591df2dd2691691544940c61710
|
7
|
+
data.tar.gz: bef839d6c64e4a345705109535e9cad8ff74e416871366837b0d5135ad6d2c467661ebc87a7c4ba83c2452d790789592da456490fa2afc3a371309a6cd7aa35c
|
data/.gitignore
CHANGED
@@ -1,12 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
10
18
|
*.bundle
|
11
19
|
*.so
|
12
20
|
*.o
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -1,4 +1,18 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in skala.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
if !ENV["CI"]
|
7
|
+
group :development do
|
8
|
+
gem "pry", "~> 0.9.12.6"
|
9
|
+
gem "pry-byebug", "<= 1.3.2"
|
10
|
+
gem "pry-rescue", "~> 1.4.1"
|
11
|
+
gem "pry-stack_explorer", "~> 0.4.9.1"
|
12
|
+
gem "pry-syntax-hacks", "~> 0.0.6"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
group :test do
|
17
|
+
gem "codeclimate-test-reporter", require: nil
|
18
|
+
end
|
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# Skala
|
2
|
+
[![Build Status](https://travis-ci.org/ubpb/skala.svg?branch=master)](https://travis-ci.org/ubpb/skala)
|
3
|
+
[![Test Coverage](https://codeclimate.com/github/ubpb/skala/badges/coverage.svg)](https://codeclimate.com/github/ubpb/skala)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/ubpb/skala/badges/gpa.svg)](https://codeclimate.com/github/ubpb/skala)
|
2
5
|
|
3
|
-
|
6
|
+
Skala was created as a base for common adapter specific code and functionality. It was extract from ```celsius``` and ```fahrenheit``` to avoid code duplication and unnecessary inter-gem-linkage.
|
4
7
|
|
5
8
|
## Installation
|
6
9
|
|
@@ -24,7 +27,7 @@ TODO: Write usage instructions here
|
|
24
27
|
|
25
28
|
## Contributing
|
26
29
|
|
27
|
-
1. Fork it ( https://github.com/
|
30
|
+
1. Fork it ( https://github.com/ubpb/skala/fork )
|
28
31
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
32
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
33
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/Rakefile
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative "./i18n"
|
2
|
+
require_relative "../skala"
|
3
|
+
|
4
|
+
class Skala::Adapter
|
5
|
+
require_relative "./adapter/operation"
|
6
|
+
|
7
|
+
include Skala::I18n
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
self.class.load_locales_from_directory("#{File.dirname(__FILE__)}/locales")
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative "../i18n"
|
2
|
+
|
3
|
+
module Skala::I18n::DeepMerger
|
4
|
+
def self.deep_merge!(destination, source, options = {})
|
5
|
+
if destination.kind_of?(Array)
|
6
|
+
if source.kind_of?(Array)
|
7
|
+
# array into array
|
8
|
+
source.each do |element|
|
9
|
+
self.deep_merge!(destination, element, options)
|
10
|
+
end
|
11
|
+
elsif source.kind_of?(Hash)
|
12
|
+
# hash into array
|
13
|
+
destination.push(source)
|
14
|
+
else
|
15
|
+
# literal into array
|
16
|
+
destination.push(source)
|
17
|
+
end
|
18
|
+
elsif destination.kind_of?(Hash)
|
19
|
+
if source.kind_of?(Array)
|
20
|
+
# array into hash
|
21
|
+
raise ArgumentError, "Cannot merge array into hash!"
|
22
|
+
elsif source.kind_of?(Hash)
|
23
|
+
# hash into hash
|
24
|
+
destination.merge!(source) do |key, destination_value, source_value|
|
25
|
+
self.deep_merge!(destination_value, source_value, options)
|
26
|
+
destination_value
|
27
|
+
end
|
28
|
+
else
|
29
|
+
# literal into hash
|
30
|
+
raise ArgumentError, "Cannot merge literal into hash!"
|
31
|
+
end
|
32
|
+
else
|
33
|
+
if source.kind_of?(Array)
|
34
|
+
# array into literal
|
35
|
+
raise ArgumentError, "Cannot merge array into literal!"
|
36
|
+
elsif source.kind_of?(Hash)
|
37
|
+
# hash into literal
|
38
|
+
raise ArgumentError, "Cannot merge hash into literal!"
|
39
|
+
else
|
40
|
+
# literal into literal
|
41
|
+
destination = source # in fact a useless assignment to fit into the overall semantic
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/skala/i18n.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require_relative "../skala"
|
3
|
+
|
4
|
+
module Skala::I18n
|
5
|
+
require_relative "./i18n/deep_merger"
|
6
|
+
|
7
|
+
def self.included(klass)
|
8
|
+
unless klass.class_variable_defined?(:@@locales)
|
9
|
+
klass.class_variable_set(:@@locales, {})
|
10
|
+
end
|
11
|
+
|
12
|
+
klass.extend(ClassMethods)
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def load_locales_from_directory(path)
|
17
|
+
# class_variable_get is needed to avoid implicite referencing the module instead of the including class
|
18
|
+
Dir.glob("#{File.expand_path(path)}/*.yml").inject(self.class_variable_get(:@@locales)) do |locales, filename|
|
19
|
+
DeepMerger.deep_merge!(locales, YAML.load_file(filename))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def translate(key, options = {})
|
25
|
+
raise "Destination locale missing!" if options[:locale].nil?
|
26
|
+
|
27
|
+
fully_qualified_key = "#{options[:locale]}.#{key}"
|
28
|
+
keys_path = fully_qualified_key.split(".")
|
29
|
+
locales = self.class.class_variable_get(:@@locales)
|
30
|
+
|
31
|
+
translated_key = keys_path.inject(locales) do |hash, hash_key|
|
32
|
+
unless hash.nil?
|
33
|
+
hash[hash_key.to_s] || hash[hash_key.to_sym]
|
34
|
+
end
|
35
|
+
end || keys_path.last
|
36
|
+
|
37
|
+
translated_key.gsub(/%{[^}]+}+/) do |match|
|
38
|
+
interpolation_key = match.gsub(/(\A%{)|(}\Z)/, "")
|
39
|
+
options[interpolation_key.to_s] || options[interpolation_key.to_sym] || match
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative "../transformation"
|
2
|
+
|
3
|
+
class Skala::Transformation::Step
|
4
|
+
attr_accessor :transformation
|
5
|
+
|
6
|
+
def initialize(transformation)
|
7
|
+
@transformation = transformation
|
8
|
+
end
|
9
|
+
|
10
|
+
#
|
11
|
+
# Each step has transparent access to all methods of it's transformation
|
12
|
+
#
|
13
|
+
def method_missing(method_name, *args, &block)
|
14
|
+
if @transformation.respond_to?(method_name)
|
15
|
+
@transformation.send(method_name, *args, &block)
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def respond_to_missing?(method_name, include_private = false)
|
22
|
+
@transformation.respond_to?(method_name) || super
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative "../skala"
|
2
|
+
|
3
|
+
class Skala::Transformation
|
4
|
+
require_relative "./transformation/step"
|
5
|
+
|
6
|
+
#
|
7
|
+
# class methods
|
8
|
+
#
|
9
|
+
class << self
|
10
|
+
attr_accessor :steps
|
11
|
+
end
|
12
|
+
|
13
|
+
# since a transformation can have many steps, writing a "require" for each is tedious
|
14
|
+
def self.require_directory(directory)
|
15
|
+
Dir.glob("#{File.expand_path(directory)}/*.rb").each do |filename|
|
16
|
+
require filename
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# convenience wrapper for @steps setter to enhance readability
|
21
|
+
def self.sequence(value)
|
22
|
+
self.steps = value
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# instance methods
|
27
|
+
#
|
28
|
+
attr_accessor :source
|
29
|
+
attr_accessor :target
|
30
|
+
|
31
|
+
def apply(options = {})
|
32
|
+
if (@source = options[:source] ||= options[:to]).nil?
|
33
|
+
raise ArgumentError, "No source given to apply transformation to!"
|
34
|
+
end
|
35
|
+
|
36
|
+
@target = options[:target]
|
37
|
+
|
38
|
+
self.class.steps.flatten.each do |step|
|
39
|
+
break if @__aborted
|
40
|
+
|
41
|
+
if step.is_a?(Class)
|
42
|
+
step.new(self).call
|
43
|
+
else
|
44
|
+
step.call(self)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
return @target
|
49
|
+
end
|
50
|
+
|
51
|
+
def abort!
|
52
|
+
@__aborted = true
|
53
|
+
end
|
54
|
+
end
|
data/lib/skala/version.rb
CHANGED
data/lib/skala.rb
CHANGED
data/skala.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "skala/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "skala"
|
@@ -16,6 +16,13 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
17
|
spec.require_paths = ["lib"]
|
18
18
|
|
19
|
-
spec.
|
20
|
-
|
19
|
+
spec.add_dependency "activesupport"
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "ox", ">= 2.1.0"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rspec", ">= 3.0.0", "< 3.2.0"
|
25
|
+
spec.add_development_dependency "simplecov", ">= 0.8.0"
|
26
|
+
spec.add_development_dependency "vcr", ">= 2.9.0", "< 3.0.0"
|
27
|
+
spec.add_development_dependency "webmock", ">= 1.19.0", "< 2.0.0"
|
21
28
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
de:
|
2
|
+
field_names:
|
3
|
+
_all: Alle Felder
|
4
|
+
_score: Relevanz
|
5
|
+
created: Erscheinungsjahr
|
6
|
+
creator: Autor/Herausgeber
|
7
|
+
identifier: Identifikator
|
8
|
+
subject: Schlagwort
|
9
|
+
title: Titel
|
10
|
+
|
11
|
+
records:
|
12
|
+
items:
|
13
|
+
loan_status:
|
14
|
+
expected: Erwartet zum %{expected_date}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
describe Skala::Adapter::Operation do
|
2
|
+
let(:adapter) do
|
3
|
+
{
|
4
|
+
some: "adapter"
|
5
|
+
}
|
6
|
+
end
|
7
|
+
|
8
|
+
context "if initialized with a adapter" do
|
9
|
+
let(:operation) do
|
10
|
+
described_class.new(adapter)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#adapter" do
|
14
|
+
it "returns the adapter the operation was initialized with" do
|
15
|
+
expect(operation.adapter).to eq(adapter)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
describe Skala::Adapter do
|
2
|
+
let(:adapter) { described_class.new() }
|
3
|
+
|
4
|
+
context "when a class is derived from #{described_class}" do
|
5
|
+
context "when the derived class overwrites .initialize" do
|
6
|
+
context "when the derived class calls super inside the overwritten .initalize" do
|
7
|
+
let(:derived_class) do
|
8
|
+
Class.new(described_class) do
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
|
12
|
+
self.class.load_locales_from_directory(File.expand_path("#{File.dirname(__FILE__)}/../assets/locales"))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:derived_class_instance) do
|
18
|
+
derived_class.new
|
19
|
+
end
|
20
|
+
|
21
|
+
it "has access to the superclass locales" do
|
22
|
+
translation_key_known_by_superclass = "field_names.creator"
|
23
|
+
translation = derived_class_instance.translate(translation_key_known_by_superclass, locale: :de)
|
24
|
+
expected_translation = derived_class_instance.class.class_variable_get(:@@locales)["de"]["field_names"]["creator"]
|
25
|
+
expect(translation).to eq(expected_translation)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
describe Skala::I18n::DeepMerger do
|
2
|
+
describe ".deep_merge!" do
|
3
|
+
describe "merges arrays into arrays" do
|
4
|
+
it "merges two arrays of literals" do
|
5
|
+
source = [1,"2",:f]
|
6
|
+
destination = [:"3", 5, "foo"]
|
7
|
+
described_class.deep_merge!(destination, source)
|
8
|
+
expect(destination).to eq([:"3", 5, "foo", 1, "2", :f])
|
9
|
+
end
|
10
|
+
|
11
|
+
it "merges two arrays of hashes" do
|
12
|
+
source = [{c:3}]
|
13
|
+
destination = [{a: 1}, {b:2}]
|
14
|
+
described_class.deep_merge!(destination, source)
|
15
|
+
expect(destination).to eq([{:a=>1}, {:b=>2}, {:c=>3}])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "merges hashes into hashes" do
|
20
|
+
it "merges two simple hashes" do
|
21
|
+
source = { c: 3 }
|
22
|
+
destination = { a: 1, b: 2 }
|
23
|
+
described_class.deep_merge!(destination, source)
|
24
|
+
expect(destination).to eq({:a=>1, :b=>2, :c=>3})
|
25
|
+
end
|
26
|
+
|
27
|
+
it "merges two nested hashes" do
|
28
|
+
source = { a: { type: "multi_value", values: [2,3] }, b: { value: "123" } }
|
29
|
+
destination = { a: { values: [1]}, b: { type: "id" } }
|
30
|
+
described_class.deep_merge!(destination, source)
|
31
|
+
expect(destination).to eq({:a=>{:values=>[1, 2, 3], :type=>"multi_value"}, :b=>{:type=>"id", :value=>"123"}})
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
describe Skala::I18n do
|
2
|
+
let(:class_with_i18n_included) do
|
3
|
+
Class.new.tap do |_klass|
|
4
|
+
_klass.send(:include, described_class)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
context "when included into a class" do
|
9
|
+
context "when the including class has a class variable named @@locales" do
|
10
|
+
let(:value_of_locales) do
|
11
|
+
{ foo: "bar" }
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:klass) do
|
15
|
+
Class.new.tap do |_klass|
|
16
|
+
_klass.class_variable_set(:@@locales, value_of_locales)
|
17
|
+
_klass.send(:include, described_class)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "does not alter the existing class variable" do
|
22
|
+
expect(klass.class_variable_get(:@@locales)).to eq(value_of_locales)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when the including class has no class variable named @@locales" do
|
27
|
+
let(:klass) do
|
28
|
+
Class.new.tap do |_klass|
|
29
|
+
_klass.send(:include, described_class)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "defines a class variable named @@locales as an empty hash" do
|
34
|
+
expect(klass.class_variable_get(:@@locales)).to eq({})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "defines a class method #load_locales_from_directory" do
|
39
|
+
expect(class_with_i18n_included).to respond_to(:load_locales_from_directory)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "defines an instance method .translate" do
|
43
|
+
expect(class_with_i18n_included.new).to respond_to(:translate)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#load_locales_from_directory" do
|
48
|
+
it "loads all yaml encoded locales from a directory and adds them to @@locales" do
|
49
|
+
class_with_i18n_included.load_locales_from_directory(File.expand_path("#{File.dirname(__FILE__)}/../assets/locales"))
|
50
|
+
expect(class_with_i18n_included.class_variable_get(:@@locales)).not_to be_empty
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#translate" do
|
55
|
+
let(:object) do
|
56
|
+
class_with_i18n_included.new.tap do |_object|
|
57
|
+
_object.class.load_locales_from_directory(File.expand_path("#{File.dirname(__FILE__)}/../assets/locales"))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "translates the given key into the language specified by the locale option" do
|
62
|
+
translated_key_de = object.translate("field_names.creator", locale: :de)
|
63
|
+
translated_key_en = object.translate("field_names.creator", locale: :en)
|
64
|
+
|
65
|
+
expected_translation_de = object.class.class_variable_get(:@@locales)["de"]["field_names"]["creator"]
|
66
|
+
expected_translation_en = object.class.class_variable_get(:@@locales)["en"]["field_names"]["creator"]
|
67
|
+
|
68
|
+
expect(translated_key_de).to eq(expected_translation_de)
|
69
|
+
expect(translated_key_en).to eq(expected_translation_en)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "supports rails style interpolation" do
|
73
|
+
expected_date = "1. Januar 2015"
|
74
|
+
translated_key = object.translate("records.items.loan_status.expected", locale: :de, expected_date: expected_date)
|
75
|
+
expected_translation = object.class.class_variable_get(:@@locales)["de"]["records"]["items"]["loan_status"]["expected"].gsub("%{expected_date}", expected_date)
|
76
|
+
|
77
|
+
expect(translated_key).to eq(expected_translation)
|
78
|
+
end
|
79
|
+
|
80
|
+
context "when there is no translation" do
|
81
|
+
it "returns to last key path" do
|
82
|
+
expect(object.translate("foo.bar.muff", locale: :en)).to eq("muff")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when no locale option is given" do
|
87
|
+
it "raises an exception" do
|
88
|
+
expect { object.translate("field_names.creator") }.to raise_error
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
describe Skala::Transformation::Step do
|
2
|
+
context "when initialized with a transformation" do
|
3
|
+
let(:transformation) do
|
4
|
+
Class.new(Skala::Transformation) do
|
5
|
+
def some_transformation_method
|
6
|
+
true
|
7
|
+
end
|
8
|
+
end.new
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:step) do
|
12
|
+
described_class.new(transformation)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#transformation" do
|
16
|
+
it "allows access to the transformation" do
|
17
|
+
expect(step.transformation).to be(transformation)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "if a unknown method is called" do
|
22
|
+
context "if the transformation has a matching method" do
|
23
|
+
it "calls the method on the transformation" do
|
24
|
+
expect(step).to respond_to(:some_transformation_method)
|
25
|
+
expect(step.some_transformation_method).to eq(transformation.some_transformation_method)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "if the transformation has no matching method" do
|
30
|
+
it "raises an error" do
|
31
|
+
expect { step.some_unknown_method }.to raise_error
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
describe Skala::Transformation do
|
2
|
+
describe ".require_directory" do
|
3
|
+
it "requires all *.rb files in the given directory" do
|
4
|
+
described_class.require_directory "#{File.dirname(__FILE__)}/../assets/transformation"
|
5
|
+
expect(defined?(SomeClass)).to eq("constant")
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#sequence" do
|
10
|
+
let(:steps_array) do
|
11
|
+
[ -> { } ]
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:transformation) do
|
15
|
+
steps = steps_array
|
16
|
+
|
17
|
+
Class.new(described_class) do
|
18
|
+
sequence steps
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "is a wrapper for the steps setter" do
|
23
|
+
expect(transformation.steps).to be(steps_array)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#abort!" do
|
28
|
+
let(:transformation) do
|
29
|
+
Class.new(described_class) do
|
30
|
+
sequence [
|
31
|
+
-> (transformation) do
|
32
|
+
transformation.target = "first_steps_output"
|
33
|
+
transformation.abort!
|
34
|
+
end,
|
35
|
+
-> (transformation) do
|
36
|
+
transformation.target = "second_steps_output"
|
37
|
+
end
|
38
|
+
]
|
39
|
+
end.new
|
40
|
+
end
|
41
|
+
|
42
|
+
it "aborts the execution of the steps sequence" do
|
43
|
+
expect(transformation.apply to: {}).to eq("first_steps_output")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#apply" do
|
48
|
+
let(:transformation) do
|
49
|
+
step_class = Class.new(described_class::Step) do
|
50
|
+
def call
|
51
|
+
transformation.target = source.dup
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
step_lambda = -> (transformation) do
|
56
|
+
transformation.target.upcase!
|
57
|
+
end
|
58
|
+
|
59
|
+
Class.new(described_class) do
|
60
|
+
sequence [
|
61
|
+
step_class,
|
62
|
+
step_lambda
|
63
|
+
]
|
64
|
+
end.new
|
65
|
+
end
|
66
|
+
|
67
|
+
context "if no :source or :to option is given" do
|
68
|
+
it "raises an error" do
|
69
|
+
expect { transformation.apply }.to raise_error(ArgumentError)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it "applies the transformation" do
|
74
|
+
some_string = "foo"
|
75
|
+
|
76
|
+
expect(transformation.apply(to: some_string)).to eq(some_string.upcase)
|
77
|
+
expect(some_string).to eq("foo")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/spec/skala_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
if ENV["CODECLIMATE_REPO_TOKEN"]
|
2
|
+
require "codeclimate-test-reporter"
|
3
|
+
CodeClimate::TestReporter.start
|
4
|
+
else
|
5
|
+
require "simplecov"
|
6
|
+
SimpleCov.start
|
7
|
+
end
|
8
|
+
|
9
|
+
begin
|
10
|
+
require "pry"
|
11
|
+
rescue LoadError
|
12
|
+
end
|
13
|
+
|
14
|
+
require "skala"
|
15
|
+
require "vcr"
|
16
|
+
require "yaml"
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
# begin --- rspec 3.1 generator
|
20
|
+
config.expect_with :rspec do |expectations|
|
21
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
22
|
+
end
|
23
|
+
|
24
|
+
config.mock_with :rspec do |mocks|
|
25
|
+
mocks.verify_partial_doubles = true
|
26
|
+
end
|
27
|
+
# end --- rspec 3.1 generator
|
28
|
+
end
|
29
|
+
|
30
|
+
VCR.configure do |c|
|
31
|
+
c.allow_http_connections_when_no_cassette = true
|
32
|
+
c.cassette_library_dir = "spec/cassettes"
|
33
|
+
c.default_cassette_options = {
|
34
|
+
match_requests_on: [:method, :uri, :query, :body],
|
35
|
+
decode_compressed_response: true
|
36
|
+
}
|
37
|
+
c.hook_into :webmock
|
38
|
+
|
39
|
+
# https://groups.google.com/forum/#!topic/vcr-ruby/2sKrJa86ktU
|
40
|
+
c.before_record do |interaction|
|
41
|
+
if interaction.response.body.encoding.name == "ASCII-8BIT"
|
42
|
+
interaction.response.body.force_encoding("UTF-8")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# https://relishapp.com/vcr/vcr/v/2-9-3/docs/test-frameworks/usage-with-rspec-metadata
|
47
|
+
c.configure_rspec_metadata!
|
48
|
+
end
|
49
|
+
|
50
|
+
def read_asset(path_to_file)
|
51
|
+
File.read(File.expand_path(File.join(File.dirname(__FILE__), "assets", path_to_file)))
|
52
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skala
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Sievers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,6 +38,20 @@ dependencies:
|
|
24
38
|
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '1.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ox
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.1.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.1.0
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: rake
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +66,80 @@ dependencies:
|
|
38
66
|
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
68
|
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 3.0.0
|
76
|
+
- - "<"
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 3.2.0
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 3.0.0
|
86
|
+
- - "<"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 3.2.0
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: simplecov
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 0.8.0
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 0.8.0
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: vcr
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 2.9.0
|
110
|
+
- - "<"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 3.0.0
|
113
|
+
type: :development
|
114
|
+
prerelease: false
|
115
|
+
version_requirements: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: 2.9.0
|
120
|
+
- - "<"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 3.0.0
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: webmock
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: 1.19.0
|
130
|
+
- - "<"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 2.0.0
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: 1.19.0
|
140
|
+
- - "<"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 2.0.0
|
41
143
|
description:
|
42
144
|
email:
|
43
145
|
executables: []
|
@@ -45,13 +147,32 @@ extensions: []
|
|
45
147
|
extra_rdoc_files: []
|
46
148
|
files:
|
47
149
|
- ".gitignore"
|
150
|
+
- ".rspec"
|
151
|
+
- ".travis.yml"
|
48
152
|
- Gemfile
|
49
153
|
- LICENSE.txt
|
50
154
|
- README.md
|
51
155
|
- Rakefile
|
52
156
|
- lib/skala.rb
|
157
|
+
- lib/skala/adapter.rb
|
158
|
+
- lib/skala/adapter/operation.rb
|
159
|
+
- lib/skala/i18n.rb
|
160
|
+
- lib/skala/i18n/deep_merger.rb
|
161
|
+
- lib/skala/transformation.rb
|
162
|
+
- lib/skala/transformation/step.rb
|
53
163
|
- lib/skala/version.rb
|
54
164
|
- skala.gemspec
|
165
|
+
- spec/assets/locales/de.yml
|
166
|
+
- spec/assets/locales/en.yml
|
167
|
+
- spec/assets/transformation/some_class.rb
|
168
|
+
- spec/skala/adapter/operation_spec.rb
|
169
|
+
- spec/skala/adapter_spec.rb
|
170
|
+
- spec/skala/i18n/deep_merger_spec.rb
|
171
|
+
- spec/skala/i18n_spec.rb
|
172
|
+
- spec/skala/transformation/step_spec.rb
|
173
|
+
- spec/skala/transformation_spec.rb
|
174
|
+
- spec/skala_spec.rb
|
175
|
+
- spec/spec_helper.rb
|
55
176
|
homepage: https://github.com/ubpb/skala
|
56
177
|
licenses:
|
57
178
|
- MIT
|
@@ -72,9 +193,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
193
|
version: '0'
|
73
194
|
requirements: []
|
74
195
|
rubyforge_project:
|
75
|
-
rubygems_version: 2.4.
|
196
|
+
rubygems_version: 2.4.6
|
76
197
|
signing_key:
|
77
198
|
specification_version: 4
|
78
199
|
summary: Unified adapter framework for search engine and ils adapters.
|
79
|
-
test_files:
|
80
|
-
|
200
|
+
test_files:
|
201
|
+
- spec/assets/locales/de.yml
|
202
|
+
- spec/assets/locales/en.yml
|
203
|
+
- spec/assets/transformation/some_class.rb
|
204
|
+
- spec/skala/adapter/operation_spec.rb
|
205
|
+
- spec/skala/adapter_spec.rb
|
206
|
+
- spec/skala/i18n/deep_merger_spec.rb
|
207
|
+
- spec/skala/i18n_spec.rb
|
208
|
+
- spec/skala/transformation/step_spec.rb
|
209
|
+
- spec/skala/transformation_spec.rb
|
210
|
+
- spec/skala_spec.rb
|
211
|
+
- spec/spec_helper.rb
|