cldwalker-alias 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +16 -0
- data/README.rdoc +56 -77
- data/Rakefile +4 -4
- data/VERSION.yml +2 -2
- data/lib/alias/console.rb +13 -49
- data/lib/alias/creator.rb +102 -81
- data/lib/alias/creators/any_to_instance_method_creator.rb +22 -0
- data/lib/alias/creators/class_method_creator.rb +19 -0
- data/lib/alias/creators/class_to_instance_method_creator.rb +25 -0
- data/lib/alias/creators/constant_creator.rb +11 -0
- data/lib/alias/creators/instance_method_creator.rb +19 -0
- data/lib/alias/manager.rb +107 -49
- data/lib/alias/util.rb +86 -0
- data/lib/alias/validator.rb +94 -0
- data/lib/alias.rb +70 -36
- data/test/alias_test.rb +54 -53
- data/test/aliases.yml +8 -4
- data/test/any_to_instance_method_creator_test.rb +39 -0
- data/test/class_method_creator_test.rb +42 -0
- data/test/class_to_instance_method_creator_test.rb +48 -0
- data/test/console_test.rb +60 -0
- data/test/constant_creator_test.rb +27 -22
- data/test/creator_test.rb +24 -65
- data/test/instance_method_creator_test.rb +41 -0
- data/test/manager_test.rb +92 -97
- data/test/test_helper.rb +23 -3
- data/test/util_test.rb +42 -0
- data/test/validator_test.rb +72 -0
- metadata +40 -24
- data/aliases.yml.example +0 -16
- data/lib/alias/class_method_creator.rb +0 -9
- data/lib/alias/constant_creator.rb +0 -50
- data/lib/alias/core_extensions.rb +0 -46
- data/lib/alias/instance_method_creator.rb +0 -9
- data/lib/alias/method_creator_helper.rb +0 -77
- data/lib/config_struct.rb +0 -17
- data/test/core_extensions_test.rb +0 -34
- data/test/method_creator_helper_test.rb +0 -59
data/lib/alias/manager.rb
CHANGED
@@ -1,42 +1,87 @@
|
|
1
|
-
# This class manages creation of aliases.
|
2
1
|
module Alias
|
2
|
+
# This class manages creation, searching and saving of aliases. Aliases are created as follows:
|
3
|
+
# * Alias hashes are read in by Alias.create and/or input through the console via Alias::Console.create_aliases.
|
4
|
+
# * These alias hashes are passed to Alias::Manager.create_aliases. An Alias::Manager object passes each alias hash to
|
5
|
+
# to the correct Alias::Creator subclass by interpreting the creator type.
|
6
|
+
# * Each creator converts their alias hash to an alias hash array and runs them through their defined validators, Alias::Validator objects.
|
7
|
+
# * The aliases that meet the validation conditions are then created using Kernel.eval.
|
3
8
|
class Manager
|
4
|
-
|
9
|
+
|
5
10
|
def initialize #:nodoc:
|
6
|
-
@
|
11
|
+
@creators = {}
|
7
12
|
@verbose = false
|
8
13
|
@force = false
|
9
14
|
end
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
# When true, all failed validations print their message. Takes an array of creator type symbols or a boolean to set all creators.
|
17
|
+
attr_accessor :verbose
|
18
|
+
# When true, optional validations will be skipped. Takes an array of creator type symbols or a boolean to set all creators.
|
19
|
+
attr_accessor :force
|
20
|
+
# A hash of creator objects that have been used by creator type.
|
21
|
+
attr_reader :creators
|
22
|
+
# A hash of created aliases by creator type.
|
23
|
+
attr_reader :created_aliases
|
24
|
+
|
25
|
+
# The main method for creating aliases. Takes a creator type, a hash of aliases whose format is defined per creator and the
|
26
|
+
# following options:
|
27
|
+
#
|
28
|
+
# [:verbose] Sets the verbose flag to print a message whenever an alias validation fails. Default is the creator's verbose flag.
|
29
|
+
# [:force] Sets the force flag to bypass optional validations. Default is the creator's manager flag.
|
30
|
+
# [:pretend] Instead of creating aliases, prints out the ruby code that would be evaluated by Kernel.eval to create the aliases.
|
31
|
+
# Default is false.
|
32
|
+
def create_aliases(creator_type, aliases_hash, options={})
|
33
|
+
return unless (creator = create_creator(creator_type))
|
34
|
+
creator.verbose = options[:verbose] ? options[:verbose] : verbose_creator?(creator_type)
|
35
|
+
creator.force = options[:force] ? options[:force] : force_creator?(creator_type)
|
36
|
+
creator.create(aliases_hash.dup, options[:pretend] || false)
|
37
|
+
true
|
38
|
+
rescue Creator::AbstractMethodError
|
39
|
+
$stderr.puts $!.message
|
40
|
+
rescue Creator::FailedAliasCreationError
|
41
|
+
$stderr.puts "'#{creator.class}' failed to create aliases with error:\n#{$!.message}"
|
16
42
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
43
|
+
|
44
|
+
# Creates aliases in the same way as create_aliases while keeping track of what's created. But differs in that creator types can
|
45
|
+
# be accessed with just the first few unique letters of a type. For example, you can pass :in to mean :instance_method. Also, the
|
46
|
+
# verbose flag is set by default.
|
47
|
+
# Examples:
|
48
|
+
# console_create_aliases :in, "String"=>{"to_s"=>"s"}
|
49
|
+
# console_create_aliases :con, {"ActiveRecord::Base"=>"AB"}, :pretend=>true
|
50
|
+
def console_create_aliases(creator_type, aliases_hash, options={})
|
51
|
+
options = {:verbose=>true}.update(options)
|
52
|
+
@created_aliases ||= {}
|
53
|
+
creator_type = (all_creator_types.sort.find {|e| e[/^#{creator_type}/] } || creator_type).to_sym
|
54
|
+
if create_aliases(creator_type, aliases_hash, options)
|
55
|
+
@created_aliases[creator_type] = aliases_hash
|
56
|
+
true
|
22
57
|
else
|
23
|
-
|
24
|
-
nil
|
58
|
+
false
|
25
59
|
end
|
26
|
-
|
27
60
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
61
|
+
|
62
|
+
# Saves aliases that were created by console_create_aliases. Can take an optional file to save to. See Alias::Console.save_aliases
|
63
|
+
# for default files this method saves to.
|
64
|
+
def save_aliases(file=nil)
|
65
|
+
if @created_aliases
|
66
|
+
Alias.add_to_config_file(@created_aliases, file)
|
67
|
+
true
|
68
|
+
else
|
69
|
+
puts "Didn't save. No created aliases detected."
|
70
|
+
false
|
35
71
|
end
|
36
72
|
end
|
37
|
-
|
73
|
+
|
74
|
+
# Searches all created alias hashes with a hash or a string. If a string, the alias key searched is :name.
|
75
|
+
# If a hash, the key should should be an alias key and the value the search term.
|
76
|
+
# All values are treated as regular expressions. Alias keys vary per creator but some of the common ones are :name, :class and :alias.
|
77
|
+
# Multiple keys for a hash will AND the searches.
|
78
|
+
# Examples:
|
79
|
+
# search 'to_'
|
80
|
+
# search :class=>"Array", :name=>'to'
|
38
81
|
def search(search_hash)
|
39
82
|
result = nil
|
83
|
+
reset_all_aliases
|
84
|
+
search_hash = {:name=>search_hash} unless search_hash.is_a?(Hash)
|
40
85
|
search_hash.each do |k,v|
|
41
86
|
new_result = simple_search(k,v)
|
42
87
|
#AND's searches
|
@@ -44,39 +89,52 @@ module Alias
|
|
44
89
|
end
|
45
90
|
#duplicate results in case they are modified
|
46
91
|
result = result.map {|e| e.dup} if result
|
47
|
-
alias_creator_objects.each {|e| e.searched_at = Time.now }
|
48
92
|
result
|
49
93
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
94
|
+
|
95
|
+
# Returns an array of all created alias hashes. The alias hash will have a :type key which contains the creator type it belongs to.
|
96
|
+
def all_aliases
|
97
|
+
@all_aliases ||= @creators.inject([]) do |t, (type, creator)|
|
98
|
+
t += creator.aliases.each {|e| e[:type] = type.to_s}
|
99
|
+
end
|
53
100
|
end
|
54
|
-
|
101
|
+
|
102
|
+
#:stopdoc:
|
103
|
+
def all_creator_types
|
104
|
+
Creator.creators.map {|e| Util.underscore(e.to_s[/::(\w+)Creator$/,1]) }
|
105
|
+
end
|
106
|
+
|
107
|
+
def aliases_of(creator_type)
|
108
|
+
@creators[creator_type] && @creators[creator_type].aliases
|
109
|
+
end
|
110
|
+
|
111
|
+
def verbose_creator?(creator_type)
|
112
|
+
@verbose.is_a?(Array) ? @verbose.include?(creator_type.to_sym) : @verbose
|
113
|
+
end
|
114
|
+
|
115
|
+
def force_creator?(creator_type)
|
116
|
+
@force.is_a?(Array) ? @force.include?(creator_type.to_sym) : @force
|
117
|
+
end
|
118
|
+
|
119
|
+
def create_creator(creator_type)
|
120
|
+
creator_class_string = "Alias::Creators::#{Util.camelize(creator_type.to_s)}Creator"
|
121
|
+
if creator_class = Util.any_const_get(creator_class_string)
|
122
|
+
@creators[creator_type.to_sym] ||= creator_class.new
|
123
|
+
else
|
124
|
+
$stderr.puts "Creator class '#{creator_class_string}' not found."
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
55
129
|
def simple_search(field, search_term)
|
56
|
-
|
57
|
-
search_term.is_a?(Regexp) ? e[field] =~ search_term : e[field] == search_term
|
58
|
-
}
|
59
|
-
result
|
130
|
+
all_aliases.select {|e| e[field] =~ /#{search_term}/ }
|
60
131
|
end
|
61
132
|
|
62
133
|
def intersection_of_two_arrays(arr1, arr2)
|
63
134
|
arr2.nil? ? arr1 : arr1.select {|e| arr2.include?(e)}
|
64
135
|
end
|
65
|
-
|
66
|
-
def
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
def reindex_aliases(searchable_array=nil)
|
71
|
-
searchable_array ||= []
|
72
|
-
@alias_creators.map do |type, creator|
|
73
|
-
if creator.modified_since_last_search?
|
74
|
-
searchable_array.delete_if {|e| e[:type] == type.to_s}
|
75
|
-
new_arr = creator.to_searchable_array.each {|e| e[:type] = type.to_s}
|
76
|
-
searchable_array += new_arr
|
77
|
-
end
|
78
|
-
end
|
79
|
-
searchable_array
|
80
|
-
end
|
136
|
+
|
137
|
+
def reset_all_aliases; @all_aliases = nil; end
|
138
|
+
#:startdoc:
|
81
139
|
end
|
82
140
|
end
|
data/lib/alias/util.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
module Alias
|
2
|
+
# A collection of utility functions used throughout.
|
3
|
+
module Util #:nodoc:
|
4
|
+
extend self
|
5
|
+
# simplified from ActiveSupport
|
6
|
+
def slice(hash, *keys)
|
7
|
+
hash.reject {|key,| !keys.include?(key) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def slice_off!(hash, *keys) #:nod
|
11
|
+
new_hash = slice(hash,*keys)
|
12
|
+
keys.each {|e| hash.delete(e)}
|
13
|
+
new_hash
|
14
|
+
end
|
15
|
+
|
16
|
+
#from ActiveSupport
|
17
|
+
def symbolize_keys(hash)
|
18
|
+
hash.inject({}) do |options, (key, value)|
|
19
|
+
options[key.to_sym] = value
|
20
|
+
options
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Recursively merge hash1 with hash2.
|
25
|
+
def recursive_hash_merge(hash1, hash2)
|
26
|
+
hash1.merge(hash2) {|k,o,n| (o.is_a?(Hash)) ? recursive_hash_merge(o,n) : n}
|
27
|
+
end
|
28
|
+
|
29
|
+
def any_const_get(name)
|
30
|
+
Util.const_cache[name] ||= Util.uncached_any_const_get(name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def const_cache
|
34
|
+
@const_cache ||= {}
|
35
|
+
end
|
36
|
+
|
37
|
+
def uncached_any_const_get(name)
|
38
|
+
begin
|
39
|
+
klass = Object
|
40
|
+
name.split('::').each {|e|
|
41
|
+
klass = klass.const_get(e)
|
42
|
+
}
|
43
|
+
klass
|
44
|
+
rescue
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
#simplified version from ActiveSupport
|
50
|
+
def camelize(string)
|
51
|
+
string.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
52
|
+
end
|
53
|
+
|
54
|
+
# from ActiveSupport
|
55
|
+
def underscore(camel_cased_word)
|
56
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
57
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
58
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
59
|
+
tr("-", "_").
|
60
|
+
downcase
|
61
|
+
end
|
62
|
+
|
63
|
+
def make_shortest_aliases(unaliased_strings)
|
64
|
+
shortest_aliases = {}
|
65
|
+
possible_alias = ''
|
66
|
+
unaliased_strings.each {|s|
|
67
|
+
possible_alias = ''
|
68
|
+
s.split('').each { |e|
|
69
|
+
possible_alias += e
|
70
|
+
if ! shortest_aliases.values.include?(possible_alias)
|
71
|
+
shortest_aliases[s] = possible_alias
|
72
|
+
break
|
73
|
+
end
|
74
|
+
}
|
75
|
+
}
|
76
|
+
shortest_aliases
|
77
|
+
end
|
78
|
+
|
79
|
+
def silence_warnings
|
80
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
81
|
+
yield
|
82
|
+
ensure
|
83
|
+
$VERBOSE = old_verbose
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Alias
|
2
|
+
# Creates validations for use with Alias::Creator.valid.
|
3
|
+
class Validator
|
4
|
+
class MissingConditionError < StandardError; end
|
5
|
+
class InvalidValidatorError < StandardError; end
|
6
|
+
|
7
|
+
attr_reader :validation_proc, :message
|
8
|
+
# Options are described in Alias::Creator.valid.
|
9
|
+
def initialize(options={})
|
10
|
+
raise ArgumentError unless options[:key] && options[:creator]
|
11
|
+
@condition = options[:if] || options[:unless] || raise(MissingConditionError)
|
12
|
+
inherits(Validator.validators[@condition]) if Validator.validators[@condition]
|
13
|
+
raise InvalidValidatorError unless @condition.is_a?(Proc)
|
14
|
+
@optional = options[:optional] || false
|
15
|
+
@validation_proc = options[:unless] ? lambda {|e| ! @condition.clone.call(e) } : @condition
|
16
|
+
@options = options
|
17
|
+
@message = options[:message] if options[:message]
|
18
|
+
@message = default_message unless @message.is_a?(Proc)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Validates a given alias hash with the validator proc defined by :if or :unless in Alias::Creator.valid.
|
22
|
+
# Default arguments that these procs receive works as follows:
|
23
|
+
# If the validation key is the same name as any of the keys in the alias hash, then only the value of that
|
24
|
+
# that alias key is passed to the procs. If not, then the whole alias hash is passed.
|
25
|
+
def validate(current_creator, alias_hash, current_attribute)
|
26
|
+
return true if @optional && current_creator.force
|
27
|
+
arg = create_proc_arg(alias_hash, current_attribute)
|
28
|
+
result = !!@validation_proc.call(arg)
|
29
|
+
puts create_message(arg) if result != true && current_creator.verbose
|
30
|
+
result
|
31
|
+
end
|
32
|
+
|
33
|
+
#:stopdoc:
|
34
|
+
def inherits(parent_validator)
|
35
|
+
@condition = parent_validator.validation_proc.clone
|
36
|
+
@message = parent_validator.message.clone
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_message
|
40
|
+
lambda {|e| "Validation failed for #{@options[:creator]}'s #{@options[:key]} since it doesn't exist"}
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_proc_arg(alias_hash, current_attribute) #:nodoc:
|
44
|
+
@options[:with] ? @options[:with].map {|f| alias_hash[f] } : (alias_hash[current_attribute] || alias_hash)
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_message(arg)
|
48
|
+
result = @message.call(arg)
|
49
|
+
@options[:unless] ? result.gsub("doesn't exist", 'already exists') : result
|
50
|
+
end
|
51
|
+
#:startdoc:
|
52
|
+
|
53
|
+
class <<self
|
54
|
+
# Hash of registered validators.
|
55
|
+
attr_reader :validators
|
56
|
+
|
57
|
+
# Registers validators which creators can reference as symbols in Alias::Creator.valid.
|
58
|
+
def register_validators(validators)
|
59
|
+
@validators ||= {}
|
60
|
+
validators.each do |e|
|
61
|
+
@validators[e[:key]] ||= Validator.new(e.merge(:creator=>self))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Default validators are :constant, :class, :instance_method and :class_method.
|
66
|
+
def default_validators
|
67
|
+
[
|
68
|
+
{:key=>:constant, :if=>lambda {|e| any_const_get(e) }, :message=>lambda {|e| "Constant '#{e}' not created since it doesn't exist"}},
|
69
|
+
{:key=>:class, :if=>lambda {|e| ((klass = any_const_get(e)) && klass.is_a?(Module)) },
|
70
|
+
:message=>lambda {|e| "Alias for class '#{e}' not created since the class doesn't exist"}},
|
71
|
+
{:key=>:instance_method, :if=> lambda {|e| instance_method?(*e) },
|
72
|
+
:message=>lambda {|e| "Alias for instance method '#{e[0]}.#{e[1]}' not created since it doesn't exist" }},
|
73
|
+
{:key=>:class_method, :if=>lambda {|e| class_method?(*e) },
|
74
|
+
:message=>lambda {|e| "Alias for class method '#{e[0]}.#{e[1]}' not created since it doesn't exist" }}
|
75
|
+
]
|
76
|
+
end
|
77
|
+
|
78
|
+
#:stopdoc:
|
79
|
+
def any_const_get(name)
|
80
|
+
Util.any_const_get(name)
|
81
|
+
end
|
82
|
+
|
83
|
+
def instance_method?(klass, method)
|
84
|
+
(klass = any_const_get(klass)) && (klass.method_defined?(method) || klass.private_method_defined?(method))
|
85
|
+
end
|
86
|
+
|
87
|
+
def class_method?(klass, method)
|
88
|
+
(klass = any_const_get(klass)) && klass.respond_to?(method, true)
|
89
|
+
end
|
90
|
+
#:startdoc:
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
Alias::Validator.register_validators(Alias::Validator.default_validators)
|
data/lib/alias.rb
CHANGED
@@ -1,51 +1,85 @@
|
|
1
|
-
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__))
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) ||
|
2
|
+
$:.include?(File.expand_path(File.dirname(__FILE__)))
|
2
3
|
require 'yaml'
|
3
|
-
require 'config_struct'
|
4
4
|
require 'alias/manager'
|
5
|
+
require 'alias/validator'
|
5
6
|
require 'alias/creator'
|
6
|
-
require 'alias/constant_creator'
|
7
|
-
require 'alias/
|
8
|
-
require 'alias/
|
9
|
-
require 'alias/
|
10
|
-
require 'alias/
|
7
|
+
require 'alias/creators/constant_creator'
|
8
|
+
require 'alias/creators/instance_method_creator'
|
9
|
+
require 'alias/creators/class_method_creator'
|
10
|
+
require 'alias/creators/class_to_instance_method_creator'
|
11
|
+
require 'alias/creators/any_to_instance_method_creator'
|
12
|
+
require 'alias/util'
|
11
13
|
require 'alias/console'
|
12
14
|
|
15
|
+
# Most of the core Alias actions are run through Alias::Manager except for Alias.create.
|
16
|
+
# See Alias::Manager for an explanation of how aliases are created.
|
13
17
|
module Alias
|
14
18
|
extend self
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
|
20
|
+
# Creates aliases from Alias.config_file if it exists and merges them with any explicit aliases. This method takes
|
21
|
+
# the same keys used by config files (see Alias.config_file) and also the following options:
|
22
|
+
# * :file : Specifies a config file to override Alias.config_file. If set to false, no config file is loaded.
|
23
|
+
# Examples:
|
24
|
+
# # Loads any default files and the ones in :aliases.
|
25
|
+
# # Sets global verbosity for creators.
|
26
|
+
# create :aliases=>{:constant=>{"Array"=>"A"}}, :verbose=>true
|
27
|
+
# # Loads the given file and sets verbosity just for the :instance_method creator.
|
28
|
+
# create :file=>"some file", :verbose=>[:instance_method]
|
29
|
+
def create(options={})
|
30
|
+
file_config = load_config_file(options.delete(:file))
|
31
|
+
new_config = Util.recursive_hash_merge(file_config, options)
|
32
|
+
manager.verbose = new_config[:verbose] if new_config[:verbose]
|
33
|
+
manager.force = new_config[:force] if new_config[:force]
|
34
|
+
(new_config[:aliases] || {}).each do |creator_type, aliases|
|
35
|
+
manager.create_aliases(creator_type, aliases)
|
23
36
|
end
|
24
|
-
|
37
|
+
@config = Util.recursive_hash_merge(config, new_config)
|
25
38
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
39
|
+
|
40
|
+
# By default, looks for existing files in config/alias.yml and then ~/.alias.yml. A config file has the following keys:
|
41
|
+
# [:aliases] This takes a hash mapping creators to their config hashes. Valid creators are :instance_method, :class_method, :constant,
|
42
|
+
# :class_to_instance_method and :any_to_instance_method.
|
43
|
+
# [:verbose] Sets whether creators are verbose with boolean or array of creator symbols. A boolean sets verbosity for all creators whereas
|
44
|
+
# the array specifies which creators. Default is false.
|
45
|
+
# [:force] Sets whether creators force optional validations with boolean or array of creator symbols. Works the same as :verbose. Default is false.
|
46
|
+
def config_file
|
47
|
+
@config_file ||= File.exists?("config/alias.yml") ? 'config/alias.yml' : "#{ENV['HOME']}/.alias.yml"
|
48
|
+
end
|
49
|
+
|
50
|
+
# Contains primary Alias::Manager object which is used throughout Alias.
|
51
|
+
def manager
|
52
|
+
@manager ||= Manager.new
|
53
|
+
end
|
54
|
+
|
55
|
+
#:stopdoc:
|
56
|
+
def add_to_config_file(new_aliases, file)
|
57
|
+
file ||= File.directory?('config') ? 'config/alias.yml' : "#{ENV['HOME']}/.alias.yml"
|
58
|
+
existing_aliases = read_config_file(file)
|
59
|
+
existing_aliases[:aliases] = Util.recursive_hash_merge existing_aliases[:aliases], new_aliases
|
60
|
+
save_to_file file, existing_aliases.to_yaml
|
61
|
+
puts "Saved created aliases to #{file}."
|
62
|
+
end
|
63
|
+
|
64
|
+
def save_to_file(file, string)
|
65
|
+
File.open(File.expand_path(file), 'w') {|f| f.write string }
|
66
|
+
end
|
67
|
+
|
68
|
+
def read_config_file(file)
|
69
|
+
file_config = File.exists?(File.expand_path(file)) ? YAML::load_file(File.expand_path(file)) : {}
|
70
|
+
file_config = Util.symbolize_keys file_config
|
71
|
+
file_config[:aliases] = file_config[:aliases] ? Util.symbolize_keys(file_config.delete(:aliases)) : {}
|
72
|
+
file_config
|
73
|
+
end
|
74
|
+
|
75
|
+
def load_config_file(file)
|
76
|
+
return {} if file == false
|
77
|
+
@config_file = file if file
|
78
|
+
read_config_file(config_file)
|
40
79
|
end
|
41
80
|
|
42
81
|
def config
|
43
82
|
@config ||= {}
|
44
83
|
end
|
45
|
-
|
46
|
-
def config=(value); @config = value; end
|
47
|
-
|
48
|
-
def manager
|
49
|
-
@manager ||= Manager.new
|
50
|
-
end
|
84
|
+
#:startdoc:
|
51
85
|
end
|
data/test/alias_test.rb
CHANGED
@@ -1,62 +1,63 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
2
2
|
|
3
3
|
class AliasTest < Test::Unit::TestCase
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
test "loads config file aliases.yml if found" do
|
11
|
-
File.stubs(:exists?).returns(false, true)
|
12
|
-
File.stubs(:read).returns('')
|
13
|
-
Alias.load_config_file
|
14
|
-
end
|
15
|
-
|
16
|
-
test "loads given config file" do
|
17
|
-
config = Alias.load_config_file(File.join(File.dirname(__FILE__),'aliases.yml'))
|
18
|
-
assert config.is_a?(Hash)
|
19
|
-
end
|
20
|
-
|
21
|
-
test "returns hash if no config file found" do
|
22
|
-
File.stubs(:exists?).returns(false)
|
23
|
-
Alias.load_config_file.should == {}
|
24
|
-
end
|
25
|
-
|
26
|
-
context "Alias_init" do
|
27
|
-
before(:each) { Alias.config = {}}
|
28
|
-
|
29
|
-
test "with block sets config properly" do
|
30
|
-
Alias.manager.expects(:create_aliases).times(2)
|
31
|
-
Alias.init do |a|
|
32
|
-
a.verbose = true
|
33
|
-
a.constant = {'Blah'=>'B'}
|
34
|
-
a.instance_method = {'String'=>{'to_s'=>'s'}}
|
35
|
-
end
|
36
|
-
expected_config = {"instance_method"=>{"String"=>{"to_s"=>"s"}}, "constant"=>{"Blah"=>"B"}, "verbose"=>true}
|
37
|
-
Alias.config.should == expected_config
|
4
|
+
context "Alias" do
|
5
|
+
test "loads config file config/alias.yml if found" do
|
6
|
+
File.expects(:exists?).with('config/alias.yml').returns(true)
|
7
|
+
Alias.config_file.should == 'config/alias.yml'
|
38
8
|
end
|
9
|
+
|
10
|
+
context "create" do
|
11
|
+
before(:each) { Alias.instance_eval "@manager = @config = @config_file = nil"}
|
39
12
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
13
|
+
test "with aliases option creates aliases" do
|
14
|
+
options = {:aliases=>{:constant=> {'Array'=>'Arr'}, :instance_method=>{'String'=>{'to_s'=>'s'}} } , :file=>false}
|
15
|
+
Alias.create options
|
16
|
+
Alias.manager.aliases_of(:instance_method).empty?.should be(false)
|
17
|
+
Alias.manager.aliases_of(:constant).empty?.should be(false)
|
18
|
+
Alias.config.should == options
|
19
|
+
end
|
46
20
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
21
|
+
test "with file option creates aliases" do
|
22
|
+
Alias.create :file=>File.join(File.dirname(__FILE__),'aliases.yml')
|
23
|
+
Alias.manager.aliases_of(:instance_method).empty?.should be(false)
|
24
|
+
Alias.manager.aliases_of(:class_method).empty?.should be(false)
|
25
|
+
Alias.manager.aliases_of(:constant).empty?.should be(false)
|
26
|
+
Alias.manager.aliases_of(:class_to_instance_method).empty?.should be(false)
|
27
|
+
end
|
28
|
+
|
29
|
+
test "with false file option doesn't load config file" do
|
30
|
+
Alias.create :file=>'blah'
|
31
|
+
File.expects(:exists?).never
|
32
|
+
Alias.create :file=>false
|
33
|
+
end
|
34
|
+
|
35
|
+
test "with invalid file option creates nothing" do
|
36
|
+
Alias.create :file=>'blah'
|
37
|
+
Alias.config.should == {:aliases=>{}}
|
38
|
+
end
|
53
39
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
40
|
+
test "with verbose option sets manager's verbose" do
|
41
|
+
Alias.manager.verbose.should == false
|
42
|
+
Alias.create :verbose=>true, :aliases=>{}, :file=>false
|
43
|
+
Alias.manager.verbose.should == true
|
44
|
+
end
|
45
|
+
|
46
|
+
test "with force option sets manager's verbose" do
|
47
|
+
Alias.manager.force.should == false
|
48
|
+
Alias.create :force=>true, :aliases=>{}
|
49
|
+
Alias.manager.force.should == true
|
50
|
+
end
|
51
|
+
|
52
|
+
test "called twice recursively merges config" do
|
53
|
+
hash1 = {:constant=>{"Blah"=>"B"}}
|
54
|
+
Alias.manager.expects(:create_aliases).with(:constant, hash1[:constant])
|
55
|
+
Alias.create :aliases=>hash1, :file=>false
|
56
|
+
hash2 = {:constant=>{"Blah2"=>"B2"}}
|
57
|
+
Alias.manager.expects(:create_aliases).with(:constant, hash2[:constant])
|
58
|
+
Alias.create :aliases=>hash2, :file=>false
|
59
|
+
Alias.config.should == {:aliases=>{:constant=>{"Blah"=>"B", "Blah2"=>"B2"}} }
|
60
|
+
end
|
59
61
|
end
|
60
62
|
end
|
61
|
-
|
62
|
-
end
|
63
|
+
end
|
data/test/aliases.yml
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
-
|
1
|
+
:aliases:
|
2
|
+
constant:
|
2
3
|
Object: O
|
3
4
|
|
4
|
-
class_method:
|
5
|
+
class_method:
|
5
6
|
Object:
|
6
7
|
const_get: cg
|
7
8
|
|
8
|
-
instance_method:
|
9
|
+
instance_method:
|
9
10
|
String:
|
10
11
|
to_s: ts
|
11
|
-
bling: bl
|
12
|
+
bling: bl
|
13
|
+
class_to_instance_method:
|
14
|
+
String:
|
15
|
+
Date.civil: civ
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
2
|
+
|
3
|
+
class Alias::Creators::AnyToInstanceMethodCreatorTest < Test::Unit::TestCase
|
4
|
+
context "AnyToInstanceMethodCreator" do
|
5
|
+
before(:each) { @manager = Alias::Manager.new }
|
6
|
+
|
7
|
+
def expect_aliases(hash)
|
8
|
+
arr = Alias::Creators::AnyToInstanceMethodCreator.maps_config(hash)
|
9
|
+
Alias::Creators::AnyToInstanceMethodCreator.expects(:generates_aliases).with(arr).returns('')
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_aliases(hash)
|
13
|
+
@manager.create_aliases(:any_to_instance_method, hash)
|
14
|
+
end
|
15
|
+
|
16
|
+
test "deletes invalid classes" do
|
17
|
+
expect_aliases 'String'=>{'String.to_s'=>'s'}
|
18
|
+
create_aliases 'String'=>{'String.to_s'=>'s'}, 'AnotherString'=>{'String.to_s'=>'s'}
|
19
|
+
end
|
20
|
+
|
21
|
+
test "deletes existing method aliases" do
|
22
|
+
expect_aliases 'String'=>{'Date.commercial'=>'s'}
|
23
|
+
create_aliases 'String'=>{'Date.civil'=>'strip', 'Date.commercial'=>'s'}
|
24
|
+
end
|
25
|
+
|
26
|
+
test "creates aliases" do
|
27
|
+
Kernel.eval %[
|
28
|
+
class ::SomeClass
|
29
|
+
def self.cap; 'itup'; end
|
30
|
+
end
|
31
|
+
module ::SomeModule; end
|
32
|
+
]
|
33
|
+
create_aliases 'SomeModule'=>{'SomeClass.cap.to_sym'=>'c', 'SomeClass.cap.gsub'=>'gsub'}
|
34
|
+
obj = Object.new.extend SomeModule
|
35
|
+
SomeClass.cap.to_sym.should == obj.c
|
36
|
+
SomeClass.cap.gsub('cap','smack') == obj.gsub('cap','smack')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|