brock 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Brock
2
+
3
+ ![Brock](http://upload.wikimedia.org/wikipedia/en/7/71/DP-Brock.png)
4
+
5
+ Generate HTML from definitions. Generate settings from params.
6
+
7
+ template = Brock.new([
8
+ { name: 'mp_maxrounds',
9
+ type: 'integer',
10
+ label: 'Max Round',
11
+ description: 'Maximum number of rounds to play',
12
+ default: 5
13
+ }
14
+ ])
15
+
16
+ template.to_html('mp_maxrounds' => 2) # => "<html>...</html>"
17
+ template.parse_params('mp_maxrounds' => 2) # => {'mp_maxrounds' => 10}
18
+
19
+
20
+ ## License
21
+
22
+ The MIT License (MIT)
23
+ Copyright © 2013 Mütli Corp. <tech+brock@minefold.com>
24
+
25
+ Permission is hereby granted, free of charge, to any person obtaining a copy
26
+ of this software and associated documentation files (the “Software”), to deal
27
+ in the Software without restriction, including without limitation the rights
28
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29
+ copies of the Software, and to permit persons to whom the Software is
30
+ furnished to do so, subject to the following conditions:
31
+
32
+ The above copyright notice and this permission notice shall be included in
33
+ all copies or substantial portions of the Software.
34
+
35
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41
+ THE SOFTWARE.
data/brock.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'brock/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'brock'
8
+ gem.version = Brock::VERSION
9
+ gem.authors = ["Dave Newman"]
10
+ gem.email = ["dave@minefold.com"]
11
+ gem.description = %q{Test Minefold funpacks}
12
+ gem.summary = %q{Test Minefold funpacks}
13
+ gem.homepage = "https://minefold.com"
14
+
15
+ gem.test_files = gem.files.grep(%r{^spec/})
16
+ gem.require_paths = ["lib"]
17
+
18
+ gem.add_development_dependency 'rspec'
19
+ gem.add_development_dependency 'nokogiri'
20
+
21
+ gem.files = %w(
22
+ Gemfile
23
+ README.md
24
+ brock.gemspec
25
+ ) + Dir['{lib,share,spec}/**/*']
26
+ end
data/lib/brock.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'brock/definition'
2
+ require 'brock/version'
3
+
4
+ module Brock
5
+
6
+ def self.version
7
+ VERSION
8
+ end
9
+
10
+ def self.to_html(definition, values, options={})
11
+ Definition.new(definition).to_html(values)
12
+ end
13
+
14
+ def self.parse_params(defintion, params)
15
+ Definition.new(defintion).parse_paras(params)
16
+ end
17
+
18
+ end
@@ -0,0 +1,54 @@
1
+ require 'brock/fields/boolean_field'
2
+ require 'brock/fields/integer_field'
3
+ require 'brock/fields/string_field'
4
+
5
+ module Brock
6
+
7
+ class FieldTypeNotSupported < StandardError
8
+ end
9
+
10
+ class Definition
11
+
12
+ attr_reader :fields
13
+
14
+ def self.field_for_type(type)
15
+ case type
16
+ when 'boolean'
17
+ BooleanField
18
+ when 'integer'
19
+ IntegerField
20
+ when 'string'
21
+ StringField
22
+ else
23
+ raise FieldTypeNotSupported
24
+ end
25
+ end
26
+
27
+ def initialize(definitions)
28
+ @fields = definitions.map do |definition|
29
+ klass = self.class.field_for_type(definition.fetch('type'))
30
+ klass.new(definition)
31
+ end
32
+ end
33
+
34
+ def to_html(values)
35
+ fields.map do |field|
36
+ field.to_html(values.fetch(field.name))
37
+ end.join("\n")
38
+ end
39
+
40
+ def parse_params(params)
41
+ params.each_with_object({}) do |(name, value), settings|
42
+ field = field_with_name(name)
43
+ settings[field.name] = field.parse_param(value)
44
+ end
45
+ end
46
+
47
+ # private
48
+
49
+ def field_with_name(name)
50
+ fields.find {|field| field.name == name.to_sym }
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,34 @@
1
+ require 'brock/field_template'
2
+
3
+ module Brock
4
+ class ParamParseError < ArgumentError
5
+ end
6
+
7
+ class Field
8
+
9
+ attr_reader :type
10
+ attr_reader :name
11
+ attr_reader :label
12
+ attr_reader :default
13
+
14
+ attr_reader :description
15
+
16
+ def initialize(params = {})
17
+ @type = params.fetch('type').to_sym
18
+ @name = params.fetch('name').to_sym
19
+ @label = params.fetch('label')
20
+ @default = params.fetch('default')
21
+
22
+ @description = params['description']
23
+ end
24
+
25
+ def to_html(value=nil)
26
+ FieldTemplate.new(self).render(value)
27
+ end
28
+
29
+ def parse_param(value)
30
+ raise ParamParseError
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ require 'erb'
2
+ require 'brock/field_template_context'
3
+
4
+ module Brock
5
+ class FieldTemplate
6
+
7
+ def self.share_path
8
+ # __FILE__ is a special variable that is inlined at compile time so its value is this path to this file, not a subclasses'.
9
+ File.expand_path('../../../share', __FILE__)
10
+ end
11
+
12
+ attr_reader :field
13
+
14
+ def initialize(field)
15
+ @field = field
16
+ end
17
+
18
+ def render(value = nil)
19
+ ctx = FieldTemplateContext.new(@field, value)
20
+ ERB.new(raw).result(ctx.binding)
21
+ end
22
+
23
+ # private
24
+
25
+ def raw
26
+ File.read(path)
27
+ end
28
+
29
+ def path
30
+ File.join(self.class.share_path, "#{field.type}_field.erb")
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ module Brock
2
+ class FieldTemplateContext
3
+
4
+ attr_reader :value
5
+
6
+ def initialize(field, value)
7
+ @field = field
8
+ @value = value
9
+ end
10
+
11
+ def binding
12
+ super
13
+ end
14
+
15
+ def method_missing(method, *args, &blk)
16
+ if @field and @field.respond_to?(method)
17
+ @field.send(method, *args, &blk)
18
+ else
19
+ super(*args, &blk)
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ require 'brock/field'
2
+
3
+ module Brock
4
+ class BooleanField < Field
5
+
6
+ def parse_param(value)
7
+ value == '1' || value == 'true' || value == true
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ require 'brock/field'
2
+
3
+ module Brock
4
+ class IntegerField < Field
5
+
6
+ def parse_param(value)
7
+ Integer(value)
8
+ rescue ArgumentError
9
+ raise ParamParseError.new(value)
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ require 'brock/field'
2
+
3
+ module Brock
4
+ class StringField < Field
5
+
6
+ def parse_param(value)
7
+ value.to_s
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Brock
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,13 @@
1
+ <div class="control-group brock-field brock-field-boolean">
2
+ <div class="controls checkbox">
3
+ <label class="control-label brock-label">
4
+ <input class="brock-field"
5
+ type="checkbox"
6
+ name="brock[<%= name %>]"
7
+ <% if value || default %>checked<% end %>
8
+ />
9
+ <%= label %>
10
+ </label>
11
+ </div>
12
+ </div>
13
+
@@ -0,0 +1,19 @@
1
+ <div class="control-group brock-field brock-field-integer">
2
+
3
+ <label class="control-label brock-label"><%= label %></label>
4
+
5
+ <div class="controls">
6
+ <input class="brock-field"
7
+ type="number"
8
+ name="brock[<%= name %>]"
9
+ placeholder="<%= default %>"
10
+ <% if value %>
11
+ value="<%= value %>"
12
+ <% end %>
13
+ />
14
+ <% if description %>
15
+ <p class="help-block brock-description"><%= description %></p>
16
+ <% end %>
17
+ </div>
18
+
19
+ </div>
@@ -0,0 +1,16 @@
1
+ <div class="control-group brock-field brock-field-string">
2
+ <label class="control-label brock-label"><%= label %></label>
3
+ <div class="controls">
4
+ <input class="brock-field"
5
+ type="text"
6
+ name="brock[<%= name %>]"
7
+ placeholder="<%= default %>"
8
+ <% if value %>
9
+ value="<%= value %>"
10
+ <% end %>
11
+ />
12
+ <% if description %>
13
+ <p class="help-block brock-description"><%= description %></p>
14
+ <% end %>
15
+ </div>
16
+ </div>
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'brock/definition'
3
+
4
+ describe Brock::Definition do
5
+
6
+ let(:data) {
7
+ [
8
+ {
9
+ "name" => "mp_maxrounds",
10
+ "type" => "integer",
11
+ "label" => "Max Rounds",
12
+ "description" => "Maximum number of rounds to play before server changes maps.",
13
+ "default" => 5
14
+ }, {
15
+ "name" => "mp_autoteambalance",
16
+ "type" => "boolean",
17
+ "label" => "Auto Team Balance",
18
+ "default" => true
19
+ }
20
+ ]
21
+ }
22
+
23
+ subject { described_class.new(data) }
24
+
25
+ it "initializes fields" do
26
+ expect { subject }.to_not raise_error(Brock::FieldTypeNotSupported)
27
+ end
28
+
29
+ end
30
+
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'brock/field'
3
+
4
+ describe Brock::Field do
5
+
6
+ subject {
7
+ described_class.new(
8
+ 'type' => 'str',
9
+ 'name' => 'a',
10
+ 'label' => 'A',
11
+ 'default' => 'a'
12
+ )
13
+ }
14
+
15
+ it "#type is a symbol" do
16
+ expect(subject.type).to be_a(Symbol)
17
+ end
18
+
19
+ it "#name is a symbol" do
20
+ expect(subject.type).to be_a(Symbol)
21
+ end
22
+
23
+ it "#parse_param raises by default" do
24
+ expect {
25
+ subject.parse_param(nil)
26
+ }.to raise_error(Brock::ParamParseError)
27
+ end
28
+
29
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ require 'brock/field_template_context'
3
+
4
+ describe Brock::FieldTemplateContext do
5
+
6
+ let(:field) { stub(name: 'field_name') }
7
+
8
+ subject { described_class.new(field, 5) }
9
+
10
+ it "delegates to the field" do
11
+ expect(subject.name).to eq('field_name')
12
+ end
13
+
14
+ it "has a value" do
15
+ expect(subject.value).to eq(5)
16
+ end
17
+
18
+ it "doesn't accidentally override the passed value" do
19
+ field.stub(:value) { 6 }
20
+ expect(subject.value).to eq(5)
21
+ end
22
+
23
+ it "#binding is public" do
24
+ expect(subject.binding).to be_a(Binding)
25
+ end
26
+
27
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ require 'brock/field_template'
3
+
4
+ describe Brock::FieldTemplate do
5
+
6
+ let(:field) { stub }
7
+
8
+ subject { described_class.new(field) }
9
+
10
+ describe "#render" do
11
+
12
+ it "works" do
13
+ subject.stub(:raw) { 'My template' }
14
+ expect(subject.render).to eq('My template')
15
+ end
16
+
17
+ it "exposes field methods" do
18
+ field.stub(:name) { 'godmode' }
19
+ subject.stub(:raw) { '<%= name %>' }
20
+ expect(subject.render).to eq('godmode')
21
+ end
22
+
23
+ end
24
+
25
+ it "figures out the correct path" do
26
+ field.stub(type: 'string')
27
+ subject.class.stub(:share_path) { '/' }
28
+ expect(subject.path).to eq('/string_field.erb')
29
+ end
30
+
31
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'brock/fields/boolean_field'
3
+
4
+ describe Brock::BooleanField do
5
+
6
+ subject {
7
+ described_class.new(
8
+ 'type' => 'boolean',
9
+ 'name' => 'team_balance',
10
+ 'label' => 'Auto team balance',
11
+ 'default' => true
12
+ )
13
+ }
14
+
15
+ it "#to_html works" do
16
+ expect(subject.to_html(false)).to be_similar_to_fixture('boolean_field.html')
17
+ end
18
+
19
+ describe "#parse_param" do
20
+
21
+ it "works with 1" do
22
+ expect(subject.parse_param('1')).to eq(true)
23
+ end
24
+
25
+ it "works with true" do
26
+ expect(subject.parse_param('true')).to eq(true)
27
+ end
28
+
29
+ it "works with truthy-objects" do
30
+ expect(subject.parse_param(true)).to eq(true)
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'brock/fields/integer_field'
3
+
4
+ describe Brock::IntegerField do
5
+
6
+ subject {
7
+ described_class.new(
8
+ 'type' => 'integer',
9
+ 'name' => 'rounds',
10
+ 'label' => 'Rounds',
11
+ 'default' => 10
12
+ )
13
+ }
14
+
15
+ it "#to_html works" do
16
+ expect(subject.to_html(5)).to be_similar_to_fixture('integer_field.html')
17
+ end
18
+
19
+ describe "#parse_param" do
20
+
21
+ it "works with an integer" do
22
+ expect(subject.parse_param(10)).to eq(10)
23
+ end
24
+
25
+ it "works with an integer-like string" do
26
+ expect(subject.parse_param('10')).to eq(10)
27
+ end
28
+
29
+ it "raises with anything else" do
30
+ expect {
31
+ subject.parse_param('boom')
32
+ }.to raise_error(Brock::ParamParseError)
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ require 'brock/fields/string_field'
3
+
4
+ describe Brock::StringField do
5
+
6
+ subject {
7
+ described_class.new(
8
+ 'type' => 'string',
9
+ 'name' => 'first_name',
10
+ 'label' => 'First name',
11
+ 'default' => 'Chris'
12
+ )
13
+ }
14
+
15
+ it "#to_html works" do
16
+ expect(subject.to_html(5)).to be_similar_to_fixture('string_field.html')
17
+ end
18
+
19
+ describe "#parse_param" do
20
+
21
+ it "works with string" do
22
+ expect(subject.parse_param('foo')).to eq('foo')
23
+ end
24
+
25
+ it "calls to_s on other objects" do
26
+ obj = stub(to_s: 'sentinal')
27
+ expect(subject.parse_param(obj)).to eq('sentinal')
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,8 @@
1
+ <div class="control-group brock-field brock-field-boolean">
2
+ <div class="controls checkbox">
3
+ <label class="control-label brock-label">
4
+ <input class="brock-field" type="checkbox" name="brock[team_balance]" checked />
5
+ Auto team balance
6
+ </label>
7
+ </div>
8
+ </div>
@@ -0,0 +1,6 @@
1
+ <div class="control-group brock-field brock-field-integer">
2
+ <label class="control-label brock-label">Rounds</label>
3
+ <div class="controls">
4
+ <input class="brock-field" type="number" name="brock[rounds]" placeholder="10" value="5" />
5
+ </div>
6
+ </div>
@@ -0,0 +1,6 @@
1
+ <div class="control-group brock-field brock-field-string">
2
+ <label class="control-label brock-label">First name</label>
3
+ <div class="controls">
4
+ <input class="brock-field" type="text" name="brock[first_name]" placeholder="Chris" value="5" />
5
+ </div>
6
+ </div>
@@ -0,0 +1,24 @@
1
+ module FixtureHelpers
2
+
3
+ def fixture(path)
4
+ File.read(File.join(File.dirname(__FILE__), 'fixtures', path))
5
+ end
6
+
7
+ end
8
+
9
+ RSpec::Matchers.define :be_similar_to_fixture do |fixture_path|
10
+
11
+ def scrub(str)
12
+ str.gsub(/\s+/, ' ')
13
+ end
14
+
15
+ match do |actual|
16
+ scrub(actual) == scrub(fixture(fixture_path))
17
+ end
18
+
19
+ end
20
+
21
+ RSpec.configure do |config|
22
+ config.include(FixtureHelpers)
23
+ config.order = 'random'
24
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: brock
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Dave Newman
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-15 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: '0'
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: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: nokogiri
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Test Minefold funpacks
47
+ email:
48
+ - dave@minefold.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - Gemfile
54
+ - README.md
55
+ - brock.gemspec
56
+ - lib/brock/definition.rb
57
+ - lib/brock/field.rb
58
+ - lib/brock/field_template.rb
59
+ - lib/brock/field_template_context.rb
60
+ - lib/brock/fields/boolean_field.rb
61
+ - lib/brock/fields/integer_field.rb
62
+ - lib/brock/fields/string_field.rb
63
+ - lib/brock/version.rb
64
+ - lib/brock.rb
65
+ - share/boolean_field.erb
66
+ - share/integer_field.erb
67
+ - share/string_field.erb
68
+ - spec/brock/definition_spec.rb
69
+ - spec/brock/field_spec.rb
70
+ - spec/brock/field_template_context_spec.rb
71
+ - spec/brock/field_template_spec.rb
72
+ - spec/brock/fields/boolean_field_spec.rb
73
+ - spec/brock/fields/integer_field_spec.rb
74
+ - spec/brock/fields/string_field_spec.rb
75
+ - spec/fixtures/boolean_field.html
76
+ - spec/fixtures/integer_field.html
77
+ - spec/fixtures/string_field.html
78
+ - spec/spec_helper.rb
79
+ homepage: https://minefold.com
80
+ licenses: []
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 1.8.23
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: Test Minefold funpacks
103
+ test_files: []