nyanko 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/Gemfile +25 -0
  4. data/MIT-LICENSE +22 -0
  5. data/README.md +105 -0
  6. data/Rakefile +1 -0
  7. data/lib/nyanko/active_if.rb +57 -0
  8. data/lib/nyanko/config.rb +13 -0
  9. data/lib/nyanko/controller.rb +23 -0
  10. data/lib/nyanko/function.rb +50 -0
  11. data/lib/nyanko/helper.rb +29 -0
  12. data/lib/nyanko/invoker/function_finder.rb +48 -0
  13. data/lib/nyanko/invoker/options.rb +69 -0
  14. data/lib/nyanko/invoker.rb +68 -0
  15. data/lib/nyanko/loader.rb +59 -0
  16. data/lib/nyanko/railtie.rb +13 -0
  17. data/lib/nyanko/unit/extender/active_record_class_methods.rb +56 -0
  18. data/lib/nyanko/unit/extender/extension.rb +51 -0
  19. data/lib/nyanko/unit/extender.rb +21 -0
  20. data/lib/nyanko/unit/scope_finder.rb +41 -0
  21. data/lib/nyanko/unit.rb +86 -0
  22. data/lib/nyanko/unit_proxy.rb +30 -0
  23. data/lib/nyanko/unit_proxy_provider.rb +21 -0
  24. data/lib/nyanko/version.rb +3 -0
  25. data/lib/nyanko.rb +16 -0
  26. data/nyanko.gemspec +29 -0
  27. data/spec/dummy/README.rdoc +261 -0
  28. data/spec/dummy/Rakefile +7 -0
  29. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  30. data/spec/dummy/app/assets/stylesheets/application.css +14 -0
  31. data/spec/dummy/app/assets/stylesheets/main.scss +21 -0
  32. data/spec/dummy/app/assets/stylesheets/reset.scss +14 -0
  33. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  34. data/spec/dummy/app/controllers/entries_controller.rb +33 -0
  35. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  36. data/spec/dummy/app/mailers/.gitkeep +0 -0
  37. data/spec/dummy/app/models/.gitkeep +0 -0
  38. data/spec/dummy/app/models/entry.rb +3 -0
  39. data/spec/dummy/app/units/entry_deletion/entry_deletion.rb +37 -0
  40. data/spec/dummy/app/units/entry_deletion/views/_delete_link.html.slim +1 -0
  41. data/spec/dummy/app/views/entries/edit.html.slim +14 -0
  42. data/spec/dummy/app/views/entries/index.html.slim +5 -0
  43. data/spec/dummy/app/views/entries/show.html.slim +8 -0
  44. data/spec/dummy/app/views/layouts/application.html.slim +16 -0
  45. data/spec/dummy/config/application.rb +68 -0
  46. data/spec/dummy/config/boot.rb +10 -0
  47. data/spec/dummy/config/database.yml +25 -0
  48. data/spec/dummy/config/environment.rb +5 -0
  49. data/spec/dummy/config/environments/development.rb +37 -0
  50. data/spec/dummy/config/environments/production.rb +67 -0
  51. data/spec/dummy/config/environments/test.rb +37 -0
  52. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  53. data/spec/dummy/config/initializers/inflections.rb +15 -0
  54. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  55. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  56. data/spec/dummy/config/initializers/session_store.rb +8 -0
  57. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  58. data/spec/dummy/config/locales/en.yml +5 -0
  59. data/spec/dummy/config/routes.rb +5 -0
  60. data/spec/dummy/config.ru +4 -0
  61. data/spec/dummy/db/migrate/20130127170331_create_entries.rb +11 -0
  62. data/spec/dummy/db/schema.rb +24 -0
  63. data/spec/dummy/lib/assets/.gitkeep +0 -0
  64. data/spec/dummy/log/.gitkeep +0 -0
  65. data/spec/dummy/public/404.html +26 -0
  66. data/spec/dummy/public/422.html +26 -0
  67. data/spec/dummy/public/500.html +25 -0
  68. data/spec/dummy/public/favicon.ico +0 -0
  69. data/spec/dummy/script/rails +6 -0
  70. data/spec/fixtures/units/example_unit/example_unit.rb +53 -0
  71. data/spec/fixtures/units/inactive_unit/inactive_unit.rb +11 -0
  72. data/spec/nyanko/controller_spec.rb +39 -0
  73. data/spec/nyanko/function_spec.rb +40 -0
  74. data/spec/nyanko/helper_spec.rb +26 -0
  75. data/spec/nyanko/invoker_spec.rb +116 -0
  76. data/spec/nyanko/loader_spec.rb +43 -0
  77. data/spec/nyanko/unit/extender_spec.rb +40 -0
  78. data/spec/nyanko/unit/scope_finder_spec.rb +37 -0
  79. data/spec/nyanko/unit_proxy_provider_spec.rb +40 -0
  80. data/spec/nyanko/unit_proxy_spec.rb +23 -0
  81. data/spec/nyanko/unit_spec.rb +169 -0
  82. data/spec/spec_helper.rb +21 -0
  83. metadata +320 -0
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+
3
+ module Nyanko
4
+ describe Controller do
5
+ describe ".unit_action" do
6
+ let(:controller_class) do
7
+ Class.new(ActionController::Base) do
8
+ include Nyanko::Controller
9
+ unit_action(:example_unit, :test)
10
+ unit_action(:example_unit, :foo, :bar)
11
+ unit_action(:example_unit, :error)
12
+
13
+ def head(code)
14
+ "Bad Request #{code}"
15
+ end
16
+ end
17
+ end
18
+
19
+ let(:controller) do
20
+ controller_class.new
21
+ end
22
+
23
+ it "defines an action to invoke unit function" do
24
+ controller.test.should == "test"
25
+ end
26
+
27
+ it "defines 2 actions at one line" do
28
+ controller.foo.should == "foo"
29
+ controller.bar.should == "bar"
30
+ end
31
+
32
+ context "when invoke is fallen back" do
33
+ it "halts with 400 status code" do
34
+ controller.error.should == "Bad Request 400"
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ module Nyanko
4
+ describe Function do
5
+ let(:unit) do
6
+ Loader.load(:example_unit)
7
+ end
8
+
9
+ let(:context) do
10
+ Class.new(ActionView::Base) do
11
+ include Nyanko::Invoker
12
+
13
+ def current_unit
14
+ units.last
15
+ end
16
+
17
+ def units
18
+ @units ||= []
19
+ end
20
+
21
+ def path
22
+ view_paths.first.to_s
23
+ end
24
+ end.new
25
+ end
26
+
27
+ describe ".invoke" do
28
+ it "invokes block with given context and stacked unit" do
29
+ described_class.new(unit, :label) { current_unit }.invoke(context).should == unit
30
+ end
31
+
32
+
33
+ context "when context is a view" do
34
+ it "invokes with unit's view path" do
35
+ described_class.new(unit, :label) { path }.invoke(context).should == unit.view_path
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ module Nyanko
4
+ describe Helper do
5
+ describe ".define" do
6
+ after do
7
+ described_class.class_eval do
8
+ remove_method :__example_unit_test rescue nil
9
+ end
10
+ end
11
+
12
+ let(:view) do
13
+ Class.new { include Nyanko::Helper }.new
14
+ end
15
+
16
+ it "defines helper methods with special prefix" do
17
+ described_class.define("ExampleUnit") do
18
+ def test
19
+ "test"
20
+ end
21
+ end
22
+ view.__example_unit_test.should == "test"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,116 @@
1
+ require "spec_helper"
2
+
3
+ module Nyanko
4
+ describe Invoker do
5
+ let(:view) do
6
+ Class.new(ActionView::Base) do
7
+ include Nyanko::Invoker
8
+ include Nyanko::Helper
9
+ include Nyanko::UnitProxyProvider
10
+ end.new
11
+ end
12
+
13
+ let(:controller) do
14
+ Class.new(ActionController::Base) do
15
+ include Nyanko::Invoker
16
+ include Nyanko::Helper
17
+ include Nyanko::UnitProxyProvider
18
+ end.new
19
+ end
20
+
21
+ describe "#invoke" do
22
+ it "invokes in the same context with receiver" do
23
+ view.invoke(:example_unit, :self, :type => :plain).should == view
24
+ end
25
+
26
+ it "invokes with locals option" do
27
+ view.invoke(:example_unit, :locals, :locals => { :key => "value" }, :type => :plain).
28
+ should == "value"
29
+ end
30
+
31
+ it "invokes with shared method" do
32
+ view.invoke(:example_unit, :shared, :type => :plain).should == "shared args"
33
+ end
34
+
35
+ it "invokes with helper method in view context" do
36
+ view.invoke(:example_unit, :helper, :type => :plain).should == "helper"
37
+ end
38
+
39
+ context "when short-hand style args is passed" do
40
+ it "recognizes args as locals option" do
41
+ view.invoke(:example_unit, :locals, :key => "value").should ==
42
+ '<div class="unit unit__example_unit unit__example_unit__locals">value</div>'
43
+ end
44
+ end
45
+
46
+ context "when type is not specified" do
47
+ it "invokes and returns result surrounded by div" do
48
+ view.invoke(:example_unit, :test).should ==
49
+ '<div class="unit unit__example_unit unit__example_unit__test">test</div>'
50
+ end
51
+ end
52
+
53
+ context "when type is :plain" do
54
+ it "invokes defined function for current context and return result" do
55
+ view.invoke(:example_unit, :test, :type => :plain).should == "test"
56
+ end
57
+ end
58
+
59
+ context "when type is :inline" do
60
+ it "invokes and returns result surrounded by span" do
61
+ view.invoke(:example_unit, :test, :type => :inline).should ==
62
+ '<span class="unit unit__example_unit unit__example_unit__test">test</span>'
63
+ end
64
+ end
65
+
66
+ context "when context is not a view" do
67
+ it "does not surround result with html tag" do
68
+ controller.invoke(:example_unit, :test).should == "test"
69
+ end
70
+ end
71
+
72
+ context "when non-existent unit is specified" do
73
+ it "does nothing" do
74
+ view.invoke(:non_existent_unit, :test, :type => :plain).should == nil
75
+ end
76
+ end
77
+
78
+ context "when dependent unit is inactive" do
79
+ it "does nothing" do
80
+ view.invoke(:example_unit, :test, :if => :inactive_unit).should == nil
81
+ end
82
+ end
83
+
84
+ context "when 2 functions are specified" do
85
+ it "invokes first active function" do
86
+ view.invoke([:inactive_unit, :inactive], [:example_unit, :test], :type => :plain).
87
+ should == "test"
88
+ end
89
+ end
90
+
91
+ context "when an error is raised in invoking" do
92
+ context "when block is given" do
93
+ context "when context is a view" do
94
+ it "captures given block as a fallback" do
95
+ view.should_receive(:capture).and_call_original
96
+ view.invoke(:example_unit, :error) { "error" }.should == "error"
97
+ end
98
+ end
99
+
100
+ context "when context is not a view" do
101
+ it "calls given block as a fallback" do
102
+ controller.should_not_receive(:capture)
103
+ controller.invoke(:example_unit, :error) { "error" }.should == "error"
104
+ end
105
+ end
106
+ end
107
+
108
+ context "when no block is given" do
109
+ it "rescues the error and does nothing" do
110
+ view.invoke(:example_unit, :error).should == nil
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+
3
+ module Nyanko
4
+ describe Loader do
5
+ describe ".load" do
6
+ after do
7
+ described_class.cache.clear
8
+ end
9
+
10
+ context "when existent unit name is passed" do
11
+ it "loads unit in units directory and returns the Module" do
12
+ described_class.load(:example_unit).should == ExampleUnit
13
+ end
14
+ end
15
+
16
+ context "when non-existent unit name is passed" do
17
+ it "returns nil" do
18
+ described_class.load(:non_existent_unit).should == nil
19
+ end
20
+ end
21
+
22
+ context "when loader has ever loaded specified unit" do
23
+ it "load unit from cache" do
24
+ described_class.any_instance.should_receive(:load_from_file).and_call_original
25
+ described_class.load(:example_unit)
26
+ described_class.load(:example_unit)
27
+ end
28
+ end
29
+
30
+ context "when loader has ever loaded specified wrong unit" do
31
+ before do
32
+ described_class.cache.clear
33
+ end
34
+
35
+ it "load unit from cache" do
36
+ described_class.any_instance.should_receive(:load_from_file).and_call_original
37
+ described_class.load(:non_existent_unit)
38
+ described_class.load(:non_existent_unit)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ module Nyanko
4
+ module Unit
5
+ describe Extender do
6
+ before do
7
+ stub_const("ExampleClass", Class.new)
8
+ end
9
+
10
+ it "extends instance methods" do
11
+ Extender.new.expand(:ExampleClass) do
12
+ def test
13
+ "test"
14
+ end
15
+ end
16
+ ExampleClass.new.test.should == "test"
17
+ end
18
+
19
+ it "extends class methods" do
20
+ Extender.new.expand(:ExampleClass) do
21
+ class_methods do
22
+ def test
23
+ "test"
24
+ end
25
+ end
26
+ end
27
+ ExampleClass.test.should == "test"
28
+ end
29
+
30
+ it "extends instance methods with prefix" do
31
+ Extender.new("__prefix_").expand(:ExampleClass) do
32
+ def test
33
+ "test"
34
+ end
35
+ end
36
+ ExampleClass.new.__prefix_test.should == "test"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,37 @@
1
+ require "spec_helper"
2
+
3
+ module Nyanko
4
+ module Unit
5
+ describe ScopeFinder do
6
+ describe ".find(identifier)" do
7
+ context "when identifier is a class" do
8
+ it "returns identifier with no change" do
9
+ identifier = ActionView::Base
10
+ described_class.find(identifier).should == ActionView::Base
11
+ end
12
+ end
13
+
14
+ context "when identifier is a reserved label" do
15
+ it "returns reserved class for that" do
16
+ identifier = :view
17
+ described_class.find(identifier).should == ActionView::Base
18
+ end
19
+ end
20
+
21
+ context "when identifier is a string that means a class" do
22
+ it "returns class of that string" do
23
+ identifier = "ActionView::Base"
24
+ described_class.find(identifier).should == ActionView::Base
25
+ end
26
+ end
27
+
28
+ context "when no class is found" do
29
+ it "returns nil" do
30
+ identifier = "Non::Existent::Class"
31
+ described_class.find(identifier).should == nil
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ module Nyanko
4
+ describe UnitProxyProvider do
5
+ let(:view) do
6
+ Class.new { include Nyanko::UnitProxyProvider }.new
7
+ end
8
+
9
+ describe "#unit" do
10
+ context "when given unit name" do
11
+ it "returns proxy for specified unit" do
12
+ proxy = view.unit(:example_unit)
13
+ proxy.should be_a UnitProxy
14
+ proxy.unit.should == ExampleUnit
15
+ end
16
+
17
+ context "when unit is not found" do
18
+ it "raises NoUnitError" do
19
+ expect { view.unit(:non_existent_unit) }.to raise_error(described_class::NoUnitError)
20
+ end
21
+ end
22
+ end
23
+
24
+ context "when given no unit name" do
25
+ before do
26
+ Function.units << Loader.load(:example_unit)
27
+ end
28
+
29
+ after do
30
+ Function.units.pop
31
+ end
32
+
33
+ it "returns proxy for the top unit of current unit stack" do
34
+ proxy = view.unit
35
+ proxy.unit.should == ExampleUnit
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+
3
+ module Nyanko
4
+ describe UnitProxy do
5
+ let(:view) do
6
+ Class.new { include UnitProxyProvider }.new
7
+ end
8
+
9
+ describe "#active?" do
10
+ it "returns activation status of unit" do
11
+ view.unit(:example_unit).should be_active
12
+ view.unit(:inactive_unit).should_not be_active
13
+ end
14
+ end
15
+
16
+ describe "#method_missing" do
17
+ it "calls prefixed method" do
18
+ view.should_receive(:__example_unit_test)
19
+ view.unit(:example_unit).test
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,169 @@
1
+ require "spec_helper"
2
+
3
+ module Nyanko
4
+ describe Unit do
5
+ before do
6
+ unit.stub(:name => "ExampleUnit")
7
+ end
8
+
9
+ let(:unit) do
10
+ Module.new { include Nyanko::Unit }
11
+ end
12
+
13
+ let(:view) do
14
+ Class.new { include Nyanko::Helper }.new
15
+ end
16
+
17
+ describe ".active_if" do
18
+ before do
19
+ ActiveIf.define(:true) { true }
20
+ ActiveIf.define(:false) { false }
21
+ end
22
+
23
+ after do
24
+ ActiveIf.clear
25
+ end
26
+
27
+ subject { unit.active?(view) }
28
+
29
+ context "in default configuration" do
30
+ it "is configured to return always true" do
31
+ should be_true
32
+ end
33
+ end
34
+
35
+ context "when labels are specified" do
36
+ before do
37
+ unit.active_if(:true, :false)
38
+ end
39
+ specify "all of defined conditions must pass" do
40
+ should be_false
41
+ end
42
+ end
43
+
44
+ context "when block is passed" do
45
+ before do
46
+ unit.active_if(:true) { false }
47
+ end
48
+ specify "all of defined conditions and block must pass" do
49
+ should be_false
50
+ end
51
+ end
52
+
53
+ context "when any is specified" do
54
+ before do
55
+ unit.instance_eval do
56
+ active_if any(:true, :false)
57
+ end
58
+ end
59
+ specify "any of conditions must pass" do
60
+ should be_true
61
+ end
62
+ end
63
+ end
64
+
65
+ describe ".scope" do
66
+ specify "given scope is recorded to used scope list" do
67
+ unit.scope(:view) { }
68
+ unit.scopes.keys.should == [ActionView::Base]
69
+ end
70
+
71
+ context "in the scoped block" do
72
+ specify "current_scope returns given scope" do
73
+ unit.scope(:view) do
74
+ unit.current_scope.should == ActionView::Base
75
+ end
76
+ end
77
+ end
78
+
79
+ context "out of the scoped block" do
80
+ specify "current_scope returns nil" do
81
+ unit.scope(:view) { }
82
+ unit.current_scope.should == nil
83
+ end
84
+ end
85
+ end
86
+
87
+ describe ".function" do
88
+ it "stores given block with current_scope and given label" do
89
+ unit.scope(:view) do
90
+ unit.function(:test) do
91
+ "test"
92
+ end
93
+ end
94
+ unit.scopes[ActionView::Base][:test].block.should === "test"
95
+ end
96
+ end
97
+
98
+ describe ".shared" do
99
+ it "stroes given block with given label" do
100
+ unit.shared(:test) do
101
+ "test"
102
+ end
103
+ unit.shared_methods[:test].call.should == "test"
104
+ end
105
+ end
106
+
107
+ describe ".helpers" do
108
+ it "provides interface for unit to define helper methods" do
109
+ unit.helpers do
110
+ def test
111
+ "test"
112
+ end
113
+ end
114
+ view.__example_unit_test.should == "test"
115
+ end
116
+ end
117
+
118
+ describe ".models" do
119
+ before do
120
+ stub_const("ExampleModel", model_class)
121
+ unit.models do
122
+ expand(:ExampleModel) do
123
+ scope :active, lambda { where(:deleted_at => nil) }
124
+
125
+ def test
126
+ "test"
127
+ end
128
+
129
+ class_methods do
130
+ def test
131
+ "test"
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ let(:model_class) do
139
+ Class.new do
140
+ include UnitProxyProvider
141
+
142
+ def self.scope(name, *args)
143
+ singleton_class.class_eval do
144
+ define_method(name) { "scoped" }
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ it "defines instance methods with prefix" do
151
+ ExampleModel.new.__example_unit_test.should == "test"
152
+ end
153
+
154
+ it "defines class methods with prefix" do
155
+ ExampleModel.__example_unit_test.should == "test"
156
+ end
157
+
158
+ it "defines association methods with prefix" do
159
+ ExampleModel.__example_unit_active.should == "scoped"
160
+ end
161
+ end
162
+
163
+ describe ".view_path" do
164
+ it "returns path for its view directory" do
165
+ unit.view_path.should == "#{Config.units_directory_path}/example_unit/views"
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,21 @@
1
+ require "simplecov"
2
+ SimpleCov.start do
3
+ add_filter "/spec\/fixtures/"
4
+ add_filter "/spec\/dummy/"
5
+ end
6
+
7
+ require "nyanko"
8
+ Nyanko::Config.units_directory_path = File.expand_path("../fixtures/units", __FILE__)
9
+
10
+ ENV["RAILS_ENV"] ||= "test"
11
+ require File.expand_path("../dummy/config/environment", __FILE__)
12
+ require "rspec/rails"
13
+ require "rspec/autorun"
14
+
15
+ RSpec.configure do |config|
16
+ config.use_transactional_fixtures = true
17
+ config.infer_base_class_for_anonymous_controllers = false
18
+ config.treat_symbols_as_metadata_keys_with_true_values = true
19
+ config.run_all_when_everything_filtered = true
20
+ config.filter_run :focus
21
+ end