nm 0.1.0 → 0.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 +7 -0
- data/Gemfile +3 -0
- data/README.md +101 -21
- data/bench/_slide.nm +5 -0
- data/bench/logger.rb +36 -0
- data/bench/results/nm.txt +30 -0
- data/bench/results/nm_partials.txt +30 -0
- data/bench/results/nm_re_source.txt +30 -0
- data/bench/results/rabl.txt +30 -0
- data/bench/runner.rb +84 -0
- data/bench/slideshow.nm +12 -0
- data/bench/slideshow.rabl +5 -0
- data/bench/slideshow.rb +47 -0
- data/bench/slideshow_partials.nm +8 -0
- data/bench/slideshow_partials.rb +17 -0
- data/bench/template.rb +16 -0
- data/lib/nm.rb +1 -0
- data/lib/nm/ext.rb +31 -0
- data/lib/nm/source.rb +49 -0
- data/lib/nm/template.rb +95 -0
- data/lib/nm/version.rb +1 -1
- data/nm.gemspec +2 -2
- data/script/bench_all.rb +5 -0
- data/script/bench_nm.rb +13 -0
- data/script/bench_nm_partials.rb +13 -0
- data/script/bench_nm_re_source.rb +13 -0
- data/script/bench_rabl.rb +13 -0
- data/test/helper.rb +8 -1
- data/test/support/factory.rb +14 -0
- data/test/support/templates/_list.nm +3 -0
- data/test/support/templates/_locals.nm +3 -0
- data/test/support/templates/_obj.nm +3 -0
- data/test/support/templates/aliases.nm +4 -0
- data/test/support/templates/list.nm +3 -0
- data/test/support/templates/locals.nm +3 -0
- data/test/support/templates/obj.nm +5 -0
- data/test/unit/ext_tests.rb +94 -0
- data/test/unit/source_tests.rb +94 -0
- data/test/unit/template_tests.rb +355 -0
- metadata +58 -33
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'assert/factory'
|
2
|
+
require 'bench/slideshow'
|
3
|
+
|
4
|
+
module NmBench
|
5
|
+
|
6
|
+
class SlideshowPartialsTemplate < SlideshowTemplate
|
7
|
+
|
8
|
+
TEMPLATES[:slideshow_partials] = self
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
super
|
12
|
+
@name = 'slideshow_partials'
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/bench/template.rb
ADDED
data/lib/nm.rb
CHANGED
data/lib/nm/ext.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Nm
|
2
|
+
|
3
|
+
class InvalidError < RuntimeError; end
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
class ::Hash
|
8
|
+
|
9
|
+
def __nm_add_call_data__(call_name, data)
|
10
|
+
if data.is_a?(::Array)
|
11
|
+
raise Nm::InvalidError, "invalid `#{call_name}` call"
|
12
|
+
end
|
13
|
+
self.merge(data || {})
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
class ::Array
|
19
|
+
|
20
|
+
def __nm_add_call_data__(call_name, data)
|
21
|
+
if data.is_a?(::Hash)
|
22
|
+
raise Nm::InvalidError, "invalid `#{call_name}` call"
|
23
|
+
end
|
24
|
+
self.concat(data || [])
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def nil.__nm_add_call_data__(call_name, data)
|
30
|
+
data
|
31
|
+
end
|
data/lib/nm/source.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'nm/template'
|
3
|
+
|
4
|
+
module Nm
|
5
|
+
|
6
|
+
class Source
|
7
|
+
|
8
|
+
EXT = ".nm"
|
9
|
+
|
10
|
+
attr_reader :root
|
11
|
+
|
12
|
+
def initialize(root)
|
13
|
+
@root = Pathname.new(root.to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
def data(file_path)
|
17
|
+
File.send(File.respond_to?(:binread) ? :binread : :read, file_path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def render(file_name, locals = nil)
|
21
|
+
Template.new(self, source_file_path(file_name), locals || {}).__data__
|
22
|
+
end
|
23
|
+
|
24
|
+
def partial(file_name, locals = nil)
|
25
|
+
Template.new(self, partial_file_path(file_name), locals || {}).__data__
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def source_file_path(file_name)
|
31
|
+
self.root.join("#{file_name}#{EXT}").to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
def partial_file_path(file_name)
|
35
|
+
basename = File.basename(file_name.to_s)
|
36
|
+
source_file_path(file_name.to_s.sub(/#{basename}\Z/, "_#{basename}"))
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
class DefaultSource < Source
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
super('/')
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/lib/nm/template.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'nm/source'
|
2
|
+
require 'nm/ext'
|
3
|
+
|
4
|
+
module Nm
|
5
|
+
|
6
|
+
class Template
|
7
|
+
|
8
|
+
def initialize(*args)
|
9
|
+
@__dstack__ = [ nil ]
|
10
|
+
|
11
|
+
# apply any given locals to template scope as methods
|
12
|
+
metaclass = class << self; self; end
|
13
|
+
(args.last.kind_of?(::Hash) ? args.pop : {}).each do |key, value|
|
14
|
+
metaclass.class_eval{ define_method(key){ value } }
|
15
|
+
end
|
16
|
+
|
17
|
+
source_file = args.last.kind_of?(::String) ? args.pop : ''
|
18
|
+
@__source__ = args.last.kind_of?(Source) ? args.pop : DefaultSource.new
|
19
|
+
|
20
|
+
return if source_file.empty?
|
21
|
+
|
22
|
+
unless File.exists?(source_file)
|
23
|
+
raise ArgumentError, "source file `#{source_file}` does not exist"
|
24
|
+
end
|
25
|
+
instance_eval(@__source__.data(source_file), source_file, 1)
|
26
|
+
end
|
27
|
+
|
28
|
+
def __data__
|
29
|
+
@__dstack__.last
|
30
|
+
end
|
31
|
+
|
32
|
+
def __node__(key, value = nil, &block)
|
33
|
+
unless @__dstack__[-1].nil? || @__dstack__[-1].is_a?(::Hash)
|
34
|
+
raise Nm::InvalidError, "invalid `node` call"
|
35
|
+
end
|
36
|
+
@__dstack__[-1] ||= ::Hash.new
|
37
|
+
|
38
|
+
@__dstack__.push(nil)
|
39
|
+
self.instance_exec(&(block || Proc.new {}))
|
40
|
+
@__dstack__.pop.tap{ |v| @__dstack__[-1][key] = (v || value) }
|
41
|
+
|
42
|
+
return self
|
43
|
+
end
|
44
|
+
|
45
|
+
alias_method :node, :__node__
|
46
|
+
alias_method :_node, :__node__
|
47
|
+
alias_method :n, :__node__
|
48
|
+
|
49
|
+
def __map__(list, &block)
|
50
|
+
unless list.respond_to?(:map)
|
51
|
+
raise ArgumentError, "given list (`#{list.class}`) doesn't respond to `.map`"
|
52
|
+
end
|
53
|
+
unless @__dstack__[-1].nil? || @__dstack__[-1].is_a?(::Array)
|
54
|
+
raise Nm::InvalidError, "invalid `map` call"
|
55
|
+
end
|
56
|
+
@__dstack__[-1] ||= ::Array.new
|
57
|
+
|
58
|
+
list.map do |item|
|
59
|
+
@__dstack__.push(nil)
|
60
|
+
self.instance_exec(item, &(block || Proc.new {}))
|
61
|
+
@__dstack__.pop.tap{ |v| @__dstack__[-1].push(v || item) }
|
62
|
+
end
|
63
|
+
|
64
|
+
return self
|
65
|
+
end
|
66
|
+
|
67
|
+
alias_method :map, :__map__
|
68
|
+
alias_method :_map, :__map__
|
69
|
+
alias_method :m, :__map__
|
70
|
+
|
71
|
+
def __render__(*args)
|
72
|
+
data = @__source__.render(*args)
|
73
|
+
@__dstack__[-1] = @__dstack__[-1].__nm_add_call_data__('render', data)
|
74
|
+
|
75
|
+
return self
|
76
|
+
end
|
77
|
+
|
78
|
+
alias_method :render, :__render__
|
79
|
+
alias_method :_render, :__render__
|
80
|
+
alias_method :r, :__render__
|
81
|
+
|
82
|
+
def __partial__(*args)
|
83
|
+
data = @__source__.partial(*args)
|
84
|
+
@__dstack__[-1] = @__dstack__[-1].__nm_add_call_data__('partial', data)
|
85
|
+
|
86
|
+
return self
|
87
|
+
end
|
88
|
+
|
89
|
+
alias_method :partial, :__partial__
|
90
|
+
alias_method :_partial, :__partial__
|
91
|
+
alias_method :p, :__partial__
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
data/lib/nm/version.rb
CHANGED
data/nm.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = Nm::VERSION
|
9
9
|
gem.authors = ["Kelly Redding", "Collin Redding"]
|
10
10
|
gem.email = ["kelly@kellyredding.com", "collin.redding@me.com"]
|
11
|
-
gem.description = %q{
|
12
|
-
gem.summary = %q{
|
11
|
+
gem.description = %q{Data templating system.}
|
12
|
+
gem.summary = %q{Data templating system.}
|
13
13
|
gem.homepage = "http://github.com/redding/nm"
|
14
14
|
gem.license = 'MIT'
|
15
15
|
|
data/script/bench_all.rb
ADDED
data/script/bench_nm.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# $ bundle exec ruby script/bench.rb
|
2
|
+
|
3
|
+
# require pry for debugging (`binding.pry`)
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
require 'bench/logger'
|
7
|
+
require 'bench/slideshow'
|
8
|
+
|
9
|
+
NmBench::Logger.new('bench/results/nm.txt') do |logger|
|
10
|
+
logger.run_template(:nm, :slideshow, 1)
|
11
|
+
logger.run_template(:nm, :slideshow, 10)
|
12
|
+
logger.run_template(:nm, :slideshow, 100)
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# $ bundle exec ruby script/bench.rb
|
2
|
+
|
3
|
+
# require pry for debugging (`binding.pry`)
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
require 'bench/logger'
|
7
|
+
require 'bench/slideshow_partials'
|
8
|
+
|
9
|
+
NmBench::Logger.new('bench/results/nm_partials.txt') do |logger|
|
10
|
+
logger.run_template(:nm, :slideshow_partials, 1)
|
11
|
+
logger.run_template(:nm, :slideshow_partials, 10)
|
12
|
+
logger.run_template(:nm, :slideshow_partials, 100)
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# $ bundle exec ruby script/bench.rb
|
2
|
+
|
3
|
+
# require pry for debugging (`binding.pry`)
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
require 'bench/logger'
|
7
|
+
require 'bench/slideshow'
|
8
|
+
|
9
|
+
NmBench::Logger.new('bench/results/nm_re_source.txt') do |logger|
|
10
|
+
logger.run_template(:nm_re_source, :slideshow, 1)
|
11
|
+
logger.run_template(:nm_re_source, :slideshow, 10)
|
12
|
+
logger.run_template(:nm_re_source, :slideshow, 100)
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# $ bundle exec ruby script/bench.rb
|
2
|
+
|
3
|
+
# require pry for debugging (`binding.pry`)
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
require 'bench/logger'
|
7
|
+
require 'bench/slideshow'
|
8
|
+
|
9
|
+
NmBench::Logger.new('bench/results/rabl.txt') do |logger|
|
10
|
+
logger.run_template(:rabl, :slideshow, 1)
|
11
|
+
logger.run_template(:rabl, :slideshow, 10)
|
12
|
+
logger.run_template(:rabl, :slideshow, 100)
|
13
|
+
end
|
data/test/helper.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
# this file is automatically required when you run `assert`
|
2
2
|
# put any test helpers here
|
3
3
|
|
4
|
+
require 'pathname'
|
5
|
+
|
4
6
|
# add the root dir to the load path
|
5
|
-
|
7
|
+
ROOT = Pathname.new(File.expand_path("../..", __FILE__))
|
8
|
+
$LOAD_PATH.unshift(ROOT.to_s)
|
9
|
+
|
10
|
+
TEMPLATE_ROOT = ROOT.join('test/support/templates')
|
6
11
|
|
7
12
|
# require pry for debugging (`binding.pry`)
|
8
13
|
require 'pry'
|
14
|
+
|
15
|
+
require 'test/support/factory'
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'nm/ext'
|
3
|
+
|
4
|
+
module Nm::Ext
|
5
|
+
|
6
|
+
class UnitTests < Assert::Context
|
7
|
+
desc "Nm ruby extension"
|
8
|
+
subject{ Nm }
|
9
|
+
|
10
|
+
should "define and invalid runtime error" do
|
11
|
+
assert_kind_of ::RuntimeError, subject::InvalidError.new
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
class AddCallDataTests < UnitTests
|
17
|
+
desc "__nm_add_call_data__"
|
18
|
+
setup do
|
19
|
+
@call_name = Factory.string
|
20
|
+
end
|
21
|
+
|
22
|
+
should "be added to ::Hash" do
|
23
|
+
assert_responds_to :__nm_add_call_data__, ::Hash.new
|
24
|
+
end
|
25
|
+
|
26
|
+
should "be added to ::Array" do
|
27
|
+
assert_responds_to :__nm_add_call_data__, ::Array.new
|
28
|
+
end
|
29
|
+
|
30
|
+
should "be added to nil" do
|
31
|
+
assert_responds_to :__nm_add_call_data__, nil
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
class HashAddCallDataTests < AddCallDataTests
|
37
|
+
desc "on ::Hash"
|
38
|
+
setup do
|
39
|
+
@h = { 1 => '1' }
|
40
|
+
end
|
41
|
+
|
42
|
+
should "merge and return hash and nil data" do
|
43
|
+
add = { 2 => '2' }
|
44
|
+
assert_equal @h.merge(add), @h.__nm_add_call_data__(@call_name, add)
|
45
|
+
assert_equal @h, @h.__nm_add_call_data__(@call_name, nil)
|
46
|
+
end
|
47
|
+
|
48
|
+
should "complain if adding Array data" do
|
49
|
+
add = []
|
50
|
+
assert_raises Nm::InvalidError do
|
51
|
+
@h.__nm_add_call_data__(@call_name, add)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
class ArrayAddCallDataTests < AddCallDataTests
|
58
|
+
desc "on ::Array"
|
59
|
+
setup do
|
60
|
+
@a = [1, 2]
|
61
|
+
end
|
62
|
+
|
63
|
+
should "concat and return array and nil data" do
|
64
|
+
add = [3, 4]
|
65
|
+
assert_equal @a.concat(add), @a.__nm_add_call_data__(@call_name, add)
|
66
|
+
assert_equal @a, @a.__nm_add_call_data__(@call_name, nil)
|
67
|
+
end
|
68
|
+
|
69
|
+
should "complain if adding Hash data" do
|
70
|
+
add = {}
|
71
|
+
assert_raises Nm::InvalidError do
|
72
|
+
@a.__nm_add_call_data__(@call_name, add)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
class NilAddCallDataTests < AddCallDataTests
|
79
|
+
desc "on nil"
|
80
|
+
setup do
|
81
|
+
@n = nil
|
82
|
+
end
|
83
|
+
|
84
|
+
should "return any given data" do
|
85
|
+
add_hash = { 1 => '1' }
|
86
|
+
add_array = [3, 4]
|
87
|
+
assert_equal add_hash, @n.__nm_add_call_data__(@call_name, add_hash)
|
88
|
+
assert_equal add_array, @n.__nm_add_call_data__(@call_name, add_array)
|
89
|
+
assert_equal @n, @n.__nm_add_call_data__(@call_name, nil)
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|