Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added simple variable checking when validating translations.

  • Loading branch information...
commit 0b75ce7906aed15e21ce4a49bc0cc5d031cae00c 1 parent 08dc20b
Willem van Bergen authored June 07, 2010 josh committed June 14, 2010
27  app/models/tolk/translation.rb
@@ -8,6 +8,7 @@ class Translation < ActiveRecord::Base
8 8
 
9 9
     serialize :text
10 10
     validates_presence_of :text, :if => proc {|r| r.primary.blank? && !r.explicit_nil }
  11
+    validate :check_matching_variables, :if => proc { |tr| tr.primary_translation.present? }
11 12
 
12 13
     validates_uniqueness_of :phrase_id, :scope => :locale_id
13 14
 
@@ -53,6 +54,23 @@ def value
53 54
       end
54 55
     end
55 56
 
  57
+    def self.detect_variables(search_in)
  58
+      case search_in
  59
+        when String then Set.new(search_in.scan(/\{\{(\w+)\}\}/).flatten)
  60
+        when Array then search_in.inject(Set[]) { |carry, item| carry + detect_variables(item) }
  61
+        when Hash then search_in.values.inject(Set[]) { |carry, item| carry + detect_variables(item) }
  62
+        else Set[]
  63
+      end
  64
+    end
  65
+
  66
+    def variables
  67
+      self.class.detect_variables(text)
  68
+    end
  69
+
  70
+    def variables_match?
  71
+      self.variables == primary_translation.variables
  72
+    end
  73
+
56 74
     private
57 75
 
58 76
     def set_explicit_nil
@@ -89,5 +107,14 @@ def set_previous_text
89 107
       true
90 108
     end
91 109
 
  110
+    def check_matching_variables
  111
+      unless variables_match?
  112
+        if primary_translation.variables.empty?
  113
+          self.errors.add(:text, "The original does not contain variables, so they should not be included.")
  114
+        else
  115
+          self.errors.add(:text, "The translation should contain the variables #{variables.to_a.to_sentence}.")
  116
+        end
  117
+      end
  118
+    end
92 119
   end
93 120
 end
5  test/locales/formats/en.yml
... ...
@@ -1,6 +1,11 @@
1 1
 en:
2 2
   number: 1
3 3
   string: I am just a stupid string :(
  4
+  variables: "String with variables {{hello}} and {{world}}"
  5
+  variables_in_struct:
  6
+    zero: "Without variable"
  7
+    one: "With {{variables}}"
  8
+    other: "With even {{more}} {{variables}}"
4 9
   number_array: [1, 2, 3]
5 10
   string_array: ['sun', 'moon']
6 11
   pluralization:
17  test/unit/format_test.rb
@@ -60,6 +60,23 @@ def test_creating_translations_fails_on_mismatch_with_primary_translation
60 60
     success.save!
61 61
     assert_equal [1, 2], success.text
62 62
   end
  63
+  
  64
+  def test_creating_translations_fails_with_unmatching_variables
  65
+    # Check that variable detection works correctly
  66
+    assert_equal Set['hello', 'world'], ph('variables').translations.primary.variables
  67
+    assert_equal Set['more', 'variables'], ph('variables_in_struct').translations.primary.variables
  68
+
  69
+    # Allow different ordering and multiple occurences of variables
  70
+    assert @spanish.translations.build(:text => '{{world}} y {{hello}} y {{hello}} y {{world}}', :phrase => ph('variables')).valid?
  71
+
  72
+    # Do not allow missing or wrong variables
  73
+    assert_raises(ActiveRecord::RecordInvalid) { @spanish.translations.create!(:text => 'Hola', :phrase => ph('variables')) }
  74
+    assert_raises(ActiveRecord::RecordInvalid) { @spanish.translations.create!(:text => '{{other}} variable', :phrase => ph('variables')) }
  75
+
  76
+    # Do not allow variables if the origin does not contain any
  77
+    assert_equal Set[], ph('string').translations.primary.variables
  78
+    assert_raises(ActiveRecord::RecordInvalid) { @spanish.translations.create!(:text => 'Hola {{mundo}}', :phrase => ph('string')) }
  79
+  end
63 80
 
64 81
   def test_creating_translations_with_nil_values
65 82
     # implicit nil value

0 notes on commit 0b75ce7

Please sign in to comment.
Something went wrong with that request. Please try again.