outil 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/outil-boostrap +7 -0
- data/lib/outil.rb +108 -0
- data/lib/outil/decorators.rb +30 -0
- data/lib/outil/ocs.rb +24 -0
- data/lib/outil/ocs/config.rb +51 -0
- data/lib/outil/ocs/index.rb +68 -0
- data/lib/outil/ocs/parser.rb +63 -0
- data/lib/outil/ocs/serialize.rb +13 -0
- data/lib/outil/version.rb +3 -0
- data/lib/outil/workspace.rb +35 -0
- data/spec/decorator_spec.rb +28 -0
- data/spec/index_spec.rb +111 -0
- data/spec/outil_spec.rb +33 -0
- data/spec/parser_spec.rb +61 -0
- data/spec/spec_helper.rb +39 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a3cfe1efb43ae4eb0bf954722310c091cfa0fbd3
|
4
|
+
data.tar.gz: 5f00fa7f90c1894982e0f3112c55fbea676e4e0c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: eb6a368e983db65fa663bc7036444a3e1c9faaeafa7e681c3ac229d1289aeabc1a858a1aa9d5aaa619937a2609094425d023276c54ddcbef1a9d90df508b65a9
|
7
|
+
data.tar.gz: 3fdd16515f75d37b7da50785d75ba397c7212bc3423fe0bb3e29d17660db7da2d3ee750b1a0f89b5372922e9d0b72e21d734900d655422a75107ab9ce27ea497
|
data/bin/outil-boostrap
ADDED
data/lib/outil.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'ruby_decorators'
|
3
|
+
require 'parser/current'
|
4
|
+
require 'unparser'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
|
9
|
+
require 'outil/version'
|
10
|
+
require 'outil/decorators'
|
11
|
+
require 'outil/workspace'
|
12
|
+
require 'outil/ocs'
|
13
|
+
require 'outil/ocs/index'
|
14
|
+
require 'outil/ocs/config'
|
15
|
+
require 'outil/ocs/parser'
|
16
|
+
|
17
|
+
module Outil
|
18
|
+
|
19
|
+
def self.index
|
20
|
+
Workspace.ocs.index
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.reset!
|
24
|
+
Workspace.reset!
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.included(base)
|
28
|
+
# Add the decorator class-method logic to the includer
|
29
|
+
# E.G. The client has control over the "use" and "named"
|
30
|
+
# class-level directives.
|
31
|
+
|
32
|
+
base.extend(Inferace)
|
33
|
+
|
34
|
+
# By default, only the Registration decorator
|
35
|
+
# is added, and it's added under the generic :outil namespace
|
36
|
+
|
37
|
+
base.class_eval do
|
38
|
+
use Decorators::Register
|
39
|
+
named :outil
|
40
|
+
end
|
41
|
+
|
42
|
+
# Pull all the AST's in the user index
|
43
|
+
# and define them as methods of the Bucket
|
44
|
+
# module just before the inclusion is done.
|
45
|
+
|
46
|
+
Workspace.ocs.index.all.each do |ast|
|
47
|
+
Outil.module_eval <<-RUBY_EVAL
|
48
|
+
#{Unparser.unparse(ast)}
|
49
|
+
RUBY_EVAL
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module Inferace
|
54
|
+
# BucketInterface is a basically
|
55
|
+
# a module mirror of the RubyDecorators::Interface
|
56
|
+
# class. To avoid adding dependencies, and increasing
|
57
|
+
# the sheer volume of hacks at work here, the Interface
|
58
|
+
# code is essentially copied and pasted here as module
|
59
|
+
# instance variables
|
60
|
+
|
61
|
+
include RubyDecorators
|
62
|
+
|
63
|
+
def self.decorate
|
64
|
+
RubyDecorators::Stack.all << self
|
65
|
+
Workspace.sync
|
66
|
+
end
|
67
|
+
|
68
|
+
def named(name)
|
69
|
+
@name = name.to_s
|
70
|
+
class_eval <<-RUBY_EVAL
|
71
|
+
def self.#{@name}(dcr)
|
72
|
+
if decorators[dcr]
|
73
|
+
self.decorate(decorators[dcr])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
RUBY_EVAL
|
77
|
+
end
|
78
|
+
|
79
|
+
def name
|
80
|
+
@name ||= self.class.name.to_s
|
81
|
+
end
|
82
|
+
|
83
|
+
def decorators
|
84
|
+
@decorators ||= {}
|
85
|
+
end
|
86
|
+
|
87
|
+
def use *decs
|
88
|
+
append = Proc.new do |dec|
|
89
|
+
fmt = dec.name.split('::').last.
|
90
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
91
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
92
|
+
tr("-", "_").
|
93
|
+
downcase.
|
94
|
+
to_sym
|
95
|
+
self.decorators[fmt] = dec
|
96
|
+
end
|
97
|
+
decs.each &append
|
98
|
+
end
|
99
|
+
|
100
|
+
def registered_methods
|
101
|
+
@registered_methods ||= {}
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.registered_decorators
|
105
|
+
@registered_decorators ||= {}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Outil
|
2
|
+
module Decorators
|
3
|
+
|
4
|
+
class Register < RubyDecorators::Decorator
|
5
|
+
|
6
|
+
def call(this, *args, &blk)
|
7
|
+
Outil::Workspace.scan *this.source_location << this.name
|
8
|
+
this.call(*args, &blk)
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
class NameSpace
|
14
|
+
|
15
|
+
def initialize(namespace)
|
16
|
+
@namespace = namespace
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(this, *args, &blk)
|
20
|
+
# TODO
|
21
|
+
# Intended behavior is to register the decorated
|
22
|
+
# method under a given namespace, so you can
|
23
|
+
# have two methods named the same thing, etc.
|
24
|
+
this.call(*args, &blk)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
data/lib/outil/ocs.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module Outil
|
2
|
+
|
3
|
+
module OCS
|
4
|
+
|
5
|
+
# Object Control System
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def config(params={})
|
10
|
+
@config ||= Config.new(params)
|
11
|
+
end
|
12
|
+
|
13
|
+
def bootstrap options={}
|
14
|
+
options.merge! Config.new().params
|
15
|
+
Dir.mkdir(options[:index]) unless Dir.exists?(options[:index])
|
16
|
+
File.open(options.delete(:path), 'w+') do |f|
|
17
|
+
f.write options.to_yaml
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Outil
|
2
|
+
module OCS
|
3
|
+
class Config
|
4
|
+
|
5
|
+
INDEX_PATH = '.outil'
|
6
|
+
CONFIG_PATH = '.outil.rc'
|
7
|
+
|
8
|
+
def self.home_path
|
9
|
+
@home_path ||= File.expand_path(
|
10
|
+
File.expand_path(ENV['HOME'] || '~'))
|
11
|
+
end
|
12
|
+
|
13
|
+
attr :params
|
14
|
+
|
15
|
+
def initialize(params={})
|
16
|
+
@params = params
|
17
|
+
infer = Proc.new do |key, const|
|
18
|
+
@params[key] = "#{self.class.home_path}/#{const}"
|
19
|
+
end
|
20
|
+
infer.call(:index, INDEX_PATH)
|
21
|
+
infer.call(:path, CONFIG_PATH)
|
22
|
+
end
|
23
|
+
|
24
|
+
def options
|
25
|
+
@options ||= (
|
26
|
+
unless File.exists?(@params[:path])
|
27
|
+
raise StandardError "Could not locate your Outil Config File"
|
28
|
+
end
|
29
|
+
indifference = Proc.new do |hash, x|
|
30
|
+
hash[x.first] = x.last
|
31
|
+
hash[x.first.to_sym] = x.last
|
32
|
+
hash
|
33
|
+
end
|
34
|
+
YAML.load_file(@params[:path])
|
35
|
+
.inject(Hash.new, &indifference)
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def index
|
40
|
+
@index ||= (
|
41
|
+
unless options[:index]
|
42
|
+
raise StandardError "Could not locate your Outil Index Path"
|
43
|
+
end
|
44
|
+
Index.new(:path => options[:index])
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Outil
|
2
|
+
module OCS
|
3
|
+
class Index
|
4
|
+
|
5
|
+
attr :path
|
6
|
+
|
7
|
+
def initialize params={}
|
8
|
+
@path = params[:path]
|
9
|
+
end
|
10
|
+
|
11
|
+
def index_path
|
12
|
+
@index_path ||= "#{@path}/index"
|
13
|
+
end
|
14
|
+
|
15
|
+
def append name, ast
|
16
|
+
write_serialize name, ast
|
17
|
+
update_index name
|
18
|
+
end
|
19
|
+
|
20
|
+
def write_serialize name, ast
|
21
|
+
File.open("#{@path}/#{name}.ast", 'w+') do |file|
|
22
|
+
file.write ast.to_yaml
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def indexed_names
|
27
|
+
File.open(index_path, 'r') do |f|
|
28
|
+
f.read.split(/\n/)
|
29
|
+
end.map(&:strip)
|
30
|
+
end
|
31
|
+
|
32
|
+
def update_index name
|
33
|
+
return if indexed_names.include?(name.to_s)
|
34
|
+
File.open(index_path, 'a') do |file|
|
35
|
+
file.write name.to_s << "\n"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def read(name)
|
40
|
+
File.open("#{@path}/#{name}.ast", 'r') do |file|
|
41
|
+
YAML.load(file.read)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def all
|
46
|
+
indexed_names.map do |name|
|
47
|
+
read name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def read_exec(name)
|
52
|
+
instance_eval <<-RUBY_EVAL
|
53
|
+
#{Unparser.unparse(read(name))}
|
54
|
+
RUBY_EVAL
|
55
|
+
end
|
56
|
+
|
57
|
+
def hard_reset!
|
58
|
+
Dir["#{@path}/*.ast"].each do |path|
|
59
|
+
File.delete path
|
60
|
+
end
|
61
|
+
File.open(index_path, 'w+') do |file|
|
62
|
+
file.write String.new
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Outil
|
2
|
+
module OCS
|
3
|
+
class ObjectParser
|
4
|
+
|
5
|
+
attr :name, :path, :found
|
6
|
+
|
7
|
+
def initialize(path, name)
|
8
|
+
@path = path
|
9
|
+
@name = name
|
10
|
+
@found = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def node
|
14
|
+
@node ||= Parser::CurrentRuby.parse(
|
15
|
+
File.open(@path, 'r') do |f|
|
16
|
+
f.read
|
17
|
+
end
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def find
|
22
|
+
return @found if @found
|
23
|
+
set_and_stop = Proc.new do |node|
|
24
|
+
return @found = node
|
25
|
+
end
|
26
|
+
traverse = Proc.new do |node|
|
27
|
+
# if we're not at a node, we can move on
|
28
|
+
next unless node.is_a?(Parser::AST::Node)
|
29
|
+
# unless we're at a method definition
|
30
|
+
# we're probably in a begin block, a class, or module
|
31
|
+
# in which case traverse the children of the current node
|
32
|
+
node.children.each &traverse unless [:defs, :def].include?(node.type)
|
33
|
+
# bottom-level node interrogation...
|
34
|
+
case node.type
|
35
|
+
when :defs
|
36
|
+
# class methods
|
37
|
+
set_and_stop.call(node) if node.children[1] == name
|
38
|
+
next
|
39
|
+
when :def
|
40
|
+
# instance method
|
41
|
+
set_and_stop.call(node) if node.children.first == name
|
42
|
+
next
|
43
|
+
else
|
44
|
+
# other kind of object
|
45
|
+
if node.is_a?(Parser::AST::Node)
|
46
|
+
# another parent node
|
47
|
+
node.children.each &traverse
|
48
|
+
else
|
49
|
+
# the bottom of a node
|
50
|
+
next
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
begin
|
55
|
+
traverse.call(node)
|
56
|
+
rescue
|
57
|
+
false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Outil
|
2
|
+
module OCS
|
3
|
+
class Serialize
|
4
|
+
# TODO: Move the Index away from YAML and toward Binary
|
5
|
+
# I want to get away from using YAML
|
6
|
+
# dumps AST Node class as a serialization method
|
7
|
+
# and the nature of AST's themselves make
|
8
|
+
# them really friendly to binary serialization.
|
9
|
+
# In theory anyway.
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Outil
|
2
|
+
|
3
|
+
class Workspace
|
4
|
+
|
5
|
+
def self.ocs
|
6
|
+
@ocs ||= OCS::Config.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.reset!
|
10
|
+
@references = []
|
11
|
+
@asts = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.references
|
15
|
+
@references ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.asts
|
19
|
+
@asts ||= {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.scan path, lineno, name
|
23
|
+
references << [path, lineno, name]
|
24
|
+
asts[name] = OCS::ObjectParser.new(path, name).find
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.sync
|
28
|
+
asts.each_pair do |name, tree|
|
29
|
+
ocs.index.append name, tree
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Outil::Decorators do
|
4
|
+
|
5
|
+
describe Outil::Decorators::Register do
|
6
|
+
|
7
|
+
describe "call" do
|
8
|
+
|
9
|
+
it "should update workspace references" do
|
10
|
+
Outil.reset!
|
11
|
+
class DummyInterfaceTwo < RubyDecorators::Interface
|
12
|
+
use Outil::Decorators::Register
|
13
|
+
named :outil
|
14
|
+
|
15
|
+
outil :register
|
16
|
+
def baz
|
17
|
+
'bar'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
DummyInterfaceTwo.new.baz
|
21
|
+
target = [[__FILE__, 18, :baz]]
|
22
|
+
Outil::Workspace.references.should eq target
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/spec/index_spec.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
4
|
+
|
5
|
+
describe Outil::OCS::Index do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@config = Outil::OCS::Config.new
|
9
|
+
@index = @config.index
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "initialize" do
|
13
|
+
it "should set path instance variable" do
|
14
|
+
@index.path.should eq(@config.params[:index])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "index_path" do
|
19
|
+
it "should return the path with index at the end" do
|
20
|
+
@index.index_path.should eq(@config.params[:index] + "/index")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "write_serialize" do
|
25
|
+
it "should write a file named for the method to the index" do
|
26
|
+
@index.write_serialize(:hello, build_target_ast)
|
27
|
+
Dir["#{@index.path}/*.ast"].map do |path|
|
28
|
+
File.basename path
|
29
|
+
end.include?("hello.ast")
|
30
|
+
.should eq(true)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "indexed_names" do
|
35
|
+
it "return a list of registered methods names" do
|
36
|
+
@index.write_serialize(:hello, build_target_ast)
|
37
|
+
@index.indexed_names.include?("hello").should eq(true)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "update_index" do
|
42
|
+
it "adds a method name to the end of the index file" do
|
43
|
+
@index.write_serialize(:dummy, build_target_ast(:dummy))
|
44
|
+
@index.update_index :dummy
|
45
|
+
@index.indexed_names.include?('dummy').should eq(true)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "read" do
|
50
|
+
it "return an ast for the specified method" do
|
51
|
+
@index.write_serialize(:dummy, build_target_ast(:dummy))
|
52
|
+
@index.update_index :dummy
|
53
|
+
@index.read(:dummy).is_a?(Parser::AST::Node).should eq(true)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "append" do
|
58
|
+
|
59
|
+
before do
|
60
|
+
@index.append :baz, build_target_ast(:baz)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should write a file named for the method to the index" do
|
64
|
+
@index.indexed_names.include?('baz').should eq(true)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "adds a method name to the end of the index file" do
|
68
|
+
Dir["#{@index.path}/*.ast"].map do |path|
|
69
|
+
File.basename path
|
70
|
+
end.include?("baz.ast")
|
71
|
+
.should eq(true)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "all" do
|
76
|
+
it "should return an array of asts" do
|
77
|
+
all_ast = Proc.new do |response|
|
78
|
+
response.map {|x| x.is_a?(Parser::AST::Node)}
|
79
|
+
.uniq == [true]
|
80
|
+
end
|
81
|
+
all_ast.call(@index.all)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "read_exec" do
|
86
|
+
it "should produce a method" do
|
87
|
+
@index.read_exec(:hello)
|
88
|
+
@index.send(:hello).should eq('hello')
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "update_index" do
|
93
|
+
it "should append method names to the index file" do
|
94
|
+
# initialize the interface a bunch and call the
|
95
|
+
# registered methods, to make sure they don't keep
|
96
|
+
10.times do
|
97
|
+
DummyInterface.new.hello
|
98
|
+
DummyInterface.new.goodbye
|
99
|
+
end
|
100
|
+
target = ['hello', 'dummy']
|
101
|
+
include_all = Proc.new do |a,b|
|
102
|
+
a.map {|x| b.include?(x) }.uniq == [true]
|
103
|
+
end
|
104
|
+
indexed = @index.indexed_names
|
105
|
+
include_all.call(target,
|
106
|
+
indexed)
|
107
|
+
.should eq(true)
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/spec/outil_spec.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
4
|
+
|
5
|
+
describe Outil do
|
6
|
+
|
7
|
+
before do
|
8
|
+
|
9
|
+
class MyClient
|
10
|
+
include Outil
|
11
|
+
|
12
|
+
outil :register
|
13
|
+
def foo
|
14
|
+
'bar'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Outil::Workspace.sync
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "included" do
|
22
|
+
it "should include registered methods" do
|
23
|
+
client = MyClient.new
|
24
|
+
client.hello.should eq('hello')
|
25
|
+
client.goodbye.should eq('goodbye')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should allow registration for its own methods" do
|
29
|
+
Outil::Workspace.ocs.index.indexed_names.include?('foo').should eq(true)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Outil::OCS::ObjectParser do
|
4
|
+
|
5
|
+
before do
|
6
|
+
Outil.reset!
|
7
|
+
DummyInterface.new.hello
|
8
|
+
@target = build_target_ast
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
Outil.reset!
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "append" do
|
16
|
+
it "append ast to workspace" do
|
17
|
+
Outil::Workspace.asts[:hello].should eq(@target)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "initialize" do
|
22
|
+
before do
|
23
|
+
@parser = Outil::OCS::ObjectParser.new(__FILE__, :hello)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should set path" do
|
27
|
+
@parser.path.should eq(__FILE__)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should set name" do
|
31
|
+
@parser.name.should eq(:hello)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "node" do
|
36
|
+
before do
|
37
|
+
@parser = build_generic_parser
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return an ast" do
|
41
|
+
@parser.node.is_a?(Parser::AST::Node).should eq(true)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "find" do
|
46
|
+
before do
|
47
|
+
@parser = build_generic_parser
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should locate the named method in the parse tree" do
|
51
|
+
@parser.find.should eq(build_target_ast)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should set the found instance variable" do
|
55
|
+
@parser.find
|
56
|
+
@parser.found.should eq(build_target_ast)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path('../../lib/outil', __FILE__)
|
2
|
+
require 'rspec'
|
3
|
+
require 'rspec/expectations'
|
4
|
+
|
5
|
+
def build_target_ast(name=false)
|
6
|
+
name = name ? name : :hello
|
7
|
+
Parser::AST::Node.new(:def,
|
8
|
+
children=[name,
|
9
|
+
Parser::AST::Node.new(:args),
|
10
|
+
Parser::AST::Node.new(:str,
|
11
|
+
children=["hello"])])
|
12
|
+
end
|
13
|
+
|
14
|
+
def build_generic_parser
|
15
|
+
Outil::OCS::ObjectParser
|
16
|
+
.new("#{File.dirname(__FILE__)}/spec_helper.rb",
|
17
|
+
:hello)
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
class DummyInterface < RubyDecorators::Interface
|
22
|
+
use Outil::Decorators::Register
|
23
|
+
named :outil
|
24
|
+
|
25
|
+
outil :register
|
26
|
+
def hello
|
27
|
+
'hello'
|
28
|
+
end
|
29
|
+
|
30
|
+
outil :register
|
31
|
+
def goodbye
|
32
|
+
'goodbye'
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
DummyInterface.new.hello
|
38
|
+
|
39
|
+
Outil::Workspace.sync
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: outil
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matt Aliabadi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: parser
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.0.beta5
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.0.0.beta5
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: unparser
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Outil is a library for storing and importing reusable code
|
56
|
+
email:
|
57
|
+
- mattmaliabadi@gmail.com
|
58
|
+
executables:
|
59
|
+
- outil-boostrap
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- bin/outil-boostrap
|
64
|
+
- lib/outil/decorators.rb
|
65
|
+
- lib/outil/ocs/config.rb
|
66
|
+
- lib/outil/ocs/index.rb
|
67
|
+
- lib/outil/ocs/parser.rb
|
68
|
+
- lib/outil/ocs/serialize.rb
|
69
|
+
- lib/outil/ocs.rb
|
70
|
+
- lib/outil/version.rb
|
71
|
+
- lib/outil/workspace.rb
|
72
|
+
- lib/outil.rb
|
73
|
+
- spec/decorator_spec.rb
|
74
|
+
- spec/index_spec.rb
|
75
|
+
- spec/outil_spec.rb
|
76
|
+
- spec/parser_spec.rb
|
77
|
+
- spec/spec_helper.rb
|
78
|
+
homepage: http://www.github.com/maliabadi/outil
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata: {}
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 2.0.6
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: Stores persistently available utility functions
|
102
|
+
test_files: []
|