mvcli 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2af39b708e5b71d002d6734923412e067411c115
4
- data.tar.gz: dcdf57432aeb3712a27878088ae4a527728b9ac2
3
+ metadata.gz: d38bca7cf98c3cad670fe5df941fd17c8d8cd267
4
+ data.tar.gz: a1438f4ab557e0f083b9eca8875b67a2b9b12a27
5
5
  SHA512:
6
- metadata.gz: dceaaf28dae8821938e47b2c528330e6cacf7abe51bfddadf0ef94c0b4d201659e55bcf52188280d88fe3f92d01728adb1e2014bc048e78aae49d795f61e3e83
7
- data.tar.gz: 4b6586b4eb3b18213257b23122114d66800419d1a1940b79c4c39512ffa33e87800a04feb7610315815f7d6e1187c591e1dc3f54ada6d70c80ac0aa3fecd1a86
6
+ metadata.gz: b707863564e785f0fe67fe47712a2ba416214708a4ae6fce7d9500e5d5347b6c2bc0b2112186bade3fda1baf1b7f1426c2eb0199189615e59d2b90e3b3969dd4
7
+ data.tar.gz: 1add93e30613c13ba50b798543e76975df840a4f4b563cb83af8988118848994fdedfdd8e08c2772cc39e3f2e95f2a6864e074212bd02c5e7033fc9f30ded21d
data/lib/mvcli/actions.rb CHANGED
@@ -1,8 +1,11 @@
1
+ require_relative "loader"
2
+ require_relative "renderer"
3
+
1
4
  module MVCLI
2
5
  class Actions
3
- def initialize(loader, renderer)
4
- @loader = loader
5
- @renderer = renderer
6
+ def initialize(root, loader = nil, renderer = nil)
7
+ @loader = loader || Loader.new(root)
8
+ @renderer = renderer || Renderer.new(root)
6
9
  end
7
10
 
8
11
  def [](key)
@@ -20,10 +23,10 @@ module MVCLI
20
23
 
21
24
  def call(command)
22
25
  controller = @loader.load :controller, @controller
23
- fail LoadError, "no such controller: #{@controller}" unless controller
24
26
  context = controller.send @method
25
27
  path = [@controller, @method].join('/')
26
28
  @renderer.render command.output, path, context
29
+ return 0
27
30
  end
28
31
  end
29
32
  end
data/lib/mvcli/app.rb CHANGED
@@ -1,23 +1,27 @@
1
1
  require_relative "middleware"
2
2
  require_relative "command"
3
+ require_relative "actions"
3
4
  require_relative "router"
4
5
 
5
6
  module MVCLI
6
7
  class App
7
-
8
8
  def initialize
9
- @middleware = Middleware.new
10
- @middleware << Router.new
9
+ @router = Router.new Actions.new root
10
+ @router.instance_eval route_file.read, route_file.to_s, 1
11
11
  end
12
12
 
13
13
  def call(command)
14
- @middleware.call command
14
+ @router.call command
15
15
  end
16
16
 
17
17
  def root
18
18
  self.class.root or fail "Invalid App: undefined application root directory"
19
19
  end
20
20
 
21
+ def route_file
22
+ root.join 'app/routes.rb'
23
+ end
24
+
21
25
  class << self
22
26
  attr_accessor :root
23
27
  end
data/lib/mvcli/erb.rb ADDED
@@ -0,0 +1,40 @@
1
+ require "erb"
2
+
3
+ module MVCLI
4
+ class ERB
5
+ def initialize
6
+ @compiler = ::ERB::Compiler.new("<>")
7
+ @compiler.pre_cmd = [""]
8
+ @compiler.put_cmd = "@_erbout <<"
9
+ @compiler.insert_cmd = "@_erbout <<"
10
+ @compiler.post_cmd = ["nil"]
11
+ end
12
+
13
+ def compile(string, filename = '(erb)')
14
+ code, enc = @compiler.compile string
15
+ Template.new code, enc, filename
16
+ end
17
+
18
+ class Template
19
+ def initialize(code, enc, filename)
20
+ @code, @enc, @filename = code, enc, filename
21
+ end
22
+
23
+ def call(context, output)
24
+ binding = context.instance_eval do
25
+ @_erbout = output
26
+ Kernel.binding
27
+ end
28
+ eval @code, binding, @filename, 1
29
+ ensure
30
+ context.remove_instance_variable(:@_erbout)
31
+ end
32
+
33
+ def to_proc
34
+ proc do |context, output|
35
+ call context, output
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,15 @@
1
+ module MVCLI
2
+ class Loader
3
+ def initialize(path)
4
+ @path = path
5
+ end
6
+
7
+ def load(type, name)
8
+ pathname = "#{name}_#{type}"
9
+ filename = File.join(@path, "app/#{type}s", pathname)
10
+ require filename
11
+ classname = pathname.capitalize.gsub(/_(\w)/) {|m| m[1].upcase}
12
+ Object.const_get(classname).new
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require 'mvcli/erb'
2
+
3
+ module MVCLI
4
+ class Renderer
5
+ def initialize(root)
6
+ @root = root
7
+ end
8
+
9
+ def render(output, path, context)
10
+ filename = @root.join('app/views', path + '.txt.erb').to_s
11
+ compiler = MVCLI::ERB.new
12
+ template = compiler.compile File.read(filename), filename
13
+ template.call(context, output)
14
+ end
15
+ end
16
+ end
data/lib/mvcli/router.rb CHANGED
@@ -7,28 +7,39 @@ module MVCLI
7
7
 
8
8
  def initialize(actions = nil)
9
9
  @actions = actions || Map.new
10
- @root = Map.new
10
+ @routes = []
11
11
  end
12
12
 
13
- def root(options = {})
14
- action = options[:to] or fail InvalidRoute, "root routes must specify an action with ':to =>' E.g. root :to => 'foo#bar'"
15
- verbs = [options[:via] || :help].flatten
16
- verbs.each do |verb|
17
- @root[verb] = action
18
- end
13
+ def match(options)
14
+ pattern, action = options.first
15
+ options.delete pattern
16
+ @routes << Route.new(pattern, @actions, action, options)
19
17
  end
20
18
 
21
19
  def call(command)
22
- verb = command.argv.first || 'help'
23
- path = command.argv.slice(1..-1) || []
24
- if path.empty?
25
- if action_name = @root[verb]
26
- if action = @actions[action_name]
27
- return action.call command
28
- end
20
+ if route = @routes.find {|r| r.matches? command}
21
+ return route.call command
22
+ end
23
+ fail RoutingError, "no route matches '#{command.argv.join ' '}'"
24
+ end
25
+
26
+ class Route
27
+ def initialize(pattern, actions, action, options = {})
28
+ @pattern, @actions, @action, @options = pattern.to_s, actions, action, options
29
+ end
30
+
31
+ def matches?(command)
32
+ segments = @pattern.split /\s+/
33
+ segments.each_with_index do |s, i|
34
+ return false unless command.argv[i] && s.to_s == command.argv[i]
29
35
  end
36
+ return true
37
+ end
38
+
39
+ def call(command)
40
+ action = @actions[@action] or fail "no action found for #{@action}"
41
+ action.call command
30
42
  end
31
- fail RoutingError, "#{path.join(':')} does not respond to #{verb}"
32
43
  end
33
44
  end
34
45
  end
data/lib/mvcli/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module MVCLI
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -4,11 +4,10 @@ require "mvcli/actions"
4
4
  describe "MVCLI::Actions" do
5
5
  Given(:loader) {mock(:Loader)}
6
6
  Given(:renderer) {mock(:Renderer, :render => true)}
7
- Given(:actions) {MVCLI::Actions.new loader, renderer}
7
+ Given(:actions) {MVCLI::Actions.new '/root', loader, renderer}
8
8
 
9
9
  context "when the loader cannot find an appropriate controller" do
10
- Given {loader.stub(:load)}
11
-
10
+ Given {loader.stub(:load) {fail LoadError}}
12
11
  When(:action) {actions['foo']}
13
12
  Then {action.should_not be_nil}
14
13
 
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+ require "mvcli/erb"
3
+
4
+ describe "MVCLI::ERB" do
5
+ Given(:erb) {MVCLI::ERB.new}
6
+ context "when I compile a template" do
7
+ Given(:output) {""}
8
+ Given(:template) {erb.compile "name: <%= name %>"}
9
+ context "and call it with a context" do
10
+ When {template.call mock(:Context, :name => 'Charles'), output}
11
+ Then {output.should eql "name: Charles"}
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+ require "mvcli/loader"
3
+
4
+ describe "MVCLI::Loader" do
5
+
6
+ Given {class ::TotallyAwesomeController; end}
7
+ Given(:loader) {MVCLI::Loader.new '/path/to/app'}
8
+ Given {loader.stub(:require) {true}}
9
+ context "loading a controller in the global namespace" do
10
+ When(:controller){loader.load :controller, 'totally_awesome'}
11
+ Then {controller.should be_instance_of TotallyAwesomeController}
12
+ end
13
+ end
@@ -5,53 +5,31 @@ describe "MVCLI::Router" do
5
5
  Given(:Router) {MVCLI::Router}
6
6
  Given(:actions) {mock(:Actions)}
7
7
  Given(:router) {self.Router.new actions}
8
+ Given {actions.stub(:[]) {|action| @action = action; ->(command) {@command = command}}}
9
+
8
10
 
9
11
  context "without any routes" do
10
12
  When(:result) {invoke}
11
13
  Then {result.should have_failed self.Router::RoutingError}
12
14
  end
13
15
 
14
- context "when an invalid root is mapped" do
15
- When(:result) {router.root :wat => :tf?}
16
- Then {result.should have_failed}
17
- end
18
-
19
- context "with its root mapped to a single verb" do
20
- Given do
21
- actions.stub(:[]).with('logins#create') do
22
- proc do |command|
23
- @login = command
24
- end
25
- end
26
- end
27
- Given {router.root :to => 'logins#create', :via => :login}
16
+ context "with a route matched to an action" do
17
+ Given {router.match 'login' => 'logins#create'}
28
18
  When {invoke 'login'}
29
- Then {@login.argv.should eql ['login']}
19
+ Then {@action.should eql 'logins#create'}
20
+ And {@command.should_not be_nil}
21
+ Then {@command.argv.should eql ['login']}
22
+ end
30
23
 
31
- context "when a command comes in for an unmapped verb" do
32
- When(:result) {invoke 'fwiff'}
33
- Then {result.should have_failed self.Router::RoutingError}
34
- end
35
- context "and a second verb is mapped to the the root" do
36
- Given do
37
- actions.stub(:[]).with('logins#destroy') {proc {|c| @logout = c}}
38
- end
39
- Given {router.root :to => 'logins#destroy', :via => :logout}
40
- context "when I access via the original verb" do
41
- Given {invoke 'logout' }
42
- Then {@logout.should_not be_nil}
43
- And {@logout.argv.should eql ['logout']}
44
- end
45
- end
24
+ context "with a route matched to a block" do
25
+ Given {router.match bam: ->(command) {@command = command}}
26
+ When {invoke 'bam'}
27
+ Then {@command.argv.should eql ['bam']}
46
28
  end
47
29
 
48
- context "with its root mapped without a specific verb" do
49
- Given do
50
- actions.stub(:[]).with('something#show') {proc {|c|@something = c}}
51
- end
52
- Given {router.root :to => 'something#show'}
53
- When {invoke 'help'}
54
- Then {@something.argv.should eql ['help']}
30
+ context "with a route with dynamic segments" do
31
+ Given {router.match 'show loadbalancer :name' => 'loadbalancers#show'}
32
+ When(:result) {invoke 'show loadbalancer 6'}
55
33
  end
56
34
 
57
35
  def invoke(*args)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mvcli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Lowell
@@ -29,7 +29,7 @@ cert_chain:
29
29
  UgImJlChAzCoDP9zi9tdm6jAr7ttF25R9PPYr11ILb7dYe3qUzlNlM6zJx/nb31b
30
30
  IhdyRVup4qLcqYSTPsm6u7VA
31
31
  -----END CERTIFICATE-----
32
- date: 2013-05-20 00:00:00.000000000 Z
32
+ date: 2013-05-22 00:00:00.000000000 Z
33
33
  dependencies:
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: map
@@ -63,11 +63,16 @@ files:
63
63
  - lib/mvcli/actions.rb
64
64
  - lib/mvcli/app.rb
65
65
  - lib/mvcli/command.rb
66
+ - lib/mvcli/erb.rb
67
+ - lib/mvcli/loader.rb
66
68
  - lib/mvcli/middleware.rb
69
+ - lib/mvcli/renderer.rb
67
70
  - lib/mvcli/router.rb
68
71
  - lib/mvcli/version.rb
69
72
  - mvcli.gemspec
70
73
  - spec/mvcli/actions_spec.rb
74
+ - spec/mvcli/erb_spec.rb
75
+ - spec/mvcli/loader_spec.rb
71
76
  - spec/mvcli/middleware_spec.rb
72
77
  - spec/mvcli/router_spec.rb
73
78
  - spec/spec_helper.rb
@@ -97,6 +102,8 @@ specification_version: 4
97
102
  summary: Local Apps. Remote Apps. They're all at your fingertips
98
103
  test_files:
99
104
  - spec/mvcli/actions_spec.rb
105
+ - spec/mvcli/erb_spec.rb
106
+ - spec/mvcli/loader_spec.rb
100
107
  - spec/mvcli/middleware_spec.rb
101
108
  - spec/mvcli/router_spec.rb
102
109
  - spec/spec_helper.rb