Skip to content

Commit

Permalink
fixed rules and translation key specs
Browse files Browse the repository at this point in the history
  • Loading branch information
berk committed Mar 30, 2012
1 parent 3723965 commit e8c4e65
Show file tree
Hide file tree
Showing 7 changed files with 414 additions and 41 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Thumbs.db
.tmp*
tmp/
local/tr8n_server/db/*.sqlite3
local/tr8n_server/db/test.sqlite3
local/tr8n_server/log/*.log
local/tr8n_server/tmp/
local/tr8n_server/.sass-cache/
local/tr8n_server/.sass-cache/
24 changes: 18 additions & 6 deletions app/models/tr8n/language.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,33 @@ class Tr8n::Language < ActiveRecord::Base
has_many :translation_key_locks, :class_name => 'Tr8n::TranslationKeyLock', :dependent => :destroy
has_many :language_metrics, :class_name => 'Tr8n::LanguageMetric'

def self.find_or_create(lcl, english_name)
find_by_locale(lcl) || create(:locale => lcl, :english_name => english_name)
def self.cache_key(locale)
"language_#{locale}"
end

def cache_key
self.class.cache_key(locale)
end

def self.for(locale)
return nil if locale.nil?
Tr8n::Cache.fetch("language_#{locale}") do
Tr8n::Cache.fetch(cache_key(locale)) do
find_by_locale(locale)
end
end

def self.find_or_create(lcl, english_name)
find_by_locale(lcl) || create(:locale => lcl, :english_name => english_name)
end

def rules
Tr8n::Cache.fetch("language_rules_#{id}") do
Tr8n::Cache.fetch("language_rules_#{locale}") do
language_rules
end
end

def cases
Tr8n::Cache.fetch("language_cases_#{id}") do
Tr8n::Cache.fetch("language_cases_#{locale}") do
language_cases
end
end
Expand All @@ -64,6 +72,7 @@ def reset!
reset_language_cases!
end

# reloads rules for the language from the yml file
def reset_language_rules!
rules.delete_all
Tr8n::Config.language_rule_classes.each do |rule_class|
Expand All @@ -73,6 +82,7 @@ def reset_language_rules!
end
end

# reloads language cases for the language from the yml file
def reset_language_cases!
cases.delete_all
Tr8n::Config.default_language_cases_for(locale).each do |lcase|
Expand Down Expand Up @@ -308,7 +318,9 @@ def translations_changed!
end

def update_cache
Tr8n::Cache.delete("language_#{locale}")
Tr8n::Cache.delete(cache_key)
Tr8n::Cache.delete("language_rules_#{locale}")
Tr8n::Cache.delete("language_cases_#{locale}")
Tr8n::Cache.delete("featured_languages")
Tr8n::Cache.delete("enabled_languages")
end
Expand Down
61 changes: 34 additions & 27 deletions app/models/tr8n/numeric_rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,13 @@ def self.number_token_value(token)
token.send(Tr8n::Config.rules_engine[:numeric_rule][:object_method])
end

def number_token_value(token)
self.class.number_token_value(token)
def self.sanitize_values(values)
return [] unless values
values.split(",").collect{|val| val.strip}
end

def self.humanize_values(values)
sanitize_values(values).join(", ")
end

# FORM: [object, singular, plural]
Expand Down Expand Up @@ -89,30 +94,7 @@ def self.default_transform(*args)
args[0].pluralize
end

def evaluate(token)
token_value = number_token_value(token)
return false unless token_value

result1 = evaluate_partial_rule(token_value.to_s, definition[:part1].to_sym, sanitize_values(definition[:value1]))
return result1 unless definition[:multipart].to_s == "true"

result2 = evaluate_partial_rule(token_value.to_s, definition[:part2].to_sym, sanitize_values(definition[:value2]))
return (result1 or result2) if definition[:operator] == "or"
return (result1 and result2)

false
end

def sanitize_values(values)
return [] unless values
values.split(",").collect{|val| val.strip}
end

def humanize_values(values)
sanitize_values(values).join(", ")
end

def evaluate_partial_rule(token_value, name, values)
def self.evaluate_rule_fragment(token_value, name, values)
if name == :is
return true if values.include?(token_value)
return false
Expand Down Expand Up @@ -140,6 +122,32 @@ def evaluate_partial_rule(token_value, name, values)
false
end

def evaluate(token)
token_value = number_token_value(token)
return false unless token_value

result1 = self.class.evaluate_rule_fragment(token_value.to_s, definition[:part1].to_sym, sanitize_values(definition[:value1]))
return result1 unless definition[:multipart].to_s == "true"

result2 = self.class.evaluate_rule_fragment(token_value.to_s, definition[:part2].to_sym, sanitize_values(definition[:value2]))
return (result1 or result2) if definition[:operator] == "or"
return (result1 and result2)

false
end

def number_token_value(token)
self.class.number_token_value(token)
end

def sanitize_values(values)
self.class.sanitize_values(values)
end

def humanize_values(values)
self.class.humanize_values(values)
end

def to_hash
{ :type => self.class.dependency,
:multipart => definition[:multipart], :operator => definition[:operator],
Expand All @@ -148,7 +156,6 @@ def to_hash
}
end


# used to describe a context of a given translation
def description
rule_desc = describe_partial_rule(definition[:part1].to_sym, definition[:value1])
Expand Down
138 changes: 137 additions & 1 deletion spec/models/tr8n/gender_rule_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,141 @@
require File.expand_path('../../spec_helper', File.dirname(__FILE__))

describe Tr8n::GenderRule do

before :all do
@lang = Tr8n::Language.create(:locale => "elb", :english_name => "Elbonian")
end

after :all do
@lang.destroy
end

describe 'class methods' do
it 'should respec configuration settings' do
Tr8n::Config.stub!(:rules_engine).and_return({
:gender_rule => {
token_suffixes: ["user", "actor", "target"],
object_method: "gender",
method_values: {
female: "f",
male: "m",
neutral: "n",
unknown: "u"
}
}
})

Tr8n::GenderRule.dependency.should eq("gender")
Tr8n::GenderRule.suffixes.should eq(["user", "actor", "target"])

Tr8n::GenderRule.gender_object_value_for(:female).should eq("f")
Tr8n::GenderRule.gender_object_value_for(:male).should eq("m")
Tr8n::GenderRule.gender_object_value_for(:neutral).should eq("n")
Tr8n::GenderRule.gender_object_value_for(:unknown).should eq("u")

obj = mock("object_with_gender")
obj.should_receive(:gender).and_return("m")
Tr8n::GenderRule.gender_token_value(obj).should eq("m")
end

describe 'default transform without token value' do
it 'should always use a musculine form' do
Tr8n::GenderRule.default_transform("he").should eq("he")
Tr8n::GenderRule.default_transform("he", "she").should eq("he")
Tr8n::GenderRule.default_transform("his", "her").should eq("his")
end
end

describe 'transform with a token value' do
it 'should return the form based on the token value' do
male = mock("male")
male.stub!(:gender).and_return("male")
female = mock("male")
female.stub!(:gender).and_return("female")
unknwon = mock("unknwon")
unknwon.stub!(:gender).and_return("unknwon")

Tr8n::GenderRule.transform(male, "registered on").should eq("registered on")
Tr8n::GenderRule.transform(male, "he", "she").should eq("he")
Tr8n::GenderRule.transform(male, "his", "her").should eq("his")
Tr8n::GenderRule.transform(male, "he", "she", "he/she").should eq("he")

Tr8n::GenderRule.transform(female, "registered on").should eq("registered on")
Tr8n::GenderRule.transform(female, "he", "she").should eq("she")
Tr8n::GenderRule.transform(female, "his", "her").should eq("her")
Tr8n::GenderRule.transform(female, "he", "she", "he/she").should eq("she")

Tr8n::GenderRule.transform(unknwon, "registered on").should eq("registered on")
Tr8n::GenderRule.transform(unknwon, "he", "she").should eq("he/she")
Tr8n::GenderRule.transform(unknwon, "his", "her").should eq("his/her")
Tr8n::GenderRule.transform(unknwon, "he", "she", "he/she").should eq("he/she")
end
end
end

describe 'instance methods' do
describe 'evaluate rule' do
it 'should return results based on gender' do
male = mock("male")
male.stub!(:gender).and_return("male")
female = mock("male")
female.stub!(:gender).and_return("female")
unknwon = mock("unknwon")
unknwon.stub!(:gender).and_return("unknwon")

definition = {operator: "is", value: "male"}
rule = Tr8n::GenderRule.create(:language => @lang, :definition => definition)
rule.evaluate(male).should be_true
rule.evaluate(female).should be_false
rule.evaluate(unknwon).should be_false

definition = {operator: "is_not", value: "male"}
rule = Tr8n::GenderRule.create(:language => @lang, :definition => definition)
rule.evaluate(male).should be_false
rule.evaluate(female).should be_true
rule.evaluate(unknwon).should be_true

definition = {operator: "is", value: "female"}
rule = Tr8n::GenderRule.create(:language => @lang, :definition => definition)
rule.evaluate(male).should be_false
rule.evaluate(female).should be_true
rule.evaluate(unknwon).should be_false

definition = {operator: "is_not", value: "female"}
rule = Tr8n::GenderRule.create(:language => @lang, :definition => definition)
rule.evaluate(male).should be_true
rule.evaluate(female).should be_false
rule.evaluate(unknwon).should be_true
end
end

describe 'hashing a rule' do
it 'should produce a correct hash' do
definition = {operator: "is", value: "male"}
rule = Tr8n::GenderRule.create(:language => @lang, :definition => definition)
rule.to_hash.should eq({:type=>"gender", :operator=>"is", :value=>"male"})
end
end

describe 'describing a rule' do
it 'should produce a correct description' do
definition = {operator: "is", value: "male"}
rule = Tr8n::GenderRule.create(:language => @lang, :definition => definition)
rule.description.should eq("is a male")

definition = {operator: "is", value: "unknown"}
rule = Tr8n::GenderRule.create(:language => @lang, :definition => definition)
rule.description.should eq("has an unknown gender")

definition = {operator: "is_not", value: "female"}
rule = Tr8n::GenderRule.create(:language => @lang, :definition => definition)
rule.description.should eq("is not a female")

definition = {operator: "is_not", value: "unknown"}
rule = Tr8n::GenderRule.create(:language => @lang, :definition => definition)
rule.description.should eq("does not have an unknown gender")
end
end

end

end
9 changes: 9 additions & 0 deletions spec/models/tr8n/language_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
require File.expand_path('../../spec_helper', File.dirname(__FILE__))

describe Tr8n::Language do
describe 'cache key' do
it 'shold use locale' do
lang = Tr8n::Language.find_or_create('test', 'Test Language')
lang.cache_key.should eq("language_test")
end
end

describe 'finding or creating a new language' do
context 'none existing language' do
it 'should not be found' do
Expand Down Expand Up @@ -67,4 +74,6 @@
end
end



end
Loading

0 comments on commit e8c4e65

Please sign in to comment.