# encoding: UTF-8 # Copyright 2012 Twitter, Inc # http://www.apache.org/licenses/LICENSE-2.0 require 'spec_helper' describe TwitterCldr::Formatters::PluralFormatter do describe '#initialize' do it 'fetches locale from options hash' do expect(described_class.new(:ru).locale).to eq(:ru) end it "uses current locale if it's not passed in options hash" do expect(described_class.new.locale).to eq(TwitterCldr.locale) end end describe '#format' do subject { described_class.new } before(:each) do allow(subject).to receive(:pluralization_rule) { |n| n == 1 ? :one : :other } end let(:horses) { { one: 'is 1 horse', other: 'are %{horses_count} horses' } } let(:horses_string) { '%<{ "horses_count": {"one": "is 1 horse", "other": "are %{horses_count} horses"} }>' } let(:simple_horses) { { one: '1 horse', other: '%{horses_count} horses' } } let(:simple_horses_string) { '%<{ "horses_count": {"one": "1 horse", "other": "%{horses_count} horses"} }>' } let(:to_be) { { one: 'is', other: 'are' } } let(:yaks) { { one: 'is 1 yak', other: 'are %{yaks_count} yaks' } } context 'when there is nothing to pluralize' do it "doesn't change the string if no interpolation found" do string = 'no interpolation here' expect(subject.format(string, {})).to eq(string) end context 'with regular pluralization' do it "doesn't change the string if a number is not provided" do string = 'there %{horses_count:horses}' expect(subject.format(string, horses: horses)).to eq(string) end it "doesn't change the string if a patterns hash is not provided" do string = 'there %{horses_count:horses}' expect(subject.format(string, horses_count: 1)).to eq(string) end it "doesn't change the string if required pattern is not provided" do string = 'there %{horses_count:horses}' expect(subject.format(string, horses_count: 2, horses: { one: 'is 1 horse' })).to eq(string) end end context 'with inline pluralization' do it "doesn't change the string if a number is not provided" do string = "there #{horses_string}" expect(subject.format(string, {})).to eq(string) end it "doesn't change the string if required pattern is not provided" do string = 'there %<{ "horses_count": {"one": "is 1 horse"} }>' expect(subject.format(string, horses_count: 2)).to eq(string) end end context 'with mixed pluralization' do it "doesn't change the string if a number is not provided" do string = "there #{horses_string} %{horses_count:horses}" expect(subject.format(string, horses: horses)).to eq(string) end it "doesn't change the string if required pattern is not provided" do string = 'there %<{ "horses_count": {"one": "is 1 horse"} }> %{horses_count:horses}' expect(subject.format(string, horses_count: 2, horses: { one: 'is 1 horse' })).to eq(string) end end end context 'when something should be pluralized' do context 'with regular pluralization' do it 'pluralizes with a simple replacement' do expect(subject.format( 'there %{horses_count:horses}', horses_count: 1, horses: horses )).to eq('there is 1 horse') end it 'pluralizes when there are named interpolation patterns in the string' do expect(subject.format( '%{there} %{horses_count:horses}', horses_count: 1, horses: horses )).to eq('%{there} is 1 horse') end it 'supports multiple patterns sets for the same number' do expect(subject.format( 'there %{horses_count:to_be} %{horses_count:horses}', horses_count: 1, horses: simple_horses, to_be: to_be )).to eq('there is 1 horse') end it 'pluralizes multiple entries' do expect(subject.format( 'there %{yaks_count:yaks} and %{horses_count:horses}', yaks_count: 1, yaks: yaks, horses_count: 2, horses: simple_horses )).to eq('there is 1 yak and 2 horses') end it 'substitutes the number for a placeholder in the pattern' do expect(subject.format( 'there %{horses_count:horses}', horses_count: 3, horses: horses )).to eq('there are 3 horses') end it 'substitutes the number for multiple placeholders in the pattern' do expect(subject.format( 'there are %{horses_count:horses}', horses_count: 3, horses: { other: '%{horses_count}, seriously %{horses_count}, horses' } )).to eq('there are 3, seriously 3, horses') end it 'throws an exception if pluralization patterns is not a hash' do expect do subject.format('there %{horses_count:horses}', horses_count: 1, horses: []) end.to raise_error(ArgumentError, 'expected patterns to be a Hash') end end context 'with inline pluralization' do it 'pluralizes with a simple replacement' do expect(subject.format("there #{horses_string}", horses_count: 1)).to eq('there is 1 horse') end it 'pluralizes when there are named interpolation patterns in the string' do expect(subject.format("%{there} #{horses_string}", horses_count: 1)).to eq('%{there} is 1 horse') end it 'supports multiple patterns sets for the same number' do expect(subject.format( %Q(there %<{ "horses_count": {"one": "is", "other": "are"} }> #{simple_horses_string}), horses_count: 1 )).to eq('there is 1 horse') end it 'pluralizes multiple entries' do expect(subject.format( %Q(there %<{ "yaks_count": {"one": "is 1 yak", "other": "are %{yaks_count} yaks"} }> and #{simple_horses_string}), yaks_count: 1, horses_count: 2 )).to eq('there is 1 yak and 2 horses') end it 'substitutes the number for a placeholder in the pattern' do expect(subject.format( "there #{horses_string}", horses_count: 3, horses: horses )).to eq('there are 3 horses') end it 'substitutes the number for multiple placeholders in the pattern' do expect(subject.format( 'there are %<{ "horses_count": {"other": "%{horses_count}, seriously %{horses_count}, horses"} }>', horses_count: 3 )).to eq('there are 3, seriously 3, horses') end it 'throws an exception if pluralization hash has more than one key' do expect do subject.format('there are %<{ "horses_count": {}, "foo": {} }>', {}) end.to raise_error(ArgumentError, 'expected a Hash with a single key') end end context 'with mixed pluralization' do it 'pluralizes separate groups' do expect(subject.format( "there %{yaks_count:yaks} and #{simple_horses_string}", yaks: yaks, yaks_count: 3, horses_count: 2 )).to eq('there are 3 yaks and 2 horses') end it 'pluralizes similar groups' do expect(subject.format( "there %{horses_count:horses} + #{simple_horses_string}", horses: horses, horses_count: 2 )).to eq('there are 2 horses + 2 horses') end end end end describe '#pluralization_rule' do it 'delegates pluralization rule fetching to Rules.rule_for method' do expect(TwitterCldr::Formatters::Plurals::Rules).to receive(:rule_for).with(42, :ja).and_return('result') expect(described_class.new(:jp).send(:pluralization_rule, 42)).to eq('result') end end end