nm 0.5.4 → 0.6.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 -7
- data/.gitignore +1 -0
- data/.l.yml +9 -0
- data/.rubocop.yml +3 -0
- data/.ruby-version +1 -0
- data/.t.yml +6 -0
- data/Gemfile +6 -2
- data/README.md +53 -51
- data/lib/nm.rb +12 -2
- data/lib/nm/context.rb +55 -0
- data/lib/nm/ext.rb +11 -18
- data/lib/nm/render.rb +12 -0
- data/lib/nm/source.rb +60 -47
- data/lib/nm/template_behaviors.rb +96 -0
- data/lib/nm/version.rb +3 -1
- data/nm.gemspec +12 -6
- data/test/helper.rb +6 -13
- data/test/support/factory.rb +3 -2
- data/test/support/templates/_list.nm +2 -0
- data/test/support/templates/_locals.nm +4 -2
- data/test/support/templates/_obj.nm +5 -3
- data/test/support/templates/aliases.nm +8 -3
- data/test/support/templates/list.nm +2 -0
- data/test/support/templates/locals.nm +4 -2
- data/test/support/templates/locals_alt.data.inem +2 -2
- data/test/support/templates/obj.nm +6 -4
- data/test/system/.keep +0 -0
- data/test/unit/context_tests.rb +51 -0
- data/test/unit/ext_tests.rb +27 -42
- data/test/unit/nm_tests.rb +20 -0
- data/test/unit/render_tests.rb +28 -0
- data/test/unit/source_tests.rb +89 -106
- data/test/unit/template_behaviors_tests.rb +259 -0
- metadata +82 -43
- data/lib/nm/template.rb +0 -103
- data/test/unit/template_tests.rb +0 -357
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "much-mixin"
|
4
|
+
require "nm/ext"
|
5
|
+
require "nm/render"
|
6
|
+
require "nm/source"
|
7
|
+
|
8
|
+
module Nm; end
|
9
|
+
|
10
|
+
module Nm::TemplateBehaviors
|
11
|
+
include MuchMixin
|
12
|
+
|
13
|
+
after_mixin_included do
|
14
|
+
attr_accessor :__nm_context__
|
15
|
+
|
16
|
+
alias_method :node, :__node__
|
17
|
+
alias_method :_node, :__node__
|
18
|
+
alias_method :n, :__node__
|
19
|
+
|
20
|
+
alias_method :map, :__map__
|
21
|
+
alias_method :_map, :__map__
|
22
|
+
alias_method :m, :__map__
|
23
|
+
|
24
|
+
alias_method :partial, :__partial__
|
25
|
+
alias_method :_partial, :__partial__
|
26
|
+
alias_method :p, :__partial__
|
27
|
+
end
|
28
|
+
|
29
|
+
mixin_instance_methods do
|
30
|
+
def __nm_render_stack__
|
31
|
+
@__nm_render_stack__ ||= []
|
32
|
+
end
|
33
|
+
|
34
|
+
def __nm_push_render__(locals)
|
35
|
+
__nm_render_stack__.push(
|
36
|
+
Nm::Render.new(dstack: @__nm_dstack__, locals: @__nm_locals__),
|
37
|
+
)
|
38
|
+
@__nm_dstack__ = [nil]
|
39
|
+
@__nm_locals__ = locals
|
40
|
+
end
|
41
|
+
|
42
|
+
def __nm_pop_render__
|
43
|
+
__nm_render_stack__.pop.tap do |render|
|
44
|
+
@__nm_dstack__ = render.dstack
|
45
|
+
@__nm_locals__ = render.locals
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def __nm_data__
|
50
|
+
@__nm_dstack__.last || {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def __node__(key, value = nil, &block)
|
54
|
+
unless @__nm_dstack__[-1].nil? || @__nm_dstack__[-1].is_a?(::Hash)
|
55
|
+
raise Nm::InvalidError, "invalid `node` call"
|
56
|
+
end
|
57
|
+
@__nm_dstack__[-1] ||= {}
|
58
|
+
|
59
|
+
@__nm_dstack__.push(nil)
|
60
|
+
instance_exec(&(block || Proc.new{}))
|
61
|
+
@__nm_dstack__.pop.tap{ |v| @__nm_dstack__[-1][key] = (v || value) }
|
62
|
+
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
def __map__(list, &block)
|
67
|
+
unless list.respond_to?(:map)
|
68
|
+
raise(
|
69
|
+
ArgumentError,
|
70
|
+
"given list (`#{list.class}`) doesn't respond to `.map`",
|
71
|
+
)
|
72
|
+
end
|
73
|
+
unless @__nm_dstack__[-1].nil? || @__nm_dstack__[-1].is_a?(::Array)
|
74
|
+
raise Nm::InvalidError, "invalid `map` call"
|
75
|
+
end
|
76
|
+
@__nm_dstack__[-1] ||= []
|
77
|
+
|
78
|
+
list.map do |item|
|
79
|
+
@__nm_dstack__.push(nil)
|
80
|
+
instance_exec(item, &(block || Proc.new{}))
|
81
|
+
@__nm_dstack__.pop.tap{ |v| @__nm_dstack__[-1].push(v || item) }
|
82
|
+
end
|
83
|
+
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
87
|
+
def __partial__(*args)
|
88
|
+
@__nm_dstack__[-1] =
|
89
|
+
@__nm_dstack__[-1].__nm_add_partial_data__(
|
90
|
+
__nm_context__.partial(*args),
|
91
|
+
)
|
92
|
+
|
93
|
+
self
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/nm/version.rb
CHANGED
data/nm.gemspec
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
6
|
require "nm/version"
|
5
7
|
|
@@ -8,12 +10,12 @@ Gem::Specification.new do |gem|
|
|
8
10
|
gem.version = Nm::VERSION
|
9
11
|
gem.authors = ["Kelly Redding", "Collin Redding"]
|
10
12
|
gem.email = ["kelly@kellyredding.com", "collin.redding@me.com"]
|
11
|
-
gem.summary =
|
12
|
-
gem.description =
|
13
|
+
gem.summary = "Node-Map: a data templating DSL."
|
14
|
+
gem.description = "Node-Map: a data templating DSL."
|
13
15
|
gem.homepage = "http://github.com/redding/nm"
|
14
|
-
gem.license =
|
16
|
+
gem.license = "MIT"
|
15
17
|
|
16
|
-
gem_files = `git ls-files`.split(
|
18
|
+
gem_files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
19
|
gem_files -= gem_files.grep(%r{^(bench)/})
|
18
20
|
gem_files -= gem_files.grep(%r{^(script)/})
|
19
21
|
gem.files = gem_files
|
@@ -21,6 +23,10 @@ Gem::Specification.new do |gem|
|
|
21
23
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
22
24
|
gem.require_paths = ["lib"]
|
23
25
|
|
24
|
-
gem.
|
26
|
+
gem.required_ruby_version = "~> 2.5"
|
27
|
+
|
28
|
+
gem.add_development_dependency("much-style-guide", ["~> 0.6.6"])
|
29
|
+
gem.add_development_dependency("assert", ["~> 2.19.6"])
|
25
30
|
|
31
|
+
gem.add_dependency("much-mixin", ["~> 0.2.4"])
|
26
32
|
end
|
data/test/helper.rb
CHANGED
@@ -1,24 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# this file is automatically required when you run `assert`
|
2
4
|
# put any test helpers here
|
3
5
|
|
4
|
-
require
|
6
|
+
require "pathname"
|
5
7
|
|
6
8
|
# add the root dir to the load path
|
7
9
|
ROOT = Pathname.new(File.expand_path("../..", __FILE__))
|
8
10
|
$LOAD_PATH.unshift(ROOT.to_s)
|
9
11
|
|
10
|
-
TEMPLATE_ROOT = ROOT.join(
|
12
|
+
TEMPLATE_ROOT = ROOT.join("test/support/templates")
|
11
13
|
|
12
14
|
# require pry for debugging (`binding.pry`)
|
13
|
-
require
|
14
|
-
|
15
|
-
require 'test/support/factory'
|
16
|
-
|
17
|
-
# 1.8.7 backfills
|
15
|
+
require "pry"
|
18
16
|
|
19
|
-
|
20
|
-
if !(a = Array.new).respond_to?(:sample) && a.respond_to?(:choice)
|
21
|
-
class Array
|
22
|
-
alias_method :sample, :choice
|
23
|
-
end
|
24
|
-
end
|
17
|
+
require "test/support/factory"
|
data/test/support/factory.rb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
_map(1..1) do
|
4
|
+
n "node local value", node
|
5
|
+
_node "map local value", map
|
6
|
+
__node__ "context method value", helper_method1
|
7
|
+
__node__ "context local value", key1
|
8
|
+
__node__ "render local value", key2
|
4
9
|
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
node
|
2
|
-
node
|
1
|
+
node "locals" do
|
2
|
+
node "key", key
|
3
3
|
end
|
data/test/system/.keep
ADDED
File without changes
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "assert"
|
4
|
+
require "nm/context"
|
5
|
+
|
6
|
+
require "nm/source"
|
7
|
+
require "nm/template_behaviors"
|
8
|
+
|
9
|
+
class Nm::Context
|
10
|
+
class UnitTests < Assert::Context
|
11
|
+
desc "Nm::Context"
|
12
|
+
subject{ unit_class }
|
13
|
+
|
14
|
+
let(:unit_class){ Nm::Context }
|
15
|
+
end
|
16
|
+
|
17
|
+
class InitTests < UnitTests
|
18
|
+
desc "when init"
|
19
|
+
subject{ unit_class.new(context, source: source, locals: locals) }
|
20
|
+
|
21
|
+
let(:context){ Class.new.new }
|
22
|
+
let(:template_root){ Factory.template_root }
|
23
|
+
let(:source){ Nm::Source.new(template_root) }
|
24
|
+
let(:locals){ { "key" => "a-value" } }
|
25
|
+
|
26
|
+
should have_imeths :render, :partial, :render_content
|
27
|
+
|
28
|
+
should "setup the context to render Nm templates" do
|
29
|
+
local_name, local_val = [Factory.string, Factory.string]
|
30
|
+
nm_context =
|
31
|
+
unit_class.new(
|
32
|
+
context,
|
33
|
+
source: source,
|
34
|
+
locals: { local_name => local_val },
|
35
|
+
)
|
36
|
+
|
37
|
+
assert_that(context.class).does_not_include(Nm::TemplateBehaviors)
|
38
|
+
|
39
|
+
metaclass = class << context; self; end
|
40
|
+
assert_that(metaclass).includes(Nm::TemplateBehaviors)
|
41
|
+
|
42
|
+
assert_that(context).responds_to(local_name)
|
43
|
+
assert_that(context.send(local_name)).equals(local_val)
|
44
|
+
|
45
|
+
assert_that(context.__nm_context__).equals(nm_context)
|
46
|
+
end
|
47
|
+
|
48
|
+
# See test/unit/template_behaviors_tests.rb for testing the mixed in
|
49
|
+
# template behaviors and rendering.
|
50
|
+
end
|
51
|
+
end
|
data/test/unit/ext_tests.rb
CHANGED
@@ -1,94 +1,79 @@
|
|
1
|
-
|
2
|
-
require 'nm/ext'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
require "assert"
|
4
|
+
require "nm/ext"
|
5
5
|
|
6
|
+
module Nm::Ext
|
6
7
|
class UnitTests < Assert::Context
|
7
8
|
desc "Nm ruby extension"
|
8
9
|
subject{ Nm }
|
9
10
|
|
10
|
-
should "define
|
11
|
-
|
11
|
+
should "define an invalid runtime error" do
|
12
|
+
assert_that(subject::InvalidError.new).is_a(RuntimeError)
|
12
13
|
end
|
13
|
-
|
14
14
|
end
|
15
15
|
|
16
16
|
class AddCallDataTests < UnitTests
|
17
|
-
desc "
|
18
|
-
setup do
|
19
|
-
@call_name = Factory.string
|
20
|
-
end
|
17
|
+
desc "__nm_add_partial_data__"
|
21
18
|
|
22
19
|
should "be added to ::Hash" do
|
23
|
-
|
20
|
+
assert_that({}).responds_to(:__nm_add_partial_data__)
|
24
21
|
end
|
25
22
|
|
26
23
|
should "be added to ::Array" do
|
27
|
-
|
24
|
+
assert_that([]).responds_to(:__nm_add_partial_data__)
|
28
25
|
end
|
29
26
|
|
30
27
|
should "be added to nil" do
|
31
|
-
|
28
|
+
assert_that(nil).responds_to(:__nm_add_partial_data__)
|
32
29
|
end
|
33
|
-
|
34
30
|
end
|
35
31
|
|
36
32
|
class HashAddCallDataTests < AddCallDataTests
|
37
33
|
desc "on ::Hash"
|
38
|
-
|
39
|
-
|
40
|
-
end
|
34
|
+
|
35
|
+
let(:h){ { 1 => "1" } }
|
41
36
|
|
42
37
|
should "merge and return hash and nil data" do
|
43
|
-
add = { 2 =>
|
44
|
-
|
45
|
-
|
38
|
+
add = { 2 => "2" }
|
39
|
+
assert_that(h.__nm_add_partial_data__(add)).equals(h.merge(add))
|
40
|
+
assert_that(h.__nm_add_partial_data__(nil)).equals(h)
|
46
41
|
end
|
47
42
|
|
48
43
|
should "complain if adding Array data" do
|
49
44
|
add = []
|
50
|
-
|
51
|
-
@h.__nm_add_call_data__(@call_name, add)
|
52
|
-
end
|
45
|
+
assert_that{ h.__nm_add_partial_data__(add) }.raises(Nm::InvalidError)
|
53
46
|
end
|
54
|
-
|
55
47
|
end
|
56
48
|
|
57
49
|
class ArrayAddCallDataTests < AddCallDataTests
|
58
50
|
desc "on ::Array"
|
59
|
-
|
60
|
-
|
61
|
-
end
|
51
|
+
|
52
|
+
let(:a){ [1, 2] }
|
62
53
|
|
63
54
|
should "concat and return array and nil data" do
|
64
55
|
add = [3, 4]
|
65
|
-
|
66
|
-
|
56
|
+
assert_that(a.__nm_add_partial_data__(add)).equals(a.concat(add))
|
57
|
+
assert_that(a.__nm_add_partial_data__(nil)).equals(a)
|
67
58
|
end
|
68
59
|
|
69
60
|
should "complain if adding Hash data" do
|
70
61
|
add = {}
|
71
|
-
|
72
|
-
@a.__nm_add_call_data__(@call_name, add)
|
73
|
-
end
|
62
|
+
assert_that{ a.__nm_add_partial_data__(add) }.raises(Nm::InvalidError)
|
74
63
|
end
|
75
|
-
|
76
64
|
end
|
77
65
|
|
78
66
|
class NilAddCallDataTests < AddCallDataTests
|
79
67
|
desc "on nil"
|
80
|
-
|
81
|
-
|
82
|
-
end
|
68
|
+
|
69
|
+
let(:n){ nil }
|
83
70
|
|
84
71
|
should "return any given data" do
|
85
|
-
add_hash = { 1 =>
|
72
|
+
add_hash = { 1 => "1" }
|
86
73
|
add_array = [3, 4]
|
87
|
-
|
88
|
-
|
89
|
-
|
74
|
+
assert_that(n.__nm_add_partial_data__(add_hash)).equals(add_hash)
|
75
|
+
assert_that(n.__nm_add_partial_data__(add_array)).equals(add_array)
|
76
|
+
assert_that(n.__nm_add_partial_data__(nil)).equals(n)
|
90
77
|
end
|
91
|
-
|
92
78
|
end
|
93
|
-
|
94
79
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "assert"
|
4
|
+
require "nm"
|
5
|
+
|
6
|
+
module Nm
|
7
|
+
class UnitTests < Assert::Context
|
8
|
+
desc "Nm"
|
9
|
+
subject{ unit_class }
|
10
|
+
|
11
|
+
let(:unit_class){ Nm }
|
12
|
+
|
13
|
+
should have_imeths :default_context_class, :default_context
|
14
|
+
|
15
|
+
should "know its attributes" do
|
16
|
+
assert_that(subject.default_context_class).is_a(Class)
|
17
|
+
assert_that(subject.default_context).is_a(subject.default_context_class)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|