nyanko 0.0.1

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