stringfire 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .#*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in stringfire.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 conanite
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,64 @@
1
+ # Stringfire
2
+
3
+ Strip the first token off a string, pass remainder of string as arg to function identified by first token
4
+
5
+ Useful where you want user-supplied executable expressions embedded in your data (in a CMS for example), but for obvious reasons you're not going to let them write ruby code
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'stringfire'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install stringfire
20
+
21
+ ## Usage
22
+
23
+ @interpreter = Stringfire::Interpreter.new
24
+
25
+ @interpreter.command("say-hello") { |arg| "hello, #{arg}" }
26
+
27
+ @interpreter.interpret "say-hello dear user" # => "hello, dear user"
28
+
29
+ You can nest interpreters
30
+
31
+ @interpreter.command("if-admin") { |arg| User.admin? ? @interpreter.interpret(arg) : "" }
32
+
33
+ login_as(admin_user)
34
+ @interpreter.interpret "if-admin say-hello dear user" # => "hello, dear user"
35
+
36
+ logout
37
+ @interpreter.interpret "if-admin say-hello dear user" # => ""
38
+
39
+ You can pass arbitrary additional args
40
+
41
+ @interpreter.command("say-bye") { |arg, lovely, days| "bye-bye, #{arg}, it was #{lovely} to meet you, see you in #{days} days" }
42
+
43
+ @interpreter.interpret("say-bye dear user", "wonderful", 2) # => "bye-bye, dear user, it was wonderful to meet you, see you in 2 days"
44
+
45
+ Additional args may be useful in a Rails context if you need to pass an ActionController or ActionView instance to your commands :
46
+
47
+ @interpreter.command("tweets") { |arg, view| view.render_cell :tweets, :show, arg.split(/,/) }
48
+
49
+ @interpreter.interpret("tweets conanite, 10, no-RT", view) # => same as calling view.render_cell(:tweets, :show, "conanite", "10", "no-RT")
50
+
51
+ You can specify a default handler for unknown commands
52
+
53
+ @interpreter.default { |text, *args| raise "Unable to interpret '#{text}': available commands are #{@interpreter.command_names.join ', '}" }
54
+
55
+ @interpreter.interpret("foobar toto james anthony krishna", 1, 2, 3) # => Error: Unable to interpret 'foobar toto james anthony krishna': available commands are say-hello, if-admin, say-bye
56
+
57
+
58
+ ## Contributing
59
+
60
+ 1. Fork it
61
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
62
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
63
+ 4. Push to the branch (`git push origin my-new-feature`)
64
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,43 @@
1
+ require "stringfire/version"
2
+
3
+ module Stringfire
4
+
5
+ class Interpreter
6
+ def split_first_word str
7
+ result = str.strip.split /\s/, 2
8
+ result << "" while result.size < 2
9
+ result
10
+ end
11
+
12
+ def initialize
13
+ @commands = { }
14
+ default { |command, *args| command }
15
+ end
16
+
17
+ def command name, &block
18
+ @commands[name] = block
19
+ end
20
+
21
+ def command_names
22
+ @commands.keys
23
+ end
24
+
25
+ def default *args, &block
26
+ if block_given?
27
+ @default = block
28
+ else
29
+ @default.call *args
30
+ end
31
+ end
32
+
33
+ def interpret command_text, *args
34
+ name, details = split_first_word command_text
35
+ if @commands.key? name
36
+ @commands[name].call details, *args
37
+ else
38
+ default command_text, *args
39
+ end
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,3 @@
1
+ module Stringfire
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,19 @@
1
+ require "stringfire"
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # Require this file using `require "spec_helper"` to ensure that it is only
6
+ # loaded once.
7
+ #
8
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
9
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+
14
+ # Run specs in random order to surface order dependencies. If you find an
15
+ # order dependency and want to debug it, you can fix the order by providing
16
+ # the seed, which is printed after each run.
17
+ # --seed 1234
18
+ config.order = 'random'
19
+ end
@@ -0,0 +1,56 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require File.expand_path('../../spec_helper', __FILE__)
4
+
5
+ describe Stringfire::Interpreter do
6
+
7
+ class User
8
+ attr_accessor :admin
9
+ end
10
+
11
+ let(:interpreter) { Stringfire::Interpreter.new }
12
+
13
+ let(:user) { User.new }
14
+
15
+ before {
16
+ interpreter.command("say-hello") { |arg| "hello, #{arg}" }
17
+ interpreter.command("if-admin") { |arg| user.admin ? interpreter.interpret(arg) : "" }
18
+ interpreter.command("say-bye") { |arg, lovely, days| "bye-bye, #{arg}, it was #{lovely} to meet you, see you in #{days} days" }
19
+ interpreter.command("tweets") { |arg, view| view.render_cell :tweets, :show, *arg.split(/\s*,\s*/) }
20
+ interpreter.default { |text, *args| raise "Unable to interpret '#{text}': available commands are #{interpreter.command_names.join ', '}" }
21
+ }
22
+
23
+ it "should say hello" do
24
+ interpreter.interpret("say-hello dear user").should == "hello, dear user"
25
+ end
26
+
27
+ it "should say hello to admin" do
28
+ user.admin = true
29
+ interpreter.interpret("if-admin say-hello dear user").should == "hello, dear user"
30
+ end
31
+
32
+ it "should say nothing to non-admin" do
33
+ user.admin = false
34
+ interpreter.interpret("if-admin say-hello dear user").should == ""
35
+ end
36
+
37
+ it "should say goodbye with axtra args" do
38
+ interpreter.interpret("say-bye dear user", "wonderful", 2).should == "bye-bye, dear user, it was wonderful to meet you, see you in 2 days"
39
+ end
40
+
41
+ it "should be useful in a Rails context" do
42
+ view = mock("view")
43
+ view.should_receive(:render_cell).with(:tweets, :show, "conanite", "10", "no-RT").and_return "conanite's fascinating tweets"
44
+
45
+ interpreter.interpret("tweets conanite, 10, no-RT", view).should == "conanite's fascinating tweets"
46
+ end
47
+
48
+ it "should be unable to interpret foobar" do
49
+ Proc.new {
50
+ interpreter.interpret("foobar toto james anthony krishna", 1, 2, 3)
51
+ }.should raise_error RuntimeError, "Unable to interpret 'foobar toto james anthony krishna': available commands are say-hello, if-admin, say-bye, tweets"
52
+
53
+ end
54
+ end
55
+
56
+
@@ -0,0 +1,22 @@
1
+ # -*- coding: utf-8; mode: ruby -*-
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'stringfire/version'
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = "stringfire"
9
+ gem.version = Stringfire::VERSION
10
+ gem.authors = ["Conan Dalton"]
11
+ gem.email = ["conan@conandalton.net"]
12
+ gem.description = %q{Strip the first token off a string, pass remainder of string as arg to function identified by first token}
13
+ gem.summary = "Useful where you want user-supplied executable expressions embedded in your data (in a CMS for example), but for obvious reasons you're not going to let them write ruby code"
14
+ gem.homepage = "https://github.com/conanite/stringfire"
15
+
16
+ gem.add_development_dependency 'rspec', '~> 2.9'
17
+
18
+ gem.files = `git ls-files`.split($/)
19
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
20
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
21
+ gem.require_paths = ["lib"]
22
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stringfire
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Conan Dalton
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.9'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.9'
30
+ description: Strip the first token off a string, pass remainder of string as arg to
31
+ function identified by first token
32
+ email:
33
+ - conan@conandalton.net
34
+ executables: []
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - .gitignore
39
+ - .rspec
40
+ - Gemfile
41
+ - LICENSE.txt
42
+ - README.md
43
+ - Rakefile
44
+ - lib/stringfire.rb
45
+ - lib/stringfire/version.rb
46
+ - spec/spec_helper.rb
47
+ - spec/stringfire/interpreter_spec.rb
48
+ - stringfire.gemspec
49
+ homepage: https://github.com/conanite/stringfire
50
+ licenses: []
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 1.8.24
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Useful where you want user-supplied executable expressions embedded in your
73
+ data (in a CMS for example), but for obvious reasons you're not going to let them
74
+ write ruby code
75
+ test_files:
76
+ - spec/spec_helper.rb
77
+ - spec/stringfire/interpreter_spec.rb