mayl 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: