Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

#7 extend .require

  • Loading branch information...
commit 7890835fceb120bb4db3efe194290d8732a12c09 1 parent 2ffdcb8
@gutenye authored
View
1  .gitignore
@@ -1,2 +1,3 @@
*~
Gemfile.lock
+tags
View
14 Gemfile
@@ -1,10 +1,12 @@
-source :rubygems
+source "http://rubygems.org"
+
+gem "hike", "~>1.2.0"
group :development do
- gem 'rspec'
- gem 'watchr'
- gem 'rag'
- gem 'pd'
+ gem "rspec"
+ gem "watchr"
+ gem "rag"
+ gem "pd"
end
-gemspec
+#gemspec
View
67 README.md
@@ -18,14 +18,14 @@ Features
Introduction
-------------
-The three levels of configuration include system, user, and cmdline:
+The three levels of configuration include system, user, and realtime:
- APP/lib/guten/rc.rb # system level
- ~/.gutenrc # user level
- $ guten --list or ENV[GEMFILE]=x guten # cmdline level
+ /etc/foo or APP/lib/foo/rc.rb # system level
+ ~/.foorc # user level
+ $ foo --list or $ ENV[GEMFILE]=x foo # realtime level
module Guten
- Rc = Optimism.require("guten/rc") + Optimism.require("~/.gutenrc") # require use $:
+ Rc = Optimism.require(%w[foo/rc ~/.foorc])
Rc.list = true or Rc.gemfile = ENV[GEMFILE] # from cmdline.
end
@@ -41,7 +41,7 @@ The three levels of configuration include system, user, and cmdline:
my.development do # namespace
adapter "postgresql"
database "hello_development"
- username "guten"
+ username "foo"
end
time proc{|offset| Time.now} # computed attribute
@@ -57,7 +57,7 @@ The three levels of configuration include system, user, and cmdline:
my.development do |c|
c.adapter = "mysql2"
c.database = "hello"
- c.username = "guten"
+ c.username = "foo"
end
c.time = proc{|offset| Time.now}
@@ -65,18 +65,18 @@ The three levels of configuration include system, user, and cmdline:
### An example of some sugar syntax. _works in a file only_ ###
- # file: guten/rc.rb
+ # file: foo/rc.rb
development:
adapter "mysql2"
database "hello"
- username "guten"
+ username "foo"
#=>
development do
adapter "mysql2"
database "hello"
- username "guten"
+ username "foo"
end
@@ -88,14 +88,17 @@ In order for this to work, a tab ("\t") must be used for indention.
In order to initialize the configuration object either of the two ways can be used.
Rc = Optimism.new
- Rc = Optimism.require "guten/rc" # from file
+ Rc = Optimism.require "foo/rc" # from file
Rc = Optimism do
a 1
end
Rc = Optimism[a: 1] # from a hash data
- Rc._merge!(a: 1)
-file: "guten/rc.rb"
+ Rc = Optimism.new
+ Rc.production << {a: 1} #=> Rc.production.a is 1
+ Rc.production << Optimism.require_string("my.age = 1") #=> Rc.production.my.age is 1
+
+file: "foo/rc.rb"
a 1
@@ -231,6 +234,28 @@ Internal, datas are stored as a Hash. You can access all hash methods via `_meth
Rc._keys #=> [:a]
+### Require ###
+
+ # load configuration from file. support $:
+ Optimism.require %w(
+ foo/rc
+ ~/.foorc
+ end
+
+ # load configuration from string
+ Optimism.require_string <<-EOF
+ my.age = 1
+ EOF
+
+
+ # load configuration from environment variable
+ ENV[OPTIMISM_A_B] = 1
+ Rc = Optimism.require_env(/OPTIMISM_(.*)/) #=> Rc.a_b is 1
+ Rc = Optimism.require_env(/OPTIMISM_(.*)/, split: '_') #=> Rc.a.b is 1
+
+ # load configuration from user input
+ Rc = Optimism.require_input("what's your name?", "my.name") #=> Rc.my.name is 'what you typed in terminal'
+
### Temporarily change ###
Rc.a = 1
@@ -259,22 +284,28 @@ Note: for a list of blocked methods, see Optimism::BUILTIN_METHODS
end
end
+ Optimism do
+ _.name = "foo"
+ my.name = "bar" # _ is optional here.
+ end
+
\# file: a.rb
- c = self
- c.host = "localhost"
- c.port = 8080
- c.name do |c|
+ _.host = "localhost"
+ _.port = 8080
+ _.name do |c|
c.first = "Guten"
end
Contributing
--------------
+------------
* Feel free to join the project and make contributions (by submitting a pull request)
* Submit any bugs/features/ideas to github issue tracker
* Coding Style Guide: https://gist.github.com/1105334
+[a list of Contributors](https://github.com/GutenYe/optimism/wiki/Contributors)
+
Install
----------
View
94 lib/optimism.rb
@@ -1,3 +1,5 @@
+require 'hike'
+
libdir = File.dirname(__FILE__)
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
@@ -5,6 +7,7 @@
semantics
hash_method_fix
parser
+ require
).each { |n| require "optimism/#{n}" }
# <#Optimism> is a node, it has _child, _parent and _root attribute.
@@ -34,14 +37,16 @@
class Optimism
autoload :VERSION, "optimism/version"
- Error = Class.new Exception
- LoadError = Class.new Error
+ Error = Class.new Exception
+ MissingFile = Class.new Error
BUILTIN_METHODS = [ :p, :raise, :sleep, :rand, :srand, :exit, :require, :at_exit, :autoload, :open]
class << self
public *BUILTIN_METHODS
+ include Require
+
# eval a file/string configuration.
#
# @params [String] content
@@ -53,7 +58,30 @@ def eval(content=nil, &blk)
optimism._root
end
- # convert Hash, Optimism to Optimism
+ # deep convert Hash to optimism
+ #
+ # @example
+ # hash2optimism({a: {b: 1})
+ # #=> Optimism[a: Optimism[b: 1]]
+ #
+ # @param [Hash,Optimism] hash
+ # @return [Optimism]
+ def convert(hash)
+ return hash if Optimism === hash
+
+ node = Optimism.new
+ hash.each { |k,v|
+ if Hash === v
+ node[k] = convert(v)
+ else
+ node[k] = v
+ end
+ }
+ node
+ end
+
+ # convert Hash to Optimism
+ #
# @param [Optimism,Hash] data
# @return [Optimism]
def [](data)
@@ -80,55 +108,13 @@ def get(obj)
end
end
- # load a configuration file,
- # use $: and support '~/.gutenrc'
- #
- # @example
- # Rc = Optimism.require("~/.gutenrc")
- #
- # Rc = Optimism.require("/absolute/path/rc.rb")
- #
- # Rc = Optimism.require("guten/rc") #=> load 'APP/lib/guten/rc.rb'
- # # first try 'guten/rc.rb', then 'guten/rc'
- #
- # @param [String] name
- # @return [Optimism]
- def require(name)
- path = nil
- # ~/.gutenrc
- if name =~ /^~/
- file = File.expand_path(name)
- path = file if File.exists?(file)
-
- # /absolute/path/to/rc
- elsif File.absolute_path(name) == name
- path = name if File.exists?(name)
-
- # relative/rc
- else
- catch :break do
- $:.each { |p|
- ['.rb', ''].each { |ext|
- file = File.join(p, name+ext)
- if File.exists? file
- path = file
- throw :break
- end
- }
- }
- end
- end
-
- raise LoadError, "can't find file -- #{name}" unless path
-
- Optimism.eval File.read(path)
- end
end
undef_method *BUILTIN_METHODS
include Semantics
include HashMethodFix
+ include RequireInstanceMethod
# parent node, a <#Optimism>
attr_accessor :_parent
@@ -176,9 +162,25 @@ def _child=(obj)
end
# set data
+ #
+ # @example
+ #
+ # o = Optimism.new
+ #
+ # a = Optimism do
+ # _.b = 1
+ # end
+ #
+ # o[:a] = a OR o.a << a #=> o.a.b is 1
+ #
def []=(key, value)
key = key.respond_to?(:to_sym) ? key.to_sym : key
+ if Optimism === value
+ value._parent = self
+ value._root = self._root
+ end
+
@_child[key] = value
end
View
59 lib/optimism/hash_method_fix.rb
@@ -4,23 +4,68 @@ class Optimism
#
module HashMethodFix
- # merge new data IN PLACE
+ # deep merge new data IN PLACE
#
# @params [Hash,Optimism] obj
# @return [self]
- def _merge! obj
- _child.merge! Optimism.get(obj)
+ def _merge!(other)
+ other = Optimism.convert(other)
+ other._each { |k, v|
+ if Optimism === self[k] and Optimism === other[k]
+ self[k]._merge!(other[k])
+ else
+ self[k] = other[k]
+ end
+ }
+
self
end
- # merge new data
+ alias << _merge!
+
+ # deep merge new data
#
# @params [Hash,Optimism] obj
# @return [Optimism] new <#Optimism>
- def _merge obj
- data = _child.merge(Optimism.get(obj))
- Optimism[data]
+ def _merge other
+ target = dup
+ other = Optimism.convert(other)
+
+ other._each { |k, v|
+ if Optimism === target[k] and Optimism === other[k]
+ target[k]._merge(other[k])
+ else
+ target[k] = other[k]
+ end
+ }
+
+ target
end
+ # support path
+ #
+ # @example
+ #
+ # o = Optimism do
+ # _.a = 1
+ # _.b.c = 2
+ # end
+ #
+ # o._get("b.c") #=> 2
+ # o._get("c.d") #=> nil. path doesn't exist.
+ # o._get("a.b") #=> nil. path is wrong
+ #
+ # @param [String] key
+ # @return [Object] value
+ def _get(key)
+ value = self
+ key.split(".").each { |k|
+ return nil unless Optimism === value # wrong path
+ value = value[k]
+ return nil if value.nil? # path doesn't exist.
+ }
+
+ value
+ end
end
end
View
277 lib/optimism/require.rb
@@ -0,0 +1,277 @@
+class Optimism
+ module Require
+ # load configuration from file
+ #
+ # use $: and support home path like '~/.foorc'.
+ # by defualt, it ignore missing files.
+ #
+ # @example
+ #
+ # Optimism.require "foo" # first try guten/rc, then try guten/rc.rb
+ #
+ # Optimism.require %w(
+ # /etc/foo
+ # ~/.foorc
+ # )
+ #
+ # # with option :parent. add a namespace
+ # Rc = Optimism.require_string <<-EOF, :parent => 'a.b'
+ # c.d = 1
+ # e.f = 2
+ # EOF
+ # # => Rc.a.b.c.d is 1
+ #
+ # # add to an existing configuration object.
+ # Rc = Optimism.new
+ # Rc.a.b << Optimism.require_string("my.age = 1") #=> Rc.a.b.my.age is 1
+ #
+ # # call with block
+ # ENV["AGE"] = "1"
+ # Rc = Optimism.require_env("AGE") { |age| age.to_i }
+ # p Rc.age #=> 1
+ #
+ # # option :mixin => :ignore is ignore already exisiting value.
+ # # a.rb
+ # a.b = 1
+ # a.c = "foo"
+ # # b.rb
+ # a.b = 2
+ # a.d = "bar"
+ # Optimism.require %w(a b), :mixin => :ignore
+ # #=>
+ # a.b is 1
+ # a.c is "foo"
+ # a.d is "bar"
+ #
+ # @param [Array,String] name_s
+ # @param [Hash] opts
+ # @option opts [String] :parent wrap into a namespace.
+ # @option opts [Boolean] :mixin (:replace) :replace :ignore
+ # @option opts [Boolean] :ignore_syntax_error not raise SyntaxError
+ # @option opts [Boolean] :raise_missing_file raise MissingFile
+ # @return [Optimism]
+ #
+ # @param [Hash] opts
+ def require_file(name_s, opts={})
+ opts[:mixin] ||= :replace
+ name_s = Array === name_s ? name_s : [name_s]
+ error = opts[:ignore_syntax_error] ? SyntaxError : nil
+
+ o = Optimism.new
+ name_s.each { |name|
+ path = find_file(name, opts)
+ unless path
+ raise MissingFile if opts[:raise_missing_file]
+ next
+ end
+
+ begin
+ new = Optimism.eval(File.read(path))
+ rescue error
+ end
+
+ case opts[:mixin]
+ when :replace
+ o << new
+ when :ignore
+ new << o
+ o = new
+ end
+ }
+
+ o = wrap_into_namespace(opts[:parent], o) if opts[:parent]
+
+ o
+ end
+
+ alias require require_file
+
+ # load configuration from environment variables.
+ # @see require_file
+ #
+ # @example
+ #
+ # ENV["A"] = "1"
+ # ENV["OPTIMISM_A] = "a"
+ # ENV["OPTIMISM_B_C] = "b"
+ #
+ # # default is case_insensive
+ # require_env("A") #=> Optimism[a: "1"]
+ # require_env("A", case_sensive: true) #=> Optimism[A: "1"]
+ #
+ # # with Regexp
+ # require_env(/OPTIMISM_(.*)/) #=> Optimism[a: "a", b_c: "b"]
+ # require_env(/OPTIMISM_(.*), split: "_") #=> Optimism[a: "a", b: Optimism[c: "b"]]
+ #
+ # @overload require_env(env_s, opts={}, &blk)
+ # @param [String, Array, Regexp] env_s
+ # @param [Hash] opts
+ # @option opts [String] :parent
+ # @option opts [String, Regexp] :split
+ # @option opts [Boolean] :case_sensive (false)
+ # @return [Optimism] def require_env(*args, &blk)
+ def require_env(*args, &blk)
+ if Regexp === args[0]
+ pat = args[0]
+ opts = args[1] || {}
+ envs = ENV.each.with_object({}) { |(key,value), memo|
+ next unless key.match(pat)
+ memo[$1] = key
+ }
+
+ elsif String === args[0]
+ envs = {args[0] => args[0]}
+ opts = args[1] || {}
+
+ elsif Array === args[0]
+ envs = args[0].each.with_object({}) { |v, memo|
+ memo[v] = v
+ }
+ opts = args[1] || {}
+ end
+ opts[:split] ||= /\Z/
+
+ o = Optimism.new
+ envs.each { |key, env|
+ key = opts[:case_sensive] ? key : key.downcase
+
+ names = key.split(opts[:split])
+ names[0...-1].each { |name|
+ o[name] = Optimism.new
+ o = o[name]
+ }
+ value = blk ? blk.call(ENV[env]) : ENV[env]
+ o[names[-1]] = value
+ }
+ o = o._root
+ o = wrap_into_namespace(opts[:parent], o) if opts[:parent]
+
+ o
+ end
+
+ # load configuration from string.
+ # @see require_file
+ #
+ # @example
+ #
+ # require_string <<EOF, :parent => 'production'
+ # a.b = 1
+ # c.d = 2
+ # EOF
+ #
+ # @param [String] string
+ # @param [Hash] opts
+ # @option opts [String] :parent
+ # @return [Optimism]
+ def require_string(string, opts={})
+ o = Optimism.eval(string)
+ o = wrap_into_namespace(opts[:parent], o) if opts[:parent]
+
+ o
+ end
+
+ # get configuration from user input.
+ # @ see require_input
+ #
+ # @example
+ #
+ # o = require_input("what's your name?", "my.name", default: "foo")
+ # o.my.name #=> get from user input or "foo"
+ #
+ # @param [String] msg print message to stdin.
+ # @param [String] key
+ # @param [Hash] opts
+ # @option opts [Object] :parent
+ # @option opts [Object] :default use this default if user doesn't input anything.
+ # @return [Optimism]
+ def require_input(msg, key, opts={}, &blk)
+ default = opts[:default] ? "(#{opts[:default]})" : ""
+ print msg+"#{default} "
+ value = gets.strip
+ value = value.empty? ? opts[:default] : value
+ value = blk ? blk.call(value) : value
+
+ o = new_node(key, value)._root
+ o = wrap_into_namespace(opts[:parent], o) if opts[:parent]
+
+ o
+ end
+
+ private
+ def find_file(name, opts={})
+ path = nil
+
+ # ~/.gutenrc
+ if name =~ /^~/
+ file = File.expand_path(name)
+ path = file if File.exists?(file)
+
+ # /absolute/path/to/rc
+ elsif File.absolute_path(name) == name
+ path = name if File.exists?(name)
+
+ # relative/rc
+ else
+ hike = Hike::Trail.new
+ hike.extensions.push ".rb"
+ hike.paths.replace $:
+ path = hike.find(name)
+ end
+
+ path
+ end
+
+ # @example
+ #
+ # o = Optimism[c: 1]
+ # new = wrap_into_namespace('a.b', o)
+ # # => new.a.b.c is 1
+ #
+ def wrap_into_namespace(parent, node)
+ namespace = new_node(parent)
+ namespace << node
+ namespace._root
+ end
+
+ # create a new node by string node.
+ # return last node, not root node, not last value
+ #
+ # @exampe
+ #
+ # new_node('a.b') #=> Rc.a.b
+ # new_node('a.b', 1) #=> Rc.a.b is 1
+ #
+ def new_node(parent, value=Optimism.new)
+ node = Optimism.new
+ nodes = parent.split(".")
+
+ nodes[0...-1].each { |name|
+ node[name] = Optimism.new
+ node = node[name]
+ }
+
+ node[nodes[-1]] = value
+
+ Optimism === value ? value : node
+ end
+ end
+
+ module RequireInstanceMethod
+
+ # a shortcut for Require#require_input
+ # @see Require#require_input
+ #
+ # @example
+ #
+ # o = Optimism do
+ # _.my.age = 1
+ # end
+ # o._require_input("how old are you?", "my.age") # use a default value with 1
+ #
+ def _require_input(msg, key, opts={}, &blk)
+ default = _get(key)
+ self << Optimism.require_input(msg, key, default: default, &blk)
+ self
+ end
+ end
+end
View
2  optimism.gemspec
@@ -15,4 +15,6 @@ a configuration library for Ruby
s.rubyforge_project = "xx"
s.files = `git ls-files`.split("\n")
+
+ s.add_dependency 'hike', '~>1.2.0'
end
View
1  optimism.watchr
@@ -19,4 +19,3 @@ def test path
puts cmd
system cmd
end
-
View
1  spec/data/invalid_syntax.rb
@@ -0,0 +1 @@
+1abc 1
View
2  spec/data/mixin_a.rb
@@ -0,0 +1,2 @@
+a.b = 1
+a.c = 'foo'
View
2  spec/data/mixin_b.rb
@@ -0,0 +1,2 @@
+a.b = 2
+a.d = 'bar'
View
1  spec/data/rc.rb
@@ -0,0 +1 @@
+_.a = 1
View
84 spec/optimism/hash_method_fix_spec.rb
@@ -0,0 +1,84 @@
+require "spec_helper"
+
+describe Optimism do
+
+ describe "#_merge!" do
+ it "works" do
+ o = Optimism.new
+
+ o.b._merge! a: 1
+ o.should == Optimism[b: Optimism[a: 1]]
+
+ o.b._merge! Optimism[a: 2]
+ o.should == Optimism[b: Optimism[a: 2]]
+ end
+
+ #
+ # o.
+ # a.b = 1
+ # a.c = "foo"
+ # b.c = "x"
+ #
+ # o2
+ # a.b = 2
+ # a.d = "bar"
+ #
+ # o << o2
+ # #=>
+ # o.a.b = 2
+ # o.a.c = "foo"
+ # o.a.d = "bar"
+ # o.b.c = "x"
+ it "is deep merge" do
+ o = Optimism do
+ a.b = 1
+ a.c = "foo"
+ b.c = "x"
+ end
+
+ o2 = Optimism do
+ a.b = 2
+ a.d = "bar"
+ end
+
+ o._merge! o2
+ o.should == Optimism[a: Optimism[b: 2, c: "foo", d: "bar"], b: Optimism[c: "x"]]
+ end
+ end
+
+ describe "#_merge" do
+ it "works" do
+ o = Optimism.new
+ new = o._merge a: 1
+ o.should == o
+ new.should == Optimism[a: 1]
+ end
+ end
+
+ describe "#_get" do
+ before(:all) {
+ @o = Optimism do
+ _.a = 1
+ _.b.c = 2
+ end
+ }
+
+ it "works" do
+ @o._get("a").should == 1
+ end
+
+ it "support path" do
+ @o._get("b.c").should == 2
+ end
+
+ it "return nil if path is not exists" do
+ @o._get("c.d").should == nil
+ end
+
+ it "return nil if path is wrong" do
+ @o._get("a.b").should == nil
+ end
+
+
+ end
+end
View
180 spec/optimism/require_spec.rb
@@ -0,0 +1,180 @@
+require "spec_helper"
+
+module Optimism::Require
+ public :find_file, :new_node
+end
+
+describe Optimism::Require do
+ describe ".new_node" do
+ it "works" do
+ o = Optimism.new_node("a.b")
+ o._root.should == Optimism[a: Optimism[b: Optimism.new]]
+ end
+
+ it "call with a value" do
+ o = Optimism.new_node("a.b", 1)
+ o._root.should == Optimism[a: Optimism[b: 1]]
+ end
+ end
+
+ describe ".find_file" do
+ before(:all) {
+ @rc_path = File.join($spec_dir, "data/rc.rb")
+ }
+
+
+ it "finds an absolute path" do
+ Optimism.find_file(@rc_path).should == @rc_path
+ end
+
+ it "finds a relative path" do
+ Optimism.find_file('data/rc').should == @rc_path
+ end
+
+ it "loads a home path" do
+ ENV["HOME"] = $spec_dir
+ Optimism.find_file('~/data/rc.rb').should == File.join(ENV["HOME"], "data/rc.rb")
+ end
+
+ end
+
+ describe ".require_file" do
+ it "works on :parent" do
+ o = Optimism.require("data/rc", :parent => 'a.b')
+ o.should == Optimism[a: Optimism[b: Optimism[a: 1]]]
+ end
+
+ it "works on :mixin with :replace" do
+ o = Optimism.require(%w(data/mixin_a data/mixin_b), :mixin => :replace)
+ o.should == Optimism[a: Optimism[b: 2, c: "foo", d: "bar"]]
+ end
+
+ it "works on :mixin with :ignore" do
+ o = Optimism.require(%w(data/mixin_a data/mixin_b), :mixin => :ignore)
+ o.should == Optimism[a: Optimism[b: 1, c: "foo", d: "bar"]]
+ end
+
+ it "raise InvalidSyntax" do
+ lambda{ Optimism.require("data/invalid_syntax") }.should raise_error(SyntaxError)
+ end
+
+ it "not raise MissingFile by default" do
+ lambda { Optimism.require("data/file_not_exists") }.should_not raise_error(Optimism::MissingFile)
+ end
+
+ it "raise MissingFile with :raise_missing_file" do
+ lambda { Optimism.require("data/file_not_exists", :raise_missing_file => true) }.should raise_error(Optimism::MissingFile)
+ end
+
+
+ end
+
+ describe ".require_env" do
+ before(:all) {
+ ENV["A"] = "1"
+ ENV["B"] = "2"
+ ENV["OPTIMISM_A"] = "1"
+ ENV["OPTIMISM_B_C"] = "2"
+ }
+
+ it "load an environment variable" do
+ o = Optimism.require_env("A")
+ o.should == Optimism[a: "1"]
+ end
+
+ it "with :case_sensive option" do
+ o = Optimism.require_env("A", :case_sensive => true)
+ o.should == Optimism[A: "1"]
+ end
+
+ it "support block, convert value to integer." do
+ o = Optimism.require_env("A") { |a|
+ a.to_i
+ }
+ o.should == Optimism[a: 1]
+ end
+
+ it "load multiplate environment variables at once" do
+ o = Optimism.require_env(%w(A B))
+ o.should == Optimism[a: "1", b: "2"]
+ end
+
+ it "load by pattern" do
+ o = Optimism.require_env(/OPTIMISM_(.*)/)
+ o.should == Optimism[a: "1", b_c: "2"]
+ end
+
+ it "load by pattern, but env not exists" do
+ o = Optimism.require_env(/ENV_NOT_EXISTS__(.)/)
+ o.should == Optimism.new
+ end
+
+ it "load by pattern with :split" do
+ o = Optimism.require_env(/OPTIMISM_(.*)/, :split => '_')
+ o.should == Optimism[a: "1", b: Optimism[c: "2"]]
+ end
+
+ end
+
+ describe ".require_string" do
+ it "works" do
+ o = Optimism.require_string <<-EOF
+ _.a = 1
+ EOF
+ o.should == Optimism[a: 1]
+ end
+ end
+
+ describe ".require_input" do
+ it "works" do
+ module Optimism::Require
+ def gets() "guten\n" end
+ end
+ o = Optimism.require_input("what's your name?", "my.name")
+ o.should == Optimism[my: Optimism[name: "guten"]]
+ end
+
+ it "with :default option" do
+ module Optimism::Require
+ def gets() "\n" end
+ end
+ o = Optimism.require_input("what's your name?", "my.name", default: "foo")
+ o.should == Optimism[my: Optimism[name: "foo"]]
+ end
+
+ it "call with block" do
+ module Optimism::Require
+ def gets() "1\n" end
+ end
+ o = Optimism.require_input("how old are you?", "age") { |age| age.to_i }
+ o.should == Optimism[age: 1]
+ end
+ end
+
+ describe "#_require_input" do
+ it "works" do
+ module Optimism::Require
+ def gets() "fine\n" end
+ end
+
+ o = Optimism.new
+ o.a.b._require_input "how are you?", "status"
+
+ o.a.b.status.should == "fine"
+ end
+
+ it "with default value" do
+ module Optimism::Require
+ def gets() "\n" end
+ end
+
+ o = Optimism do
+ my.status = "well"
+ end
+ o.my._require_input "how are you?", "status"
+
+ o.my.status.should == "well"
+ end
+ end
+
+end
View
53 spec/optimism_spec.rb
@@ -1,6 +1,38 @@
require "spec_helper"
+$:.unshift $spec_dir
+
describe Optimism do
+ it "test" do
+ end
+
+ describe ".convert" do
+ it "works with simple hash data" do
+ Optimism.convert({a: 1}).should == Optimism[a: 1]
+ end
+
+ it "works with compilex hash data" do
+ Optimism.convert({a: 1, b: {c: 1}}).should == Optimism[a: 1, b: Optimism[c: 1]]
+ end
+
+ it "works with simple optimism data" do
+ o = Optimism[a: 1]
+ Optimism.convert(o).should == o
+ end
+
+ it "works with complex hash and optimism data" do
+ data = {
+ a: 1,
+ b: Optimism[c: 2],
+ c: {
+ e: Optimism[d: 3]
+ }
+ }
+ right = Optimism[a: 1, b: Optimism[c: 2], c: Optimism[e: Optimism[d: 3]]]
+ Optimism.convert(data).should == right
+ end
+ end
+
describe ".get" do
it "gets from Hash" do
Optimism.get(a: 1).should == {a: 1}
@@ -16,27 +48,7 @@
Optimism[a:1].should be_an_instance_of Optimism
end
end
- describe ".require" do
- it "raise LoadError when file doesn't exist" do
- lambda{Optimism.require "file/doesnt/exists"}.should raise_error(Optimism::LoadError)
- end
- it "loads an absolute path" do
- Optimism.require(File.join($spec_data_dir, 'rc.rb'))._child == {a: 1}
- end
-
- it "loads a relative path" do
- $: << $spec_data_dir
- Optimism.require('rc')._child == {a: 1}
- Optimism.require('rc.rb')._child == {a: 1}
- end
-
- it "loads a home path" do
- ENV["HOME"] = $spec_data_dir
- Optimism.require('rc.rb')._child == {a: 1}
- end
-
- end
context "access" do
before :all do
@@ -306,4 +318,5 @@
end
end
+
end
View
1  spec/spec_helper.rb
@@ -1,4 +1,3 @@
require "optimism"
$spec_dir = File.dirname(__FILE__)
-$spec_data_dir = File.expand_path('../data', __FILE__)
View
8 spec/test_spec.rb
@@ -2,7 +2,11 @@
describe Optimism do
it 'works' do
- o = Optimism.new
- #pd o.i
+ o = Optimism do
+ _.name = 'a'
+ a.b = 'c'
+ end
+ o.send 'c.b'
+ #pd o
end
end
View
15 test.watchr
@@ -0,0 +1,15 @@
+# lib/**/*.rb
+watch %r~lib/(.*)\.rb~ do |m|
+ test "spec/test_spec.rb"
+end
+
+# spec/**/*_spec.rb
+watch %r~spec/.*_spec\.rb~ do |m|
+ test m[0]
+end
+
+def test path
+ cmd = "rspec #{path}"
+ puts cmd
+ system cmd
+end

2 comments on commit 7890835

@anithri

You are a coding machine! Nice job.

@gutenye
Owner

thanks.

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