mova 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.yardopts +1 -0
- data/CONTRIBUTING.md +47 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +22 -0
- data/README.md +102 -0
- data/Rakefile +7 -0
- data/benchmarks/compare/locale_fallbacks.rb +42 -0
- data/benchmarks/compare/long_scope.rb +48 -0
- data/benchmarks/each_vs_or.rb +42 -0
- data/benchmarks/fallbacks_with_local_storage.rb +21 -0
- data/benchmarks/fallbacks_with_remote_storage.rb +24 -0
- data/lib/mova.rb +36 -0
- data/lib/mova/interpolation/sprintf.rb +73 -0
- data/lib/mova/read_strategy/eager.rb +25 -0
- data/lib/mova/read_strategy/lazy.rb +21 -0
- data/lib/mova/scope.rb +94 -0
- data/lib/mova/storage/chain.rb +124 -0
- data/lib/mova/storage/memory.rb +67 -0
- data/lib/mova/storage/readonly.rb +51 -0
- data/lib/mova/translator.rb +183 -0
- data/mova.gemspec +18 -0
- data/test/acceptance_test.rb +22 -0
- data/test/interpolation/sprintf_test.rb +60 -0
- data/test/mova_test.rb +21 -0
- data/test/read_strategy/eager_test.rb +47 -0
- data/test/read_strategy/lazy_test.rb +46 -0
- data/test/scope_test.rb +41 -0
- data/test/storage/chain_test.rb +100 -0
- data/test/storage/memory_test.rb +52 -0
- data/test/storage/readonly_test.rb +36 -0
- data/test/test_helper.rb +47 -0
- data/test/translator/get_test.rb +55 -0
- data/test/translator/initialize_test.rb +23 -0
- data/test/translator/put_test.rb +27 -0
- metadata +121 -0
@@ -0,0 +1,100 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "mova/storage/chain"
|
3
|
+
|
4
|
+
module Mova
|
5
|
+
class ChainTest < Minitest::Test
|
6
|
+
def storage1
|
7
|
+
@storage1 ||= double("Storage 1")
|
8
|
+
end
|
9
|
+
|
10
|
+
def storage2
|
11
|
+
@storage2 ||= double("Storage 2")
|
12
|
+
end
|
13
|
+
|
14
|
+
def chain
|
15
|
+
@chain ||= Storage::Chain.new(storage1, storage2)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_read_from_storage1
|
19
|
+
expect(storage1).to receive(:read).with(:hello).and_return("hello")
|
20
|
+
assert_equal "hello", chain.read(:hello)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_read_from_storage2
|
24
|
+
expect(storage1).to receive(:read).with(:hello).ordered.and_return(nil)
|
25
|
+
expect(storage2).to receive(:read).with(:hello).ordered.and_return("hi")
|
26
|
+
assert_equal "hi", chain.read(:hello)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_read_from_storage2_when_empty_string_is_returned_from_storage2
|
30
|
+
expect(storage1).to receive(:read).with(:hello).ordered.and_return("")
|
31
|
+
expect(storage2).to receive(:read).with(:hello).ordered.and_return("hi")
|
32
|
+
assert_equal "hi", chain.read(:hello)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_read_multi_from_storage1_only
|
36
|
+
expected = {"hello" => "world", "foo" => "bar"}
|
37
|
+
expect(storage1).to receive(:read_multi).with("hello", "foo").and_return(expected)
|
38
|
+
assert_equal expected, chain.read_multi("hello", "foo")
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_read_multi_from_storage2_only
|
42
|
+
expected = {"hello" => "world", "foo" => "bar"}
|
43
|
+
expect(storage1).to receive(:read_multi).with("hello", "foo").and_return({})
|
44
|
+
expect(storage2).to receive(:read_multi).with("hello", "foo").and_return(expected)
|
45
|
+
assert_equal expected, chain.read_multi("hello", "foo")
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_read_multi_from_storage1_and_storage2_with_preserved_key_order
|
49
|
+
expected = {"hello" => "world", "foo" => "bar"}
|
50
|
+
expect(storage1).to receive(:read_multi).with("hello", "foo").and_return("hello" => "world")
|
51
|
+
expect(storage2).to receive(:read_multi).with("hello", "foo").and_return("foo" => "bar")
|
52
|
+
result = chain.read_multi("hello", "foo")
|
53
|
+
assert_equal expected, result
|
54
|
+
assert_equal expected.keys, result.keys
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_read_multi_from_second_storage_has_priority_for_non_empty_values
|
58
|
+
expected = {"hello" => "world"}
|
59
|
+
expect(storage1).to receive(:read_multi).with("hello").and_return("hello" => "")
|
60
|
+
expect(storage2).to receive(:read_multi).with("hello").and_return("hello" => "world")
|
61
|
+
assert_equal expected, chain.read_multi("hello")
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_read_multi_doesnt_return_nils
|
65
|
+
expected = {"hello" => "world"}
|
66
|
+
expect(storage1).to receive(:read_multi).with("hello", "foo").and_return("hello" => "world")
|
67
|
+
expect(storage2).to receive(:read_multi).with("hello", "foo").and_return({})
|
68
|
+
assert_equal expected, chain.read_multi("hello", "foo")
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_write
|
72
|
+
expect(storage1).to receive(:write).with("hello", "world")
|
73
|
+
expect(storage2).to receive(:write).with("hello", "world")
|
74
|
+
chain.write("hello", "world")
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_clear
|
78
|
+
expect(storage1).to receive(:clear)
|
79
|
+
expect(storage2).to receive(:clear)
|
80
|
+
chain.clear
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_exist_for_non_existing_value
|
84
|
+
expect(storage1).to receive(:exist?).with("hello").and_return(false)
|
85
|
+
expect(storage2).to receive(:exist?).with("hello").and_return(false)
|
86
|
+
refute chain.exist?("hello")
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_exist_in_first_storage
|
90
|
+
expect(storage1).to receive(:exist?).with("hello").and_return(true)
|
91
|
+
assert chain.exist?("hello")
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_exist_in_second_storage
|
95
|
+
expect(storage1).to receive(:exist?).with("hello").and_return(false)
|
96
|
+
expect(storage2).to receive(:exist?).with("hello").and_return(true)
|
97
|
+
assert chain.exist?("hello")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "mova/storage/memory"
|
3
|
+
|
4
|
+
module Mova
|
5
|
+
class MemoryTest < Minitest::Test
|
6
|
+
def storage
|
7
|
+
@storage ||= Storage::Memory.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_read_for_non_existing_value
|
11
|
+
assert_nil storage.read("hello")
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_read
|
15
|
+
storage.write("hello", "world")
|
16
|
+
assert_equal "world", storage.read("hello")
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_read_multi
|
20
|
+
storage.write("hello", "world")
|
21
|
+
storage.write("foo", "bar")
|
22
|
+
expected = {"hello" => "world", "foo" => "bar"}
|
23
|
+
assert_equal expected, storage.read_multi("hello", "foo")
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_read_multi_doesnt_return_nils
|
27
|
+
storage.write("hello", "world")
|
28
|
+
expected = {"hello" => "world"}
|
29
|
+
assert_equal expected, storage.read_multi("hello", "foo")
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_exist_for_non_existing_value
|
33
|
+
refute storage.exist?("hello")
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_exist
|
37
|
+
storage.write("hello", "world")
|
38
|
+
assert storage.exist?("hello")
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_exist_for_nil_value
|
42
|
+
storage.write("hello", nil)
|
43
|
+
assert storage.exist?("hello")
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_clear
|
47
|
+
storage.write("hello", "world")
|
48
|
+
storage.clear
|
49
|
+
assert_nil storage.read("hello")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "mova/storage/readonly"
|
3
|
+
|
4
|
+
module Mova
|
5
|
+
class ReadonlyTest < Minitest::Test
|
6
|
+
include Test::Doubles
|
7
|
+
|
8
|
+
def readonly
|
9
|
+
@readonly ||= Storage::Readonly.new(storage)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_read
|
13
|
+
expect(storage).to receive(:read).with("hello").and_return("world")
|
14
|
+
assert_equal "world", readonly.read("hello")
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_read_multi
|
18
|
+
expected = {"hello" => "world"}
|
19
|
+
expect(storage).to receive(:read_multi).with("hello").and_return(expected)
|
20
|
+
assert_equal expected, readonly.read_multi("hello")
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_write
|
24
|
+
assert_nil readonly.write("hello", "world")
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_exist
|
28
|
+
expect(storage).to receive(:exist?).with("hello").and_return(true)
|
29
|
+
assert readonly.exist?("hello")
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_clear
|
33
|
+
assert_nil readonly.clear
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "mova"
|
3
|
+
|
4
|
+
require "minitest"
|
5
|
+
Minitest.autorun
|
6
|
+
|
7
|
+
require "rspec/mocks"
|
8
|
+
|
9
|
+
RSpec::Mocks.configuration.syntax = :expect
|
10
|
+
|
11
|
+
module RSpec::Mocks
|
12
|
+
remove_const :MockExpectationError
|
13
|
+
# treat as Minitest failure, not an exception
|
14
|
+
MockExpectationError = Class.new(Minitest::Assertion)
|
15
|
+
end
|
16
|
+
|
17
|
+
module Mova
|
18
|
+
module Test
|
19
|
+
module Doubles
|
20
|
+
def storage
|
21
|
+
@storage ||= double("Storage")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module RSpecMocksForMinitest
|
26
|
+
include RSpec::Mocks::ExampleMethods
|
27
|
+
|
28
|
+
def before_setup
|
29
|
+
RSpec::Mocks.setup
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def after_teardown
|
34
|
+
begin
|
35
|
+
RSpec::Mocks.verify
|
36
|
+
ensure
|
37
|
+
RSpec::Mocks.teardown
|
38
|
+
end
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Minitest::Test
|
46
|
+
include Mova::Test::RSpecMocksForMinitest
|
47
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
module Mova
|
4
|
+
class TranslatorGetTest < Minitest::Test
|
5
|
+
def translator
|
6
|
+
@translator ||= Translator.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_get
|
10
|
+
expect(translator).to receive(:locales_to_try).with(:en).and_return([:en])
|
11
|
+
expect(translator).to receive(:keys_to_try).with(:hello).and_return([:hello])
|
12
|
+
expect(translator).to receive(:read_first).with([:en], [:hello]).and_return("Hello")
|
13
|
+
assert_equal "Hello", translator.get(:hello, :en)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_get_allows_to_override_locales_to_try
|
17
|
+
expect(translator).to receive(:keys_to_try).with(:hello).and_return([:hello])
|
18
|
+
expect(translator).to receive(:read_first).with([:de, :en], [:hello]).and_return("Hello")
|
19
|
+
assert_equal "Hello", translator.get(:hello, [:de, :en])
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_get_allows_to_override_keys_to_try
|
23
|
+
expect(translator).to receive(:locales_to_try).with(:en).and_return([:en])
|
24
|
+
expect(translator).to receive(:read_first).with([:en], [:hi, :hello]).and_return("Hello")
|
25
|
+
assert_equal "Hello", translator.get([:hi, :hello], :en)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_get_uses_default_when_read_first_returns_nil
|
29
|
+
expect(translator).to receive(:read_first).and_return(nil)
|
30
|
+
expect(translator).to receive(:default).and_return("hi")
|
31
|
+
assert_equal "hi", translator.get(:hello, :en)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_get_passes_to_default_locales_keys_and_its_options
|
35
|
+
expect(translator).to receive(:locales_to_try).with(:en).and_return([:en])
|
36
|
+
expect(translator).to receive(:keys_to_try).with(:hello).and_return([:hello])
|
37
|
+
expect(translator).to receive(:read_first).with([:en], [:hello]).and_return(nil)
|
38
|
+
expect(translator).to receive(:default).with([:en], [:hello], my: "option")
|
39
|
+
translator.get(:hello, :en, my: "option")
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_get_passes_its_options_to_default
|
43
|
+
expect(translator).to receive(:read_first).and_return(nil)
|
44
|
+
expect(translator).to receive(:default).with(instance_of(Array), instance_of(Array), {my: "option"}).and_return("hi")
|
45
|
+
assert_equal "hi", translator.get(:hello, :en, my: "option")
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_get_uses_option_default_first
|
49
|
+
expect(translator).to receive(:locales_to_try).with(:en).and_return([:en])
|
50
|
+
expect(translator).to receive(:keys_to_try).with(:hello).and_return([:hello])
|
51
|
+
expect(translator).to receive(:read_first).with([:en], [:hello]).and_return(nil)
|
52
|
+
assert_equal "hi", translator.get(:hello, :en, default: "hi")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
module Mova
|
4
|
+
class TranslatorInitializeTest < Minitest::Test
|
5
|
+
include Test::Doubles
|
6
|
+
|
7
|
+
def translator
|
8
|
+
@translator ||= Translator.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_assigns_storage
|
12
|
+
translator = Translator.new(storage: storage)
|
13
|
+
assert_equal storage, translator.storage
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_assigns_default_storage
|
17
|
+
assert_respond_to translator.storage, :read
|
18
|
+
assert_respond_to translator.storage, :read_multi
|
19
|
+
assert_respond_to translator.storage, :write
|
20
|
+
assert_respond_to translator.storage, :exist?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
module Mova
|
4
|
+
class TranslatorPutTest < Minitest::Test
|
5
|
+
include Test::Doubles
|
6
|
+
|
7
|
+
def translator
|
8
|
+
@translator ||= Translator.new(storage: storage)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_put_writes_key_if_it_doesnt_exist
|
12
|
+
expect(storage).to receive(:exist?).with("en.hello").and_return(false)
|
13
|
+
expect(storage).to receive(:write).with("en.hello", "world")
|
14
|
+
translator.put(en: {hello: "world"})
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_put_doesnt_write_key_if_it_exists
|
18
|
+
expect(storage).to receive(:exist?).with("en.hello").and_return(true)
|
19
|
+
translator.put(en: {hello: "world"})
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_put_bang_writes_key_if_it_exists
|
23
|
+
expect(storage).to receive(:write).with("en.hello", "world")
|
24
|
+
translator.put!(en: {hello: "world"})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mova
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrii Malyshko
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-21 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: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description: Translation and localization library
|
42
|
+
email:
|
43
|
+
- mail@nashbridges.me
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- ".yardopts"
|
50
|
+
- CONTRIBUTING.md
|
51
|
+
- Gemfile
|
52
|
+
- LICENSE.txt
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- benchmarks/compare/locale_fallbacks.rb
|
56
|
+
- benchmarks/compare/long_scope.rb
|
57
|
+
- benchmarks/each_vs_or.rb
|
58
|
+
- benchmarks/fallbacks_with_local_storage.rb
|
59
|
+
- benchmarks/fallbacks_with_remote_storage.rb
|
60
|
+
- lib/mova.rb
|
61
|
+
- lib/mova/interpolation/sprintf.rb
|
62
|
+
- lib/mova/read_strategy/eager.rb
|
63
|
+
- lib/mova/read_strategy/lazy.rb
|
64
|
+
- lib/mova/scope.rb
|
65
|
+
- lib/mova/storage/chain.rb
|
66
|
+
- lib/mova/storage/memory.rb
|
67
|
+
- lib/mova/storage/readonly.rb
|
68
|
+
- lib/mova/translator.rb
|
69
|
+
- mova.gemspec
|
70
|
+
- test/acceptance_test.rb
|
71
|
+
- test/interpolation/sprintf_test.rb
|
72
|
+
- test/mova_test.rb
|
73
|
+
- test/read_strategy/eager_test.rb
|
74
|
+
- test/read_strategy/lazy_test.rb
|
75
|
+
- test/scope_test.rb
|
76
|
+
- test/storage/chain_test.rb
|
77
|
+
- test/storage/memory_test.rb
|
78
|
+
- test/storage/readonly_test.rb
|
79
|
+
- test/test_helper.rb
|
80
|
+
- test/translator/get_test.rb
|
81
|
+
- test/translator/initialize_test.rb
|
82
|
+
- test/translator/put_test.rb
|
83
|
+
homepage: https://github.com/mova-rb/mova
|
84
|
+
licenses:
|
85
|
+
- MIT
|
86
|
+
metadata: {}
|
87
|
+
post_install_message:
|
88
|
+
rdoc_options: []
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
requirements: []
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 2.2.2
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: Translation and localization library
|
107
|
+
test_files:
|
108
|
+
- test/acceptance_test.rb
|
109
|
+
- test/interpolation/sprintf_test.rb
|
110
|
+
- test/mova_test.rb
|
111
|
+
- test/read_strategy/eager_test.rb
|
112
|
+
- test/read_strategy/lazy_test.rb
|
113
|
+
- test/scope_test.rb
|
114
|
+
- test/storage/chain_test.rb
|
115
|
+
- test/storage/memory_test.rb
|
116
|
+
- test/storage/readonly_test.rb
|
117
|
+
- test/test_helper.rb
|
118
|
+
- test/translator/get_test.rb
|
119
|
+
- test/translator/initialize_test.rb
|
120
|
+
- test/translator/put_test.rb
|
121
|
+
has_rdoc:
|