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.
@@ -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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Nm
2
- VERSION = "0.5.4"
4
+ VERSION = "0.6.0"
3
5
  end
data/nm.gemspec CHANGED
@@ -1,5 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
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 = %q{Data templating system.}
12
- gem.description = %q{Data templating system.}
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 = 'MIT'
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.add_development_dependency("assert", ["~> 2.16.1"])
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 'pathname'
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('test/support/templates')
12
+ TEMPLATE_ROOT = ROOT.join("test/support/templates")
11
13
 
12
14
  # require pry for debugging (`binding.pry`)
13
- require 'pry'
14
-
15
- require 'test/support/factory'
16
-
17
- # 1.8.7 backfills
15
+ require "pry"
18
16
 
19
- # Array#sample
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"
@@ -1,4 +1,6 @@
1
- require 'assert/factory'
1
+ # frozen_string_literal: true
2
+
3
+ require "assert/factory"
2
4
 
3
5
  module Factory
4
6
  extend Assert::Factory
@@ -10,5 +12,4 @@ module Factory
10
12
  def self.template_file(name)
11
13
  TEMPLATE_ROOT.join(name).to_s
12
14
  end
13
-
14
15
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  map [1, 2, 3] do |num|
2
4
  node num.to_s, num
3
5
  end
@@ -1,3 +1,5 @@
1
- node 'locals' do
2
- node 'key', key
1
+ # frozen_string_literal: true
2
+
3
+ node "locals" do
4
+ node "key", key
3
5
  end
@@ -1,3 +1,5 @@
1
- node 'a', 'Aye'
2
- node 'b', 'Bee'
3
- node 'c', "See"
1
+ # frozen_string_literal: true
2
+
3
+ node "a", "Aye"
4
+ node "b", "Bee"
5
+ node "c", "See"
@@ -1,4 +1,9 @@
1
- _map (1..1) do
2
- n 'node local value', node
3
- _node 'map local value', map
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,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  map [1, 2, 3] do |num|
2
4
  node num.to_s, num
3
5
  end
@@ -1,3 +1,5 @@
1
- node 'locals' do
2
- node 'key', key
1
+ # frozen_string_literal: true
2
+
3
+ node "locals" do
4
+ node "key", key
3
5
  end
@@ -1,3 +1,3 @@
1
- node 'locals' do
2
- node 'key', key
1
+ node "locals" do
2
+ node "key", key
3
3
  end
@@ -1,5 +1,7 @@
1
- node 'obj' do
2
- node 'a', 'Aye'
3
- node 'b', 'Bee'
4
- node 'c', "See"
1
+ # frozen_string_literal: true
2
+
3
+ node "obj" do
4
+ node "a", "Aye"
5
+ node "b", "Bee"
6
+ node "c", "See"
5
7
  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
@@ -1,94 +1,79 @@
1
- require 'assert'
2
- require 'nm/ext'
1
+ # frozen_string_literal: true
3
2
 
4
- module Nm::Ext
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 and invalid runtime error" do
11
- assert_kind_of ::RuntimeError, subject::InvalidError.new
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 "__nm_add_call_data__"
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
- assert_responds_to :__nm_add_call_data__, ::Hash.new
20
+ assert_that({}).responds_to(:__nm_add_partial_data__)
24
21
  end
25
22
 
26
23
  should "be added to ::Array" do
27
- assert_responds_to :__nm_add_call_data__, ::Array.new
24
+ assert_that([]).responds_to(:__nm_add_partial_data__)
28
25
  end
29
26
 
30
27
  should "be added to nil" do
31
- assert_responds_to :__nm_add_call_data__, nil
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
- setup do
39
- @h = { 1 => '1' }
40
- end
34
+
35
+ let(:h){ { 1 => "1" } }
41
36
 
42
37
  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)
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
- assert_raises Nm::InvalidError do
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
- setup do
60
- @a = [1, 2]
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
- 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)
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
- assert_raises Nm::InvalidError do
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
- setup do
81
- @n = nil
82
- end
68
+
69
+ let(:n){ nil }
83
70
 
84
71
  should "return any given data" do
85
- add_hash = { 1 => '1' }
72
+ add_hash = { 1 => "1" }
86
73
  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)
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