mayl 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ config/locales
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create use 1.9.3@mayl
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mayl.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Josep M. Bach
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,92 @@
1
+ # mayl - a YAML console
2
+
3
+ Mayl is an anagram of YAML, and also a console to create, edit and maintain
4
+ YAML files in any kind of Ruby projects.
5
+
6
+ ## Installation
7
+
8
+ Install mayl yourself:
9
+
10
+ $ gem install mayl
11
+
12
+ ## Usage
13
+
14
+ Mayl expects your YAML files to be organized like this: one file per locale
15
+ (`en.yml`, `es.yml`, `ca.yml`...) in a directory.
16
+
17
+ When it starts, it needs to know where to find all these YAML files, and it
18
+ looks by default under `./config/locales` but you can always run it like `mayl
19
+ some/other/dir` to override this.
20
+
21
+ $ mayl
22
+ Detected locales: ca, en, es
23
+ >
24
+
25
+ Now we'll set a new key by typing `set KEY` and typing in the translations:
26
+
27
+ > set activerecord.models.post
28
+ ca: Article
29
+ en: Post
30
+ es: Artículo
31
+
32
+ Set activerecord.models.post to Article (ca), Post (en) and Artículo (es)
33
+ >
34
+
35
+ Changes get written to the file immediately. We can consult a key any time,
36
+ and in case we see any error, correct it quickly with `edit LOCALE NEWVALUE`:
37
+
38
+ > get activerecord.models.post
39
+ ca: Article
40
+ en: Post
41
+ es: Artículo
42
+ > edit es Entrada
43
+
44
+ Set activerecord.models.post to Entrada (es)
45
+ >
46
+
47
+ ### Namespaces
48
+
49
+ If you want to work for a while inside a namespace, let's say
50
+ `activerecord.models`, you can do so by `cd`-ing into it, and even `ls` the
51
+ existing keys:
52
+
53
+ > cd activerecord.models
54
+ activerecord.models > get post
55
+ ca: Article
56
+ en: Post
57
+ es: Entrada
58
+ activerecord.models > cd ..
59
+ activerecord > ls
60
+ models attributes
61
+ activerecord > cd ..
62
+ >
63
+
64
+ Cool way to navigate your YAML files huh?
65
+
66
+ ### Other useful commands
67
+
68
+ * `exit`: Exits the console.
69
+
70
+ ## Development
71
+
72
+ To run the tests:
73
+
74
+ $ rake
75
+
76
+ To build the documentation under the `doc` directory:
77
+
78
+ $ rake doc
79
+
80
+ ## Contributing
81
+
82
+ 1. Fork it
83
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
84
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
85
+ 4. Push to the branch (`git push origin my-new-feature`)
86
+ 5. Create new Pull Request
87
+
88
+ ## Who's this
89
+
90
+ This was made by [Josep M. Bach (Txus)](http://txustice.me) under the MIT
91
+ license. I'm [@txustice](http://twitter.com/txustice) on twitter (where you
92
+ should probably follow me!).
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'yard'
5
+ YARD::Config.load_plugin('yard-tomdoc')
6
+ YARD::Rake::YardocTask.new do |t|
7
+ t.files = ['lib/**/*.rb']
8
+ t.options = %w(-r README.md)
9
+ end
10
+
11
+ require 'rake/testtask'
12
+ Rake::TestTask.new do |t|
13
+ t.libs << "test"
14
+ t.test_files = FileList['./test/**/*_test.rb']
15
+ end
16
+
17
+ task :doc => :yard
18
+ task :default => :test
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $: << 'lib'
3
+ require 'mayl'
4
+
5
+ Mayl::Repl.new(ARGV[1]).start
@@ -0,0 +1,12 @@
1
+ require "mayl/version"
2
+ require "mayl/commands"
3
+ require "mayl/locale"
4
+ require "mayl/loader"
5
+ require "mayl/env"
6
+ require "mayl/parser"
7
+ require "mayl/repl"
8
+
9
+ # Public: Mayl is an anagram of YAML, and also a console to create, edit and
10
+ # maintain YAML files in any kind of Ruby projects.
11
+ module Mayl
12
+ end
@@ -0,0 +1,13 @@
1
+ module Mayl
2
+ # Public: The Commands module is a namespace for all the commands that Mayl
3
+ # uses.
4
+ module Commands
5
+ end
6
+ end
7
+
8
+ require 'mayl/commands/set'
9
+ require 'mayl/commands/get'
10
+ require 'mayl/commands/edit'
11
+ require 'mayl/commands/cd'
12
+ require 'mayl/commands/exit'
13
+ require 'mayl/commands/ls'
@@ -0,0 +1,42 @@
1
+ module Mayl
2
+ module Commands
3
+ # Public: The Cd command navigates through YAML namespaces.
4
+ #
5
+ # Example
6
+ #
7
+ # command = Cd.new(env, 'models.bla')
8
+ # command.execute
9
+ #
10
+ class Cd
11
+ # Public: Initializes a new Cd command.
12
+ #
13
+ # env - the global environment
14
+ # path - the path to cd in
15
+ def initialize(env, path)
16
+ @env = env
17
+ @path = path
18
+ end
19
+
20
+ # Public: Adds the path to the namespace.
21
+ #
22
+ # Returns nil.
23
+ def execute
24
+ case @path
25
+ when ".."
26
+ ns = @env.namespace.split('.')
27
+ ns.pop
28
+ @env.namespace = ns.join('.')
29
+ when "."
30
+ @env.namespace = ""
31
+ else
32
+ if @env.namespace.empty?
33
+ @env.namespace = @path
34
+ else
35
+ @env.namespace += '.' << @path
36
+ end
37
+ end
38
+ nil
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,54 @@
1
+ module Mayl
2
+ module Commands
3
+ # Public: The Edit command quickly edits the last value consulted with Get
4
+ # or Set.
5
+ #
6
+ # Example
7
+ #
8
+ # command = Edit.new(env, 'es', 'Artículo')
9
+ # command.execute
10
+ #
11
+ class Edit
12
+ attr_reader :locale, :value
13
+
14
+ # Public: Initializes a new Get command.
15
+ #
16
+ # env - the global environment
17
+ # locale - the locale that we want to edit
18
+ # value - the value to set
19
+ def initialize(env, locale, value)
20
+ @env = env
21
+ @key = @env.last_value
22
+ raise ArgumentError, "You must get or set a key before calling edit" unless @key
23
+ @locale = locale
24
+ @value = value
25
+ end
26
+
27
+ # Public: Executes the command, editing the @key for the given @locale.
28
+ #
29
+ # Returns the key.
30
+ def execute
31
+ locale = locales.detect do |locale|
32
+ locale.name.to_s == @locale.to_s
33
+ end
34
+ locale.set @key, @value
35
+ @key
36
+ end
37
+
38
+ #######
39
+ private
40
+ #######
41
+
42
+ # Public: Returns an Array with the locales of the environment.
43
+ def locales
44
+ @env.locales
45
+ end
46
+
47
+ # Public: Returns the given String key according to the qualified
48
+ # namespace we are in.
49
+ def qualified_key
50
+ [@env.namespace.to_s, @key].reject(&:empty?).compact.join('.')
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,25 @@
1
+ module Mayl
2
+ module Commands
3
+ # Public: The Exit command exits the program.
4
+ #
5
+ # Example
6
+ #
7
+ # command = Exit.new(env)
8
+ # command.execute
9
+ #
10
+ class Exit
11
+ # Public: Initializes a new Exit command.
12
+ #
13
+ # env - the global environment
14
+ def initialize(env)
15
+ end
16
+
17
+ # Public: Exits the program.
18
+ #
19
+ # Returns nothing.
20
+ def execute
21
+ exit(0)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,59 @@
1
+ module Mayl
2
+ module Commands
3
+ # Public: The Get command accepts a key and returns a summary of the
4
+ # values for that key in every locale.
5
+ #
6
+ # Example
7
+ #
8
+ # command = Get.new(env, 'activerecord.models.post')
9
+ # command.execute
10
+ # # Outputs:
11
+ # # ca: Article
12
+ # # es: Artículo
13
+ # # en: Post
14
+ #
15
+ class Get
16
+ attr_reader :key
17
+
18
+ # Public: Initializes a new Get command.
19
+ #
20
+ # env - the global environment
21
+ # key - the String key to get the value of
22
+ def initialize(env, key)
23
+ @env = env
24
+ @key = key
25
+ end
26
+
27
+ # Public: Executes the command, iterating over each locale, asking the
28
+ # value for the key, and printing it out.
29
+ #
30
+ # Returns the key.
31
+ def execute
32
+ locales.each do |locale|
33
+ result = locale.get qualified_key
34
+ if result.is_a? String
35
+ print " #{locale.to_s}: #{result}\n"
36
+ else
37
+ print " #{locale.to_s}: (empty)\n"
38
+ end
39
+ end
40
+ @key
41
+ end
42
+
43
+ #######
44
+ private
45
+ #######
46
+
47
+ # Public: Returns an Array with the locales of the environment.
48
+ def locales
49
+ @env.locales
50
+ end
51
+
52
+ # Public: Returns the given String key according to the qualified
53
+ # namespace we are in.
54
+ def qualified_key
55
+ [@env.namespace.to_s, @key].reject(&:empty?).compact.join('.')
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,40 @@
1
+ module Mayl
2
+ module Commands
3
+ # Public: The Cd command navigates through YAML namespaces.
4
+ #
5
+ # Example
6
+ #
7
+ # command = Ls.new(env)
8
+ # command.execute
9
+ #
10
+ class Ls
11
+ # Public: Initializes a new Cd command.
12
+ #
13
+ # env - the global environment
14
+ def initialize(env)
15
+ @env = env
16
+ end
17
+
18
+ # Public: Adds the path to the namespace.
19
+ #
20
+ # Returns nil.
21
+ def execute
22
+ locales.map { |locale|
23
+ locale.peek(@env.namespace)
24
+ }.flatten.uniq.each do |option|
25
+ print "#{option} "
26
+ end
27
+ nil
28
+ end
29
+
30
+ #######
31
+ private
32
+ #######
33
+
34
+ # Public: Returns an Array with the locales of the environment.
35
+ def locales
36
+ @env.locales
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,54 @@
1
+ module Mayl
2
+ module Commands
3
+ # Public: The Set command accepts a key and asks the user to type in the
4
+ # translations for that key in each of the locales.
5
+ #
6
+ # Example
7
+ #
8
+ # command = Set.new(env, 'activerecord.models.post')
9
+ # command.execute
10
+ # ca: <type something>
11
+ # en: <type something>
12
+ # # Now locales have those values set.
13
+ #
14
+ class Set
15
+ attr_reader :key
16
+
17
+ # Public: Initializes a new Set command.
18
+ #
19
+ # env - the global environment
20
+ # key - the String key to be set
21
+ def initialize(env, key)
22
+ @env = env
23
+ @key = key
24
+ end
25
+
26
+ # Public: Executes the command, iterating over each locale, asking the
27
+ # user for a value, and setting it.
28
+ #
29
+ # Returns the key.
30
+ def execute
31
+ locales.each do |locale|
32
+ print " #{locale.to_s}: "
33
+ locale.set qualified_key, gets.chomp
34
+ end
35
+ @key
36
+ end
37
+
38
+ #######
39
+ private
40
+ #######
41
+
42
+ # Public: Returns an Array with the locales of the environment.
43
+ def locales
44
+ @env.locales
45
+ end
46
+
47
+ # Public: Returns the given String key according to the qualified
48
+ # namespace we are in.
49
+ def qualified_key
50
+ [@env.namespace.to_s, @key].reject(&:empty?).compact.join('.')
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,21 @@
1
+ module Mayl
2
+ # Public: Represents the global state with the loaded locales, and has the
3
+ # ability to save locales to disk.
4
+ class Env
5
+ attr_reader :locales
6
+ attr_accessor :last_value
7
+ attr_accessor :namespace
8
+
9
+ # Public: Initializes a new Env loading the locales from a path.
10
+ def initialize(path)
11
+ @locales = Loader.load(path)
12
+ @last_value = nil
13
+ @namespace = ""
14
+ end
15
+
16
+ # Public: Saves any changes to disk.
17
+ def commit
18
+ @locales.each(&:commit)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ require 'yaml'
2
+
3
+ module Mayl
4
+ # Public: This module is responsible for loading YAML files and converting
5
+ # them to Locale objects.
6
+ #
7
+ # Example
8
+ #
9
+ # Loader.load('config/locales')
10
+ # # => [#<Locale:...>, #<Locale:...>]
11
+ #
12
+ module Loader
13
+ # Public: Maps a set of YAML files in a directory to Locale objects, to
14
+ # work comfortably with them.
15
+ #
16
+ # path - The path under which to scan for YAML files.
17
+ #
18
+ # Returns an Array of Locale objects.
19
+ def self.load(path)
20
+ Dir[File.expand_path(path) << "/*.yml"].map { |filename|
21
+ Locale.new filename, YAML.load(File.read(filename))
22
+ }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,83 @@
1
+ require 'yaml'
2
+
3
+ module Mayl
4
+ # Public: A Locale is the representation of a YAML translation file.
5
+ #
6
+ # Example
7
+ #
8
+ # locale = Locale.new(:ca, {'ca' => {'activerecord' => ... }})
9
+ # locale.set('activerecord.models.comment', 'Comentari')
10
+ # locale.get('activerecord.models.comment')
11
+ # # => 'Comentari
12
+ #
13
+ class Locale
14
+ attr_reader :name
15
+
16
+ # Public: Initializes a new Locale.
17
+ #
18
+ # path - the filename path of the YAML file
19
+ # hash - the Hash outputted by the YAML parser
20
+ def initialize(path, hash)
21
+ @path = path
22
+ @name = path.split('/').last.gsub('.yml','').to_sym
23
+ @data = hash[name.to_s]
24
+ @dirty = false
25
+ end
26
+
27
+ # Public: Sets a key to a given value.
28
+ #
29
+ # key - the String key to be set, fully qualified
30
+ # value - the new value to give to that key
31
+ #
32
+ # Returns nothing.
33
+ def set(key, value)
34
+ ary = key.split('.')
35
+ qualifier = ary[0..-2]
36
+ name = ary.last
37
+
38
+ _data = @data
39
+ qualifier.each do |path|
40
+ _data = _data[path]
41
+ end
42
+ _data[name] = value
43
+
44
+ @dirty = true
45
+ end
46
+
47
+ # Public: Gets the value for a given key.
48
+ #
49
+ # key - the String key to be set, fully qualified
50
+ #
51
+ # Returns the String value.
52
+ def get(key)
53
+ key.split('.').inject(@data) do |acc, name|
54
+ acc[name] ||= {}
55
+ end
56
+ end
57
+
58
+ # Public: Returns an Array of nodes inside a key, or nil if the key
59
+ # represents a leaf.
60
+ def peek(key)
61
+ result = get(key)
62
+ if result.is_a?(Hash)
63
+ result.keys
64
+ end
65
+ end
66
+
67
+ # Public: Saves any changes to disk.
68
+ #
69
+ # Returns nothing.
70
+ def commit
71
+ return false unless @dirty
72
+
73
+ File.open(@path, 'w') do |f|
74
+ f.write YAML.dump({ @name.to_s => @data })
75
+ end
76
+ end
77
+
78
+ # Public: Returns a String representation of the Locale.
79
+ def to_s
80
+ @name
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,20 @@
1
+ module Mayl
2
+ # Public: The parser interprets commands and executes them.
3
+ class Parser
4
+ # Public: initializes a new Parser with an environment.
5
+ #
6
+ # env - the global state.
7
+ def initialize(env)
8
+ @env = env
9
+ end
10
+
11
+ # Public: Parses a given input and creates a command representation for it.
12
+ #
13
+ # Returns a Command.
14
+ def parse(input)
15
+ operator, *operands = input.split
16
+ klass = Commands.const_get(operator.capitalize)
17
+ klass.new(@env, *Array(operands))
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ module Mayl
2
+ # Public: The class responsible for reading user input, interpreting it and
3
+ # executing associated commands.
4
+ class Repl
5
+ attr_reader :parser
6
+
7
+ # Public: Initializes a new REPL from a given path.
8
+ #
9
+ # path - The path to get the locales from (defaults to 'config/locales').
10
+ def initialize(path)
11
+ path ||= 'config/locales'
12
+ @env = Env.new(path)
13
+ @parser = Parser.new(@env)
14
+ end
15
+
16
+ # Public: Fires up the REPL that parses and executes given commands.
17
+ #
18
+ # Returns nothing.
19
+ def start
20
+ locales = @env.locales.map(&:name)
21
+ prompt = "> "
22
+ puts "Detected locales: #{locales.join(', ')}"
23
+ while (print prompt; input = gets)
24
+ begin
25
+ value = @parser.parse(input.chomp).execute
26
+ @env.last_value = value
27
+ @env.commit
28
+ prompt = [@env.namespace, '> '].reject(&:empty?).join ' '
29
+ rescue => e
30
+ print "Error: #{e.message}"
31
+ ensure
32
+ print "\n"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,4 @@
1
+ module Mayl
2
+ # The version of the Mayl gem.
3
+ VERSION = "0.0.1"
4
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/mayl/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Josep M. Bach"]
6
+ gem.email = ["josep.m.bach@gmail.com"]
7
+ gem.description = %q{A console to create, edit and maintain YAML files in any kind of Ruby projects}
8
+ gem.summary = %q{A console to create, edit and maintain YAML files in any kind of Ruby projects}
9
+ gem.homepage = "http://blog.txustice.me/mayl"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "mayl"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Mayl::VERSION
17
+
18
+ gem.add_development_dependency 'yard'
19
+ gem.add_development_dependency 'yard-tomdoc'
20
+ gem.add_development_dependency 'redcarpet'
21
+
22
+ gem.add_development_dependency 'minitest'
23
+ gem.add_development_dependency 'mocha'
24
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+ require 'ostruct'
4
+
5
+ module Mayl
6
+ module Commands
7
+ describe Cd do
8
+ before do
9
+ @locales = [stub(to_s: 'ca'), stub(to_s: 'en')]
10
+ @env = OpenStruct.new(locales: @locales, namespace: 'activerecord.models')
11
+ end
12
+
13
+ it 'enters a directory' do
14
+ @command = Cd.new @env, 'post.attributes'
15
+ @command.execute
16
+ @env.namespace.must_equal 'activerecord.models.post.attributes'
17
+ end
18
+
19
+ it 'goes down one level' do
20
+ @command = Cd.new @env, '..'
21
+ @command.execute
22
+ @env.namespace.must_equal 'activerecord'
23
+ end
24
+
25
+ it 'goes to the root level' do
26
+ @command = Cd.new @env, '.'
27
+ @command.execute
28
+ @env.namespace.must_equal ''
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ module Mayl
5
+ module Commands
6
+ describe Edit do
7
+ before do
8
+ @locales = [stub(name: 'ca'), stub(name: 'en')]
9
+ @env = stub locales: @locales, namespace: '', last_value: 'activerecord.models.post'
10
+ @command = Edit.new @env, 'en', 'Entry'
11
+ end
12
+
13
+ it 'edits the last key getted or setted' do
14
+ @locales.last.expects(:set).with('activerecord.models.post', 'Entry')
15
+ @command.execute
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ require 'test_helper'
2
+
3
+ module Mayl
4
+ module Commands
5
+ describe Exit do
6
+ before do
7
+ @command = Exit.new(stub)
8
+ end
9
+
10
+ it 'exits the program' do
11
+ @command.expects(:exit).with(0)
12
+ @command.execute
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ module Mayl
5
+ module Commands
6
+ describe Get do
7
+ before do
8
+ @locales = [stub(to_s: 'ca'), stub(to_s: 'en')]
9
+ @env = stub locales: @locales, namespace: 'activerecord'
10
+ @command = Get.new @env, 'models.post'
11
+ end
12
+
13
+ it 'shows the user the values for a key in each locale' do
14
+ @locales.first.expects(:get).with('activerecord.models.post').returns('Article')
15
+ @locales.last.expects(:get).with('activerecord.models.post').returns('Post')
16
+
17
+ @command.expects(:print).with(" ca: Article\n")
18
+ @command.expects(:print).with(" en: Post\n")
19
+
20
+ @command.execute
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ module Mayl
5
+ module Commands
6
+ describe Ls do
7
+ before do
8
+ @locales = [stub(to_s: 'ca'), stub(to_s: 'en')]
9
+ @env = stub locales: @locales, namespace: 'activerecord'
10
+ @command = Ls.new @env
11
+ end
12
+
13
+ it 'prints the current keys inside the namespace' do
14
+ @locales.first.expects(:peek).with('activerecord').returns ['models']
15
+ @locales.last.expects(:peek).with('activerecord').returns ['attributes', 'models']
16
+
17
+ @command.expects(:print).with('models ')
18
+ @command.expects(:print).with('attributes ')
19
+
20
+ @command.execute
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ module Mayl
4
+ module Commands
5
+ describe Set do
6
+ before do
7
+ @locales = [stub(to_s: 'ca'), stub(to_s: 'en')]
8
+ @env = stub locales: @locales, namespace: 'activerecord'
9
+ @command = Set.new @env, 'models.post'
10
+ end
11
+
12
+ it 'lets the user enter a value for the key in each of the locales' do
13
+ @command.expects(:gets).twice.returns('Article', 'Post') # User interaction
14
+
15
+ @locales.first.expects(:set).with('activerecord.models.post', 'Article')
16
+ @locales.last.expects(:set).with('activerecord.models.post', 'Post')
17
+
18
+ @command.execute
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ module Mayl
4
+ describe Env do
5
+ before do
6
+ @locales = [stub, stub]
7
+ Loader.expects(:load).with('my/path').returns @locales
8
+ @env = Mayl::Env.new('my/path')
9
+ end
10
+
11
+ it 'is a container for locales' do
12
+ @env.locales.must_equal @locales
13
+ end
14
+
15
+ it 'commits changes to disk' do
16
+ @locales.each do |locale|
17
+ locale.expects(:commit)
18
+ end
19
+
20
+ @env.commit
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,10 @@
1
+ require 'test_helper'
2
+
3
+ module Mayl
4
+ describe Loader do
5
+ it 'loads YAML files inside a path' do
6
+ locales = Loader.load('test/support')
7
+ locales.map(&:name).sort.must_equal [:ca, :en, :es]
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+
3
+ module Mayl
4
+ describe Locale do
5
+ before do
6
+ hash = { 'ca' => { 'activerecord' => { 'models' => { 'post' => 'Article' } } } }
7
+ @locale = Locale.new('some/ca.yml', hash)
8
+ end
9
+
10
+ it 'gets a key' do
11
+ @locale.get('activerecord.models.post').must_equal 'Article'
12
+ end
13
+
14
+ it 'sets and retrieves a given key' do
15
+ @locale.set('activerecord.models.comment', 'Comentari')
16
+ @locale.get('activerecord.models.comment').must_equal 'Comentari'
17
+ end
18
+
19
+ describe '#commit' do
20
+ it 'does not commit if there are no changes' do
21
+ @locale.commit.must_equal false
22
+ end
23
+ end
24
+
25
+ it 'saves changes to disk' do
26
+ @locale.set('activerecord.whatever', 'foo')
27
+ YAML.expects(:dump).with({
28
+ 'ca' => {
29
+ 'activerecord' => {
30
+ 'models' => {
31
+ 'post' => 'Article'
32
+ },
33
+
34
+ 'whatever' => 'foo'
35
+ }
36
+ }
37
+ }).returns dumped_contents = stub
38
+
39
+ File.expects(:open).with('some/ca.yml', 'w').yields file = stub
40
+ file.expects(:write).with dumped_contents
41
+
42
+ @locale.commit
43
+ end
44
+
45
+ it 'peeks the contents of a given key' do
46
+ @locale.peek('activerecord').must_equal ['models']
47
+ @locale.peek('activerecord.models').must_equal ['post']
48
+ @locale.peek('activerecord.models.post').must_equal nil
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ require 'test_helper'
3
+
4
+ module Mayl
5
+ describe Parser do
6
+ before do
7
+ @env = stub
8
+ @parser = Parser.new(@env)
9
+ end
10
+
11
+ it 'parses commands' do
12
+ command = @parser.parse "set key"
13
+ command.must_be_kind_of Commands::Set
14
+ command.key.must_equal 'key'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ module Mayl
4
+ describe Repl do
5
+ before do
6
+ @repl = Mayl::Repl.new('some/path.yml')
7
+ end
8
+
9
+ it 'parses and executes commands' do
10
+ @foo = stub
11
+ @foo.expects(:execute)
12
+ @baz = stub
13
+ @baz.expects(:execute)
14
+
15
+ @repl.expects(:gets).times(3).returns("foo bar\n", "baz lol\n", nil)
16
+
17
+ @repl.parser.expects(:parse).with('foo bar').returns @foo
18
+ @repl.parser.expects(:parse).with('baz lol').returns @baz
19
+
20
+ @repl.start
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ describe Mayl do
4
+ it 'rocks' do
5
+ true.must_equal true
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ ca:
2
+ activerecord:
3
+ models:
4
+ post: Article
@@ -0,0 +1,4 @@
1
+ en:
2
+ activercord:
3
+ models:
4
+ post: Post
@@ -0,0 +1,4 @@
1
+ es:
2
+ activercord:
3
+ models:
4
+ post: Artículo
@@ -0,0 +1,5 @@
1
+ gem 'minitest'
2
+ require 'minitest/spec'
3
+ require 'minitest/autorun'
4
+ require 'mocha'
5
+ require 'mayl'
metadata ADDED
@@ -0,0 +1,182 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mayl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Josep M. Bach
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: yard
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: yard-tomdoc
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: redcarpet
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: mocha
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: A console to create, edit and maintain YAML files in any kind of Ruby
95
+ projects
96
+ email:
97
+ - josep.m.bach@gmail.com
98
+ executables:
99
+ - mayl
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - .gitignore
104
+ - .rvmrc
105
+ - Gemfile
106
+ - LICENSE
107
+ - README.md
108
+ - Rakefile
109
+ - bin/mayl
110
+ - lib/mayl.rb
111
+ - lib/mayl/commands.rb
112
+ - lib/mayl/commands/cd.rb
113
+ - lib/mayl/commands/edit.rb
114
+ - lib/mayl/commands/exit.rb
115
+ - lib/mayl/commands/get.rb
116
+ - lib/mayl/commands/ls.rb
117
+ - lib/mayl/commands/set.rb
118
+ - lib/mayl/env.rb
119
+ - lib/mayl/loader.rb
120
+ - lib/mayl/locale.rb
121
+ - lib/mayl/parser.rb
122
+ - lib/mayl/repl.rb
123
+ - lib/mayl/version.rb
124
+ - mayl.gemspec
125
+ - test/mayl/commands/cd_test.rb
126
+ - test/mayl/commands/edit_test.rb
127
+ - test/mayl/commands/exit_test.rb
128
+ - test/mayl/commands/get_test.rb
129
+ - test/mayl/commands/ls_test.rb
130
+ - test/mayl/commands/set_test.rb
131
+ - test/mayl/env_test.rb
132
+ - test/mayl/loader_test.rb
133
+ - test/mayl/locale_test.rb
134
+ - test/mayl/parser_test.rb
135
+ - test/mayl/repl_test.rb
136
+ - test/mayl_test.rb
137
+ - test/support/ca.yml
138
+ - test/support/en.yml
139
+ - test/support/es.yml
140
+ - test/test_helper.rb
141
+ homepage: http://blog.txustice.me/mayl
142
+ licenses: []
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ required_rubygems_version: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ! '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubyforge_project:
161
+ rubygems_version: 1.8.21
162
+ signing_key:
163
+ specification_version: 3
164
+ summary: A console to create, edit and maintain YAML files in any kind of Ruby projects
165
+ test_files:
166
+ - test/mayl/commands/cd_test.rb
167
+ - test/mayl/commands/edit_test.rb
168
+ - test/mayl/commands/exit_test.rb
169
+ - test/mayl/commands/get_test.rb
170
+ - test/mayl/commands/ls_test.rb
171
+ - test/mayl/commands/set_test.rb
172
+ - test/mayl/env_test.rb
173
+ - test/mayl/loader_test.rb
174
+ - test/mayl/locale_test.rb
175
+ - test/mayl/parser_test.rb
176
+ - test/mayl/repl_test.rb
177
+ - test/mayl_test.rb
178
+ - test/support/ca.yml
179
+ - test/support/en.yml
180
+ - test/support/es.yml
181
+ - test/test_helper.rb
182
+ has_rdoc: