lita 4.1.0 → 4.2.0

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: 8f7cb3c5b605c35c60bdff103c47df2488814712
4
- data.tar.gz: 22be31cadc4608c676923ea7253a9a3b6456e5ad
3
+ metadata.gz: 24b9a37965d639387442b0a419f4c1c860f726b9
4
+ data.tar.gz: 59d805329cc2aeab6724473f78dda55e01a1e970
5
5
  SHA512:
6
- metadata.gz: 5f11b1e00ff16c75e0a5c56a7c96b6d658d27ef207444deb2808265471409f5fc5d6c2d3c585b3c56434e8097515ce5eee85f7d02de983979e005a47435e415b
7
- data.tar.gz: 2bb7b4fd5497735d4e4a78559b26878f4de79e016901bf1c123c56b78fa37bc6d3c1e7b430875fd7fd820f55026b5f66e3d54ac1ee7be13a96c74a7941304eb3
6
+ metadata.gz: 06734db0a8f1de6b83acabcea2546db17df71900876ee1864ef524c7607c60a3a223919dbb9aa30602915bce5d10aeacdedf84e6f7da324575d3bc0701eb305b
7
+ data.tar.gz: c94be903e979b6a5a0d3c3eae0cfcf8d1d457d5895c087d5b64070fddcf0cf88b647c425123e427d0caae149b188863f3fc1e9b0f7395189a0516093b222d382
@@ -94,6 +94,8 @@ require_relative "lita/logger"
94
94
  require_relative "lita/callback"
95
95
  require_relative "lita/configurable"
96
96
  require_relative "lita/namespace"
97
+ require_relative "lita/template"
98
+ require_relative "lita/template_resolver"
97
99
  require_relative "lita/handler/common"
98
100
  require_relative "lita/handler/chat_router"
99
101
  require_relative "lita/handler/http_router"
@@ -172,6 +172,9 @@ module Lita
172
172
  )
173
173
  template("plugin/spec/spec_helper.tt", "#{target}/spec/spec_helper.rb", config)
174
174
  template("plugin/locales/en.yml.tt", "#{target}/locales/en.yml", config)
175
+ if config[:plugin_type] == "handler"
176
+ copy_file("plugin/templates/gitkeep", "#{target}/templates/.gitkeep")
177
+ end
175
178
  copy_file("plugin/Gemfile", "#{target}/Gemfile")
176
179
  template("plugin/gemspec.tt", "#{target}/#{gem_name}.gemspec", config)
177
180
  copy_file("plugin/gitignore", "#{target}/.gitignore")
@@ -11,4 +11,13 @@ module Lita
11
11
  # An exception raised when Lita can't connect to Redis in test mode.
12
12
  # @since 4.0.3
13
13
  class RedisError < Error; end
14
+
15
+ # An exception raised when attempting to resolve a template that doesn't exist.
16
+ # @since 4.2.0
17
+ class MissingTemplateError < Error; end
18
+
19
+ # An exception raised when a handler attempts to render a template without having set its
20
+ # template root.
21
+ # @since 4.2.0
22
+ class MissingTemplateRootError < Error; end
14
23
  end
@@ -13,6 +13,20 @@ module Lita
13
13
 
14
14
  # Common class-level methods for all handlers.
15
15
  module ClassMethods
16
+ # Gets (and optionally sets) the directory where the handler's templates are stored.
17
+ # @param path [String] If provided, sets the template root to this value.
18
+ # @return [String] The template root path.
19
+ # @raise [MissingTemplateRootError] If accessed without setting a value first.
20
+ def template_root(path = nil)
21
+ @template_root = path if path
22
+
23
+ if defined?(@template_root)
24
+ return @template_root
25
+ else
26
+ raise MissingTemplateRootError
27
+ end
28
+ end
29
+
16
30
  # Returns the translation for a key, automatically namespaced to the handler.
17
31
  # @param key [String] The key of the translation.
18
32
  # @param hash [Hash] An optional hash of values to be interpolated in the string.
@@ -90,6 +104,10 @@ module Lita
90
104
  Lita.logger
91
105
  end
92
106
 
107
+ def render_template(template_name, variables = {})
108
+ Template.from_file(file_for_template(template_name)).render(variables)
109
+ end
110
+
93
111
  # @see .translate
94
112
  def translate(*args)
95
113
  self.class.translate(*args)
@@ -105,6 +123,14 @@ module Lita
105
123
  { headers: { "User-Agent" => "Lita v#{VERSION}" } }
106
124
  end
107
125
 
126
+ def file_for_template(template_name)
127
+ TemplateResolver.new(
128
+ self.class.template_root,
129
+ template_name,
130
+ robot.config.robot.adapter
131
+ ).resolve
132
+ end
133
+
108
134
  # The handler's namespace for Redis.
109
135
  def redis_namespace
110
136
  "handlers:#{self.class.namespace}"
@@ -0,0 +1,53 @@
1
+ module Lita
2
+ # A simple wrapper around ERB to render text from files or strings.
3
+ # @since 4.2.0
4
+ class Template
5
+ # A clean room object to use as the binding for ERB rendering.
6
+ # @api private
7
+ class TemplateEvaluationContext
8
+ # Returns the evaluation context's binding.
9
+ # @return [Binding] The binding.
10
+ def __get_binding
11
+ binding
12
+ end
13
+ end
14
+
15
+ class << self
16
+ # Initializes a new Template with the contents of the file at the given path.
17
+ # @param path [String] The path to the file to use as the template content.
18
+ # @return Template
19
+ def from_file(path)
20
+ new(File.read(path).chomp)
21
+ end
22
+ end
23
+
24
+ # @param source [String] A string to use as the template's content.
25
+ def initialize(source)
26
+ @erb = ERB.new(source, $SAFE, "<>")
27
+ end
28
+
29
+ # Render the template with the provided variables.
30
+ # @param variables [Hash] A collection of variables for interpolation. Each key-value pair will
31
+ # make the value available inside the template as an instance variable with the key as its
32
+ # name.
33
+ def render(variables = {})
34
+ erb.result(context_binding(variables))
35
+ end
36
+
37
+ private
38
+
39
+ # Create an empty object to use as the ERB context and set any provided variables in it.
40
+ def context_binding(variables)
41
+ context = TemplateEvaluationContext.new
42
+
43
+ variables.each do |k, v|
44
+ context.instance_variable_set("@#{k}", v)
45
+ end
46
+
47
+ context.__get_binding
48
+ end
49
+
50
+ # The underlying ERB object.
51
+ attr_reader :erb
52
+ end
53
+ end
@@ -0,0 +1,45 @@
1
+ module Lita
2
+ # Finds the file path of the most appropriate template for the given adapter.
3
+ # @api private
4
+ # @since 4.2.0
5
+ class TemplateResolver
6
+ # @param template_root [String] The directory to search for templates.
7
+ # @param template_name [String] The name of the template to search for.
8
+ # @param adapter_name [String, Symbol] The name of the current adapter.
9
+ def initialize(template_root, template_name, adapter_name)
10
+ @template_root = template_root
11
+ @template_name = template_name
12
+ @adapter_name = adapter_name
13
+ end
14
+
15
+ # Returns the adapter-specific template, falling back to a generic template.
16
+ # @return [String] The path of the template to use.
17
+ # @raises [MissingTemplateError] If no templates with the given name exist.
18
+ def resolve
19
+ return adapter_template if File.exist?(adapter_template)
20
+ return generic_template if File.exist?(generic_template)
21
+ raise MissingTemplateError, I18n.t("lita.template.missing_template", path: generic_template)
22
+ end
23
+
24
+ private
25
+
26
+ # The directory to search for templates.
27
+ attr_reader :template_root
28
+
29
+ # The name of the template to search for.
30
+ attr_reader :template_name
31
+
32
+ # The name of the current adapter.
33
+ attr_reader :adapter_name
34
+
35
+ # Path to the adapter-specific template.
36
+ def adapter_template
37
+ @adapter_template ||= File.join(template_root, "#{template_name}.#{adapter_name}.erb")
38
+ end
39
+
40
+ # Path to the generic template.
41
+ def generic_template
42
+ @generic_template ||= File.join(template_root, "#{template_name}.erb")
43
+ end
44
+ end
45
+ end
@@ -1,4 +1,4 @@
1
1
  module Lita
2
2
  # The current version of Lita.
3
- VERSION = "4.1.0"
3
+ VERSION = "4.2.0"
4
4
  end
@@ -171,6 +171,33 @@ describe Lita::Handler::Common, lita: true do
171
171
  end
172
172
  end
173
173
 
174
+ describe "#render_template" do
175
+ context "with the template root set" do
176
+ before do
177
+ handler.template_root(File.expand_path(File.join("..", "..", "..", "templates"), __FILE__))
178
+ end
179
+
180
+ it "renders the given template to a string" do
181
+ expect(subject.render_template("basic")).to eq("Template rendered from a file!")
182
+ end
183
+
184
+ it "interpolates variables into the rendered template" do
185
+ result = subject.render_template("interpolated", first: "Carl", last: "Pug")
186
+
187
+ expect(result).to eq("I love Carl Pug!")
188
+ end
189
+
190
+ it "renders adapter-specific templates if available" do
191
+ robot.config.robot.adapter = :irc
192
+ expect(subject.render_template("basic")).to eq("IRC template rendered from a file!")
193
+ end
194
+ end
195
+
196
+ it "raises an exception if the template root hasn't been set" do
197
+ expect { subject.render_template("basic") }.to raise_error(Lita::MissingTemplateRootError)
198
+ end
199
+ end
200
+
174
201
  describe "timer methods" do
175
202
  let(:queue) { Queue.new }
176
203
 
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::TemplateResolver do
4
+ subject do
5
+ described_class.new(template_root, template_name, adapter_name)
6
+ end
7
+
8
+ let(:adapter_name) { :shell }
9
+ let(:generic_template) { File.join(template_root, "basic.erb") }
10
+ let(:irc_template) { File.join(template_root, "basic.irc.erb") }
11
+ let(:template_name) { "basic" }
12
+ let(:template_root) { File.expand_path(File.join("..", "..", "templates"), __FILE__) }
13
+
14
+ describe "#resolve" do
15
+ context "when there is a template for the adapter" do
16
+ let(:adapter_name) { :irc }
17
+
18
+ it "returns the path to the adapter-specific template" do
19
+ expect(subject.resolve).to eq(irc_template)
20
+ end
21
+ end
22
+
23
+ context "when there is no template for the adapter" do
24
+ it "returns the path for the generic template" do
25
+ expect(subject.resolve).to eq(generic_template)
26
+ end
27
+ end
28
+
29
+ context "when there is no template with the given name" do
30
+ let(:template_name) { "nonexistent" }
31
+
32
+ it "raises an exception" do
33
+ expect { subject.resolve }.to raise_error(
34
+ Lita::MissingTemplateError,
35
+ %r{templates/nonexistent\.erb}
36
+ )
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,33 @@
1
+ require "spec_helper"
2
+
3
+ describe Lita::Template do
4
+ describe ".from_file" do
5
+ context "with a path to an ERB template" do
6
+ subject do
7
+ described_class.from_file(File.expand_path("../../templates/basic.erb", __FILE__))
8
+ end
9
+
10
+ it "uses the source in the file" do
11
+ expect(subject.render).to eq("Template rendered from a file!")
12
+ end
13
+ end
14
+ end
15
+
16
+ describe "#render" do
17
+ context "with a static source template" do
18
+ subject { described_class.new("Hello, Lita!") }
19
+
20
+ it "renders the text" do
21
+ expect(subject.render).to eq("Hello, Lita!")
22
+ end
23
+ end
24
+
25
+ context "with interpolation variables" do
26
+ subject { described_class.new("Hello, <%= @name %>!") }
27
+
28
+ it "renders the text with interpolated values" do
29
+ expect(subject.render(name: "Carl")).to eq("Hello, Carl!")
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1 @@
1
+ Template rendered from a file!
@@ -0,0 +1 @@
1
+ IRC template rendered from a file!
@@ -0,0 +1 @@
1
+ I love <%= @first %> <%= @last %>!
@@ -152,3 +152,5 @@ en:
152
152
  `%{old_method}` is deprecated and will be removed in Lita 5.0. Use `%{new_method}` instead.
153
153
  source:
154
154
  user_or_room_required: Either a user or a room is required.
155
+ template:
156
+ missing_template: Missing template file at %{path}.
@@ -18,7 +18,7 @@ gem "<%= config[:gem_name] %>"
18
18
  ```
19
19
  <%- end -%>
20
20
 
21
- <%- unless config[:plugin_type] == "extension" %>
21
+ <%- unless config[:plugin_type] == "extension" -%>
22
22
  ## Configuration
23
23
 
24
24
  TODO: Describe any configuration attributes the plugin exposes.
@@ -5,3 +5,10 @@ Lita.load_locales Dir[File.expand_path(
5
5
  )]
6
6
 
7
7
  require "lita/<%= config[:namespace] %>/<%= config[:name] %>"
8
+ <%- if config[:plugin_type] == "handler" -%>
9
+
10
+ Lita::<%= config[:constant_namespace] %>::<%= config[:constant_name] %>.template_root File.expand_path(
11
+ File.join("..", "..", "templates"),
12
+ __FILE__
13
+ )
14
+ <%- end -%>
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lita
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jimmy Cuadra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-11 00:00:00.000000000 Z
11
+ date: 2015-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -323,6 +323,8 @@ files:
323
323
  - lib/lita/rspec/matchers/event_route_matcher.rb
324
324
  - lib/lita/rspec/matchers/http_route_matcher.rb
325
325
  - lib/lita/source.rb
326
+ - lib/lita/template.rb
327
+ - lib/lita/template_resolver.rb
326
328
  - lib/lita/timer.rb
327
329
  - lib/lita/user.rb
328
330
  - lib/lita/util.rb
@@ -354,11 +356,16 @@ files:
354
356
  - spec/lita/robot_spec.rb
355
357
  - spec/lita/rspec_spec.rb
356
358
  - spec/lita/source_spec.rb
359
+ - spec/lita/template_resolver_spec.rb
360
+ - spec/lita/template_spec.rb
357
361
  - spec/lita/timer_spec.rb
358
362
  - spec/lita/user_spec.rb
359
363
  - spec/lita/util_spec.rb
360
364
  - spec/lita_spec.rb
361
365
  - spec/spec_helper.rb
366
+ - spec/templates/basic.erb
367
+ - spec/templates/basic.irc.erb
368
+ - spec/templates/interpolated.erb
362
369
  - templates/locales/en.yml
363
370
  - templates/plugin/Gemfile
364
371
  - templates/plugin/LICENSE.tt
@@ -371,6 +378,7 @@ files:
371
378
  - templates/plugin/locales/en.yml.tt
372
379
  - templates/plugin/spec/lita/plugin_type/plugin_spec.tt
373
380
  - templates/plugin/spec/spec_helper.tt
381
+ - templates/plugin/templates/gitkeep
374
382
  - templates/plugin/travis.yml
375
383
  - templates/robot/Gemfile
376
384
  - templates/robot/lita_config.rb
@@ -425,8 +433,14 @@ test_files:
425
433
  - spec/lita/robot_spec.rb
426
434
  - spec/lita/rspec_spec.rb
427
435
  - spec/lita/source_spec.rb
436
+ - spec/lita/template_resolver_spec.rb
437
+ - spec/lita/template_spec.rb
428
438
  - spec/lita/timer_spec.rb
429
439
  - spec/lita/user_spec.rb
430
440
  - spec/lita/util_spec.rb
431
441
  - spec/lita_spec.rb
432
442
  - spec/spec_helper.rb
443
+ - spec/templates/basic.erb
444
+ - spec/templates/basic.irc.erb
445
+ - spec/templates/interpolated.erb
446
+ has_rdoc: