interpret 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.rspec +1 -0
  2. data/.travis.yml +14 -0
  3. data/README.md +2 -0
  4. data/app/controllers/interpret/base_controller.rb +10 -14
  5. data/app/controllers/interpret/missing_translations_controller.rb +41 -10
  6. data/app/controllers/interpret/search_controller.rb +15 -3
  7. data/app/controllers/interpret/tools_controller.rb +2 -2
  8. data/app/controllers/interpret/translations_controller.rb +15 -12
  9. data/app/models/interpret/ability.rb +9 -0
  10. data/app/models/interpret/translation.rb +38 -3
  11. data/app/views/interpret/missing_translations/blank.html.erb +35 -0
  12. data/app/views/interpret/missing_translations/index.html.erb +25 -14
  13. data/app/views/interpret/missing_translations/stale.html.erb +43 -0
  14. data/app/views/interpret/missing_translations/unused.html.erb +27 -0
  15. data/app/views/interpret/tools/index.html.erb +15 -25
  16. data/app/views/interpret/translations/_listing.html.erb +3 -15
  17. data/app/views/interpret/translations/index.html.erb +3 -0
  18. data/app/views/layouts/interpret.html.erb +26 -6
  19. data/config/environment.rb +0 -0
  20. data/config/routes.rb +4 -1
  21. data/interpret.gemspec +4 -1
  22. data/lib/generators/interpret/templates/migration.rb +1 -1
  23. data/lib/interpret.rb +23 -2
  24. data/lib/interpret/controller_filter.rb +0 -10
  25. data/lib/interpret/helpers.rb +2 -2
  26. data/lib/interpret/version.rb +1 -1
  27. data/public/javascripts/interpret.js +0 -3
  28. data/public/stylesheets/interpret_style.css +0 -6
  29. data/spec/integration/missing_translations_spec.rb +61 -0
  30. data/spec/integration/search_spec.rb +88 -0
  31. data/spec/integration/stale_translations_spec.rb +28 -0
  32. data/spec/integration/tools_spec.rb +86 -0
  33. data/spec/integration/translations_spec.rb +26 -0
  34. data/spec/models/translation_spec.rb +58 -25
  35. data/spec/observers/expiration_observer_spec.rb +2 -0
  36. data/spec/spec_helper.rb +3 -15
  37. data/spec/support/selenium_db_hack.rb +19 -0
  38. data/spec/support/utils.rb +89 -0
  39. data/test_app/Gemfile +1 -1
  40. data/test_app/app/controllers/application_controller.rb +2 -4
  41. data/test_app/app/models/interpret_ability.rb +7 -0
  42. data/test_app/app/models/user.rb +0 -3
  43. data/test_app/app/views/layouts/application.html.erb +4 -7
  44. data/test_app/config/initializers/interpret.rb +2 -2
  45. data/test_app/config/initializers/rack_patch.rb +13 -0
  46. data/test_app/config/locales/es.yml +1 -1
  47. data/test_app/db/migrate/20110219173536_create_users.rb +0 -2
  48. data/test_app/db/migrate/{20110219143622_interpret_create_translations.rb → 20111021100344_interpret_create_translations.rb} +1 -1
  49. data/test_app/db/schema.rb +2 -3
  50. data/test_app/db/seeds.rb +1 -1
  51. data/test_app/public/javascripts/interpret.js +0 -3
  52. data/test_app/public/stylesheets/interpret_style.css +0 -6
  53. metadata +122 -119
  54. data/spec/database_helpers.rb +0 -15
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe "Stale translations" do
5
+ before(:all) { User.create! }
6
+ before { load_integration_data }
7
+
8
+ it "should show me nothing when I'm in english language" do
9
+ visit interpret_stale_translations_path(:en)
10
+ page.should have_content("There can't be stale translations for the main language")
11
+ end
12
+
13
+ it "should show me the recently modified translations in english", :js => true do
14
+ visit interpret_root_path(:en)
15
+ change_translation("table#results tbody tr:first", "New comments text")
16
+
17
+ visit interpret_stale_translations_path(:es)
18
+ page.all("table#stale_translations tbody tr").size.should == 1
19
+ end
20
+
21
+ it "should not show anything if I update a 'es' translation", :js => true do
22
+ visit interpret_root_path(:es)
23
+ change_translation("table#results tbody tr:first", "New comments text")
24
+
25
+ visit interpret_stale_translations_path(:es)
26
+ page.all("table#stale_translations tbody tr").size.should == 0
27
+ end
28
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe "Tools" do
5
+ before(:all) { User.create! }
6
+ before { load_integration_data }
7
+
8
+ describe "Download" do
9
+ it "should be able to download a .yml file for the current language" do
10
+ visit interpret_tools_path(:en)
11
+ page.should have_button("Download")
12
+
13
+ page.click_button "Download"
14
+ page.response_headers["Content-Type"].should == "text/plain"
15
+ end
16
+
17
+ it "should get a yaml file for the current language" do
18
+ visit interpret_tools_path(:en)
19
+ page.should have_button("Download")
20
+
21
+ page.click_button "Download"
22
+ hash = YAML.load(page.source)
23
+ hash.first.first.should == "en"
24
+ end
25
+
26
+ it "should get a yaml file with all the correct translations" do
27
+ visit interpret_tools_path(:en)
28
+ page.should have_button("Download")
29
+
30
+ page.click_button "Download"
31
+ hash = YAML.load(page.source)
32
+ source_hash = YAML.load(en_yml)
33
+
34
+ hash.sort.should == source_hash.sort
35
+ end
36
+ end
37
+
38
+ describe "Import" do
39
+ it "should be able to import a file" do
40
+ visit interpret_tools_path(:en)
41
+ path = create_tmp_file("""
42
+ en:
43
+ someky: somevalue
44
+ """)
45
+ page.attach_file("file", path)
46
+ page.click_button "Upload"
47
+ page.should have_content("Import successfully done.")
48
+ end
49
+
50
+ it "should not allow to be used with another language" do
51
+ path = create_tmp_file("""
52
+ it:
53
+ someky: somevalue
54
+ """)
55
+ visit interpret_tools_path(:en)
56
+ page.attach_file("file", path)
57
+ page.click_button "Upload"
58
+ page.should have_content("the language doesn't match")
59
+ end
60
+
61
+ it "should update existing translations" do
62
+ path = create_tmp_file(import_en_yml)
63
+ visit interpret_tools_path(:en)
64
+
65
+ page.attach_file("file", path)
66
+ page.click_button "Upload"
67
+
68
+ visit interpret_root_path(:en)
69
+ within("table#results tbody tr:nth-child(4)") do
70
+ page.should have_content("A new printer phrase")
71
+ end
72
+ end
73
+
74
+ it "should create non existant translations" do
75
+ path = create_tmp_file(import_en_yml)
76
+ visit interpret_tools_path(:en)
77
+
78
+ page.attach_file("file", path)
79
+ page.click_button "Upload"
80
+
81
+ visit interpret_root_path(:en)
82
+ page.should have_content("new_stuff")
83
+ page.should have_content("Something brand new")
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe "Translations" do
5
+ before(:all) { User.create! }
6
+ before { load_integration_data }
7
+
8
+ it "should let me edit a translation", :js => true do
9
+ visit interpret_root_path(:en)
10
+
11
+ # We need this to identify the translation we want to change
12
+ bip_id = ""
13
+ within("table#results tbody tr:first") do
14
+ bip_id = page.all("span.best_in_place").first[:id]
15
+ end
16
+ bip_id = bip_id.scan(/translation_\d+/).first
17
+
18
+ bip_area bip_id, :value, "New value"
19
+
20
+
21
+ visit interpret_root_path(:en)
22
+ within("table#results tbody tr:first") do
23
+ page.should have_content("New value")
24
+ end
25
+ end
26
+ end
@@ -38,6 +38,16 @@ es:
38
38
  """
39
39
  }
40
40
 
41
+ let(:es_2_yml) {"""
42
+ es:
43
+ p1: Hola mundo!
44
+ """}
45
+
46
+ let(:pt_2_yml) {"""
47
+ pt:
48
+ p1: Olá mundo
49
+ """}
50
+
41
51
  let(:new_en_yml) {"""
42
52
  en:
43
53
  p1: Hello modified world! This new translation should not be copied into database
@@ -80,27 +90,6 @@ es:
80
90
  """
81
91
  }
82
92
 
83
- # Convert a locale file into database translations
84
- def file2db(string_file)
85
- def parse_hash(dict, locale, prefix = "")
86
- res = []
87
- dict.keys.each do |x|
88
- if dict[x].kind_of?(Hash)
89
- res += parse_hash(dict[x], locale, "#{prefix}#{x}.")
90
- else
91
- res << Interpret::Translation.create!(:locale => locale, :key => "#{prefix}#{x}", :value => dict[x])
92
- end
93
- end
94
- res
95
- end
96
-
97
- hash = YAML.load string_file
98
- lang = hash.keys.first
99
- Interpret::Translation.transaction do
100
- parse_hash(hash.first[1], lang).map{|x| x.save!}
101
- end
102
- end
103
-
104
93
  before do
105
94
  Interpret::Translation.delete_all
106
95
  I18n.stub!(:default_locale).and_return('en')
@@ -235,16 +224,17 @@ es:
235
224
  trans.value.should == "Hello modified world! This new translation should not be copied into database"
236
225
  end
237
226
 
238
- it "should not create new keys" do
227
+ it "should create new keys" do
239
228
  Interpret::Translation.delete_all
240
229
  file2db(en_yml)
241
- howm_before = Interpret::Translation.locale('en').count
230
+ Interpret::Translation.locale('en').count
242
231
 
243
232
  @file.stub!(:content_type).and_return("text/plain")
244
233
  Interpret::Translation.import(@file)
245
234
 
246
- howm_after = Interpret::Translation.locale('en').count
247
- howm_before.should == howm_after
235
+ howm = Interpret::Translation.locale('en').count
236
+ # It should create 2 new translations, from 8 to 10
237
+ howm.should == 10
248
238
  end
249
239
 
250
240
  it "should not touch translations not present in the file" do
@@ -269,4 +259,47 @@ es:
269
259
  Interpret::Translation.export(es_trans).should == YAML.load(es_yml)
270
260
  end
271
261
  end
262
+
263
+ describe "set stale" do
264
+ it "should mark sibling translations as stale after editing the one of the app's default_language" do
265
+ Interpret::Translation.delete_all
266
+ file2db(en_yml)
267
+ file2db(es_2_yml)
268
+ file2db(pt_2_yml)
269
+
270
+ tr = Interpret::Translation.locale("en").find_by_key("p1")
271
+ tr.value = "New value"
272
+ tr.save!
273
+
274
+ Interpret::Translation.locale("es").find_by_key("p1").stale?.should be_true
275
+ Interpret::Translation.locale("pt").find_by_key("p1").stale?.should be_true
276
+ end
277
+
278
+ it "should not mark as stale the translation that you're editing when it's in the app's default_language" do
279
+ Interpret::Translation.delete_all
280
+ file2db(en_yml)
281
+ file2db(es_2_yml)
282
+
283
+ tr = Interpret::Translation.locale("en").find_by_key("p1")
284
+ tr.value = "New value"
285
+ tr.save!
286
+
287
+ tr.stale?.should be_false
288
+ end
289
+
290
+ it "should not mark sibling translations as stale after editing some that is not in the app's default_language" do
291
+ Interpret::Translation.delete_all
292
+ file2db(en_yml)
293
+ file2db(es_2_yml)
294
+ file2db(pt_2_yml)
295
+
296
+ tr = Interpret::Translation.locale("es").find_by_key("p1")
297
+ tr.value = "New value"
298
+ tr.save!
299
+
300
+ Interpret::Translation.locale("en").find_by_key("p1").stale?.should be_false
301
+ Interpret::Translation.locale("es").find_by_key("p1").stale?.should be_false
302
+ Interpret::Translation.locale("pt").find_by_key("p1").stale?.should be_false
303
+ end
304
+ end
272
305
  end
@@ -10,8 +10,10 @@ describe Interpret::ExpirationObserver do
10
10
  it "should call run_expiration on observer" do
11
11
  backend = mock("A backend")
12
12
  backend.should_receive(:"reload!").once
13
+ old = Interpret.backend
13
14
  Interpret.backend = backend
14
15
  Interpret::Translation.create! :locale => "en", :key => "en.hello", :value => "Hello world"
16
+ Interpret.backend = old
15
17
  end
16
18
  end
17
19
 
data/spec/spec_helper.rb CHANGED
@@ -2,21 +2,8 @@
2
2
  ENV["RAILS_ENV"] = "test"
3
3
 
4
4
  require File.expand_path('../../test_app/config/environment', __FILE__)
5
- require "rails/test_help"
6
5
  require "rspec/rails"
7
- require "database_helpers"
8
-
9
- ActionMailer::Base.delivery_method = :test
10
- ActionMailer::Base.perform_deliveries = true
11
- ActionMailer::Base.default_url_options[:host] = "test.com"
12
-
13
- Rails.backtrace_cleaner.remove_silencers!
14
-
15
- include DatabaseHelpers
16
- # Run any available migration
17
- puts 'Setting up database...'
18
- drop_all_tables
19
- migrate_database
6
+ require 'yaml'
20
7
 
21
8
  # Load support files
22
9
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each{|f| require f}
@@ -27,7 +14,8 @@ RSpec.configure do |config|
27
14
  require 'rspec/expectations'
28
15
 
29
16
  config.include RSpec::Matchers
30
- config.include DatabaseHelpers
17
+ config.include BestInPlace::TestHelpers
18
+ config.use_transactional_fixtures = true
31
19
 
32
20
  # == Mock Framework
33
21
  config.mock_with :rspec
@@ -0,0 +1,19 @@
1
+ # Avoids using the database_cleaner gem and allow us to have faster
2
+ # integration specs with selenium. See https://github.com/jnicklas/capybara at
3
+ # transactional fixtures section.
4
+
5
+
6
+ class ActiveRecord::Base
7
+ mattr_accessor :shared_connection
8
+ @@shared_connection = nil
9
+
10
+ def self.connection
11
+ @@shared_connection || retrieve_connection
12
+ end
13
+ end
14
+
15
+ # Forces all threads to share the same connection. This works on
16
+ # Capybara because it starts the web server in a thread.
17
+ ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
18
+
19
+
@@ -0,0 +1,89 @@
1
+ # encoding: utf-8
2
+ # Convert a locale file into database translations
3
+ def file2db(string_file)
4
+ def parse_hash(dict, locale, prefix = "")
5
+ res = []
6
+ dict.keys.each do |x|
7
+ if dict[x].kind_of?(Hash)
8
+ res += parse_hash(dict[x], locale, "#{prefix}#{x}.")
9
+ else
10
+ res << Interpret::Translation.create!(:locale => locale, :key => "#{prefix}#{x}", :value => dict[x])
11
+ end
12
+ end
13
+ res
14
+ end
15
+
16
+ hash = YAML.load string_file
17
+ lang = hash.keys.first
18
+ parse_hash(hash.first[1], lang).map{|x| x.save!}
19
+ end
20
+
21
+ def en_yml
22
+ """
23
+ en:
24
+ printer: Printer Friendly
25
+ comments: Comments
26
+ read_more: Read more
27
+ phrase: This is a rare phrase with non ascii chars
28
+
29
+ section1:
30
+ printer: Another printer
31
+
32
+ blacklist:
33
+ black_p1: A forbidden phrase
34
+
35
+ missings:
36
+ p1: Missing one
37
+ p2: Missing two
38
+ black: A one blacklisted
39
+ """
40
+ end
41
+
42
+ def import_en_yml
43
+ """
44
+ en:
45
+ printer: A new printer phrase
46
+ new_stuff: Something brand new
47
+
48
+ section1:
49
+ printer: Other change
50
+ """
51
+ end
52
+
53
+ def load_integration_data
54
+ #en_yml =
55
+ es_yml = """
56
+ es:
57
+ printer: Para imprimir
58
+ comments: Comentarios
59
+ read_more: Leer mas
60
+ phrase: Esta és una extraña frase con carácteres no ascii
61
+
62
+ section1:
63
+ printer: Otra impresora
64
+
65
+ blacklist:
66
+ black_p1: Una frase prohibida
67
+ """
68
+
69
+ file2db en_yml
70
+ file2db es_yml
71
+ end
72
+
73
+ def change_translation(scope, new_value)
74
+ bip_id = ""
75
+ within(scope) do
76
+ bip_id = page.all("span.best_in_place").first[:id]
77
+ end
78
+ bip_id = bip_id.scan(/translation_\d+/).first
79
+
80
+ bip_area bip_id, :value, new_value
81
+ end
82
+
83
+ def create_tmp_file(content)
84
+ file = Tempfile.new("interpret_test")
85
+ file.write(content)
86
+ path = file.path
87
+ file.close
88
+ path
89
+ end
data/test_app/Gemfile CHANGED
@@ -6,7 +6,7 @@ gem 'capistrano'
6
6
 
7
7
  group :development, :test do
8
8
  gem 'sqlite3-ruby', :require => 'sqlite3'
9
- gem 'ruby-debug'
10
9
  end
11
10
 
12
11
  gem 'interpret', :path => ".."
12
+ gem 'mysql2', "~> 0.2.7"
@@ -5,13 +5,11 @@ class ApplicationController < ActionController::Base
5
5
  before_filter :set_locale
6
6
 
7
7
  def current_user
8
- session[:user_id] ? User.find(session[:user_id]) : User.where(:admin => true).first
8
+ session[:user_id] ? User.find(session[:user_id]) : User.first
9
9
  end
10
10
 
11
11
  def set_current_user
12
- if params[:admin]
13
- session[:user_id] = params[:admin] == "true" ? User.where(:admin => true).first : User.where(:admin => false).first
14
- end
12
+ session[:user_id] = User.first
15
13
  end
16
14
 
17
15
  def toggle_edition_mode
@@ -0,0 +1,7 @@
1
+ class InterpretAbility
2
+ include CanCan::Ability
3
+
4
+ def initialize(user)
5
+ can :manage, :all
6
+ end
7
+ end