mvcli 0.0.1 → 0.0.2

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.
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