tickly 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -18,7 +18,8 @@ module Tickly
18
18
  handler_class = @node_handlers.find{|e| unconst_name(e) == expr[0]}
19
19
  handler_arguments = expr[1]
20
20
  hash_of_args = {}
21
- expr[1].map do | e |
21
+ # Use 1..-1 to skip the curly brace symbol
22
+ expr[1][1..-1].map do | e |
22
23
  # The name of the command is the first element, always
23
24
  hash_of_args[e[0]] = e[1]
24
25
  end
@@ -41,7 +42,7 @@ module Tickly
41
42
  end
42
43
 
43
44
  def has_subcommand?(expr)
44
- expr[1].is_a?(LiteralExpr)
45
+ expr[1][0] == :c
45
46
  end
46
47
  end
47
48
  end
@@ -0,0 +1,22 @@
1
+ module Tickly
2
+ # A more refined version of the Parser class that can scope itself to the passed Nuke node
3
+ # classnames. It will toss all of the node data that is not relevant, keeping only nodes that are
4
+ # required.
5
+ class NodeExtractor < Parser
6
+ def initialize(*interesting_node_class_names)
7
+ @nodes = interesting_node_class_names
8
+ end
9
+
10
+ # Override this to remove any unneeded subexpressions
11
+ def expand_subexpr!(expr, at_depth)
12
+ if is_node_constructor?(expr, at_depth)
13
+ node_class_name = expr[0]
14
+ expr.replace([:discarded]) unless @nodes.include?(node_class_name)
15
+ end
16
+ end
17
+
18
+ def is_node_constructor?(expr, depth)
19
+ depth == 1 && expr[0].is_a?(String) && expr.length == 2 && expr[1][0] == :c
20
+ end
21
+ end
22
+ end
data/lib/tickly/parser.rb CHANGED
@@ -3,14 +3,18 @@ require 'stringio'
3
3
  module Tickly
4
4
 
5
5
  class Parser
6
-
6
+
7
7
  # Parses a piece of TCL and returns it converted into internal expression
8
- # structures (nested StringExpr or LiteralExp objects).
8
+ # structures (nested StringExpr or LiteralExpr objects).
9
9
  def parse(io_or_str)
10
10
  io = io_or_str.respond_to?(:read) ? io_or_str : StringIO.new(io_or_str)
11
11
  sub_parse(io)
12
12
  end
13
13
 
14
+ # Override this to remove any unneeded subexpressions
15
+ def expand_subexpr!(expr, at_depth)
16
+ end
17
+
14
18
  private
15
19
 
16
20
  LAST_CHAR = -1..-1 # If we were 1.9 only we could use -1
@@ -19,55 +23,98 @@ module Tickly
19
23
  # or until the IO is exhausted. The last argument is the class used to
20
24
  # compose the subexpression being parsed. The subparser is reentrant and not
21
25
  # destructive for the object containing it.
22
- def sub_parse(io, stop_char = nil, expr_class = LiteralExpr)
26
+ def sub_parse(io, stop_char = nil, stack_depth = 0)
23
27
  # A standard stack is an expression that does not evaluate to a string
24
- stack = expr_class.new
28
+ stack = []
25
29
  buf = ''
30
+ last_char_was_linebreak = false
26
31
  until io.eof?
27
32
  char = io.read(1)
28
33
 
29
34
  if buf[LAST_CHAR] != ESC
30
35
  if char == stop_char # Bail out of a subexpr
31
36
  stack << buf if (buf.length > 0)
32
- return cleanup(stack)
37
+ # Chip away the tailing linebreak if it's there
38
+ chomp!(stack)
39
+ return stack
33
40
  elsif char == " " || char == "\n" # Space
34
41
  if buf.length > 0
35
42
  stack << buf
36
43
  buf = ''
37
44
  end
38
45
  if char == "\n" # Introduce a stack separator! This is a new line
39
- stack << nil
46
+ if stack.any? && !last_char_was_linebreak
47
+ last_char_was_linebreak = true
48
+ stack = handle_expr_terminator(stack, stack_depth)
49
+ end
40
50
  end
41
51
  elsif char == '[' # Opens a new string expression
42
52
  stack << buf if (buf.length > 0)
43
- stack << sub_parse(io, ']', StringExpr)
53
+ last_char_was_linebreak = false
54
+ stack << [:b] + sub_parse(io, ']', stack_depth + 1)
44
55
  elsif char == '{' # Opens a new literal expression
45
56
  stack << buf if (buf.length > 0)
46
- stack << sub_parse(io, '}', LiteralExpr)
57
+ last_char_was_linebreak = false
58
+ stack << [:c] + sub_parse(io, '}', stack_depth + 1)
47
59
  elsif char == '"'
48
60
  stack << buf if (buf.length > 0)
61
+ last_char_was_linebreak = false
49
62
  stack << parse_str(io, '"')
50
63
  elsif char == "'"
51
64
  stack << buf if (buf.length > 0)
65
+ last_char_was_linebreak = false
52
66
  stack << parse_str(io, "'")
53
67
  else
68
+ last_char_was_linebreak = false
54
69
  buf << char
55
70
  end
56
71
  else
72
+ last_char_was_linebreak = false
57
73
  buf << char
58
74
  end
59
75
  end
60
76
 
61
77
  # Ramass any remaining buffer contents
62
78
  stack << buf if (buf.length > 0)
63
-
64
- cleanup(stack)
79
+
80
+ # Handle any remaining subexpressions
81
+ if stack.include?(nil)
82
+ stack = handle_expr_terminator(stack, stack_depth)
83
+ end
84
+ # Chip awiy the trailing null
85
+ chomp!(stack)
86
+
87
+ return stack
65
88
  end
66
89
 
67
- private
68
-
69
90
  ESC = 92.chr # Backslash (\)
70
91
 
92
+ def chomp!(stack)
93
+ stack.delete_at(-1) if stack.any? && stack[-1].nil?
94
+ end
95
+
96
+ def handle_expr_terminator(stack, stack_depth)
97
+ # Figure out whether there was a previous expr terminator
98
+ previous_i = stack.index(nil)
99
+ # If there were none, just get this over with. Wrap the stack contents
100
+ # into a subexpression and carry on.
101
+ unless previous_i
102
+ subexpr = stack
103
+ expand_subexpr!(subexpr, stack_depth + 1)
104
+ return [subexpr] + [nil]
105
+ end
106
+
107
+ # Now, if there was one, we are the next subexpr in line that just terminated.
108
+ # What we need to do is pick out all the elements from that terminator onwards
109
+ # and wrap them.
110
+ subexpr = stack[previous_i+1..-1]
111
+
112
+ # Use expand_subexpr! to trim away any fat that we don't need
113
+ expand_subexpr!(subexpr, stack_depth + 1)
114
+
115
+ return stack[0...previous_i] + [subexpr] + [nil]
116
+ end
117
+
71
118
  def parse_str(io, stop_char)
72
119
  buf = ''
73
120
  until io.eof?
@@ -85,19 +132,5 @@ module Tickly
85
132
  return buf
86
133
  end
87
134
 
88
- # Tells whether a passed object is a StringExpr or LiteralExpr
89
- def expr?(something)
90
- [StringExpr, LiteralExpr].include?(something.class)
91
- end
92
-
93
- # Cleans up a subexpression stack. Currently it only removes nil objects
94
- # in-between items (which act as line separators)
95
- def cleanup(expr)
96
- # Ensure multiple consecutive line breaks are ignored
97
- no_multiple_breaks = Tickly.singularize_nils_in(expr)
98
- # Convert line breaks into subexpressions
99
- Tickly.split_array(no_multiple_breaks)
100
- end
101
-
102
135
  end
103
136
  end
data/lib/tickly.rb CHANGED
@@ -1,70 +1,30 @@
1
1
  require File.dirname(__FILE__) + "/tickly/parser"
2
+ require File.dirname(__FILE__) + "/tickly/node_extractor"
2
3
  require File.dirname(__FILE__) + "/tickly/evaluator"
3
4
  require 'forwardable'
4
5
 
5
6
  module Tickly
6
- VERSION = '0.0.3'
7
-
8
- # Represents a TCL expression with it's arguments (in curly or square braces)
9
- class Expr
10
- extend Forwardable
11
-
12
- def_delegators :@e, :push, :<<, :any?, :reject!, :map!, :[], :delete_at, :include?, :each, :each_with_index, :empty?, :join, :length
13
-
14
- def initialize(elements = [])
15
- @e = elements
16
- end
17
-
18
- def map(&blk)
19
- self.class.new(@e.map(&blk))
20
- end
21
-
22
- def to_a
23
- @e
24
- end
25
-
26
- def ==(another)
27
- another.to_a == to_a
28
- end
29
-
30
- def inspect
31
- @e.map{|e| e.inspect }.join(', ')
32
- end
33
-
34
- end
35
-
36
- # Represents an expression between curly braces (within which no text substitution will be done)
37
- # like { 1 2 3 }
38
- class LiteralExpr < Expr
39
- def inspect
40
- "le(%s)" % super
41
- end
42
- end
43
-
44
- # Represents an expression between square brackets (where text substitution will be done)
45
- # like [1 2 3]
46
- class StringExpr < Expr
47
- def inspect
48
- "se(%s)" % super
49
- end
50
- end
7
+ VERSION = '0.0.4'
51
8
 
52
9
  # Provides the methods for quickly emitting the LiteralExpr and StringExpr objects
53
10
  module Emitter
54
11
  def le(*elems)
55
- LiteralExpr.new(elems)
12
+ [:c] + elems
13
+ end
14
+
15
+ def e(*elems)
16
+ elems
56
17
  end
57
18
 
58
19
  def se(*elems)
59
- LiteralExpr.new(elems)
20
+ [:b] + elems
60
21
  end
61
22
  end
62
23
 
63
-
64
24
  def self.to_tcl(e)
65
- if e.is_a?(Tickly::LiteralExpr)
25
+ if e.is_a?(Array) && e[0] == :c
66
26
  '{%s}' % e.map{|e| to_tcl(e)}.join(' ')
67
- elsif e.is_a?(Tickly::StringExpr)
27
+ elsif e.is_a?(Array) && e[0] == :b
68
28
  '[%s]' % e.map{|e| to_tcl(e)}.join(' ')
69
29
  elsif e.is_a?(String) && (e.include?('"') || e.include?("'"))
70
30
  e.inspect
@@ -73,39 +33,5 @@ module Tickly
73
33
  end
74
34
  end
75
35
 
76
- # Splits the passed Array-like object into sub-arrays of the same class,
77
- # delimited by the passed separator. Note that when the separators occur at the beginning or at the end of
78
- # the passed object they will be discarded
79
- def self.split_array(arr, separator = nil)
80
- return arr unless arr.include?(separator)
81
-
82
- subarrays = arr.class.new
83
- subarrays.push(arr.class.new)
84
-
85
- arr.each_with_index do | element, i |
86
- if element == separator && subarrays.length > 0 && subarrays[-1].any? && (i < (arr.length - 1))
87
- subarrays.push(arr.class.new)
88
- elsif element == separator
89
- # toss it
90
- else
91
- subarrays[-1].push(element)
92
- end
93
- end
94
- return subarrays
95
- end
96
-
97
- # Removes consecutive nils from the passed Array-like object and returns a new one with all consecutive nils reduced
98
- # to one nil
99
- def self.singularize_nils_in(arr)
100
- new_arr = arr.class.new
101
- arr.each_with_index do | elem, i |
102
- if elem.nil? && arr[i-1].nil? && i > 0
103
- # pass
104
- else
105
- new_arr << elem
106
- end
107
- end
108
- new_arr
109
- end
110
36
 
111
37
  end
@@ -16,4 +16,4 @@ Group {
16
16
  Output {
17
17
  name Output1
18
18
  }
19
- end_group
19
+ end_group
@@ -16,7 +16,7 @@ class TestEvaluator < Test::Unit::TestCase
16
16
  end
17
17
 
18
18
  should "not send anything to the handler when the expr does not conform to the standard" do
19
- stack = le("ShouldNotBeInstantiated")
19
+ stack = e("ShouldNotBeInstantiated")
20
20
  e = Tickly::Evaluator.new
21
21
  e.add_node_handler_class(ShouldNotBeInstantiated)
22
22
  assert_nothing_raised { e.evaluate(stack) }
@@ -29,8 +29,8 @@ class TestEvaluator < Test::Unit::TestCase
29
29
  end
30
30
  end
31
31
 
32
- should "instantiate the handler class" do
33
- stack = le("SomeNode", le(le("foo", "bar"), le("baz", "bad")))
32
+ def test_instantiates_handler_class
33
+ stack = e("SomeNode", le(e("foo", "bar"), e("baz", "bad")))
34
34
  e = Tickly::Evaluator.new
35
35
  e.add_node_handler_class(SomeNode)
36
36
  node = e.evaluate(stack)
@@ -0,0 +1,30 @@
1
+ require 'helper'
2
+
3
+ class TestNodeExtractor < Test::Unit::TestCase
4
+
5
+ include Tickly::Emitter
6
+
7
+ def test_parsing_nuke_script_with_indentations
8
+ f = File.open(File.dirname(__FILE__) + "/test-data/nuke_group.txt")
9
+ x = Tickly::NodeExtractor.new("Group")
10
+
11
+ p = x.parse(f)
12
+ grp = e(
13
+ e("set", "cut_paste_input", se("stack", "0")),
14
+ e("version", "6.3", "v4"),
15
+ e("Group",
16
+ le(
17
+ e("inputs", "0"),
18
+ e("name", "Group1"),
19
+ e("selected", "true")
20
+ )
21
+ ),
22
+ e(:discarded),
23
+ e(:discarded),
24
+ e(:discarded),
25
+ e("end_group")
26
+ )
27
+ assert_equal grp, p
28
+ end
29
+
30
+ end
data/test/test_parser.rb CHANGED
@@ -5,72 +5,65 @@ class TestParser < Test::Unit::TestCase
5
5
  include Tickly::Emitter
6
6
 
7
7
  should "parse a single int as a stack with a string" do
8
- assert_kind_of Tickly::LiteralExpr, P.parse('2')
9
- assert_equal le("2"), P.parse('2')
8
+ assert_equal e("2"), P.parse('2')
10
9
  end
11
10
 
12
11
  should "parse a single int and discard whitespace" do
13
12
  p = P.parse(' 2 ')
14
- assert_kind_of Tickly::LiteralExpr, p
15
- assert_equal le("2"), p
16
- assert_equal "{2}", Tickly.to_tcl(p)
13
+ assert_equal e("2"), p
17
14
  end
18
15
 
19
16
  should "parse multiple ints and strings as a stack of subexpressions" do
20
- assert_kind_of Tickly::LiteralExpr, P.parse('2 foo bar baz')
21
- assert_equal le("2", "foo", "bar", "baz"), P.parse('2 foo bar baz')
17
+ assert_equal e("2", "foo", "bar", "baz"), P.parse('2 foo bar baz')
22
18
  end
23
19
 
24
20
  should "parse and expand a string in double quotes" do
25
21
  p = P.parse('"This is a string literal with spaces"')
26
- assert_equal le("This is a string literal with spaces"), p
22
+ assert_equal e("This is a string literal with spaces"), p
27
23
 
28
24
  p = P.parse('"This is a string literal \"escaped\" with spaces"')
29
- assert_equal le("This is a string literal \"escaped\" with spaces"), p
25
+ assert_equal e("This is a string literal \"escaped\" with spaces"), p
30
26
  end
31
27
 
32
28
  should "parse a string expression" do
33
- p = P.parse("[1 2 3]")
34
- assert_kind_of Tickly::LiteralExpr, p
35
- assert_equal 1, p.length
36
- assert_kind_of Tickly::StringExpr, p[0]
29
+ assert_equal e(se("1", "2", "3")), P.parse("[1 2 3]")
37
30
  end
38
31
 
39
32
  should "parse multiple string expressions" do
40
33
  p = P.parse("[1 2 3] [3 4 5 foo]")
41
- assert_equal le(se("1", "2", "3"), se("3", "4", "5", "foo")), p
34
+ assert_equal e(se("1", "2", "3"), se("3", "4", "5", "foo")), p
42
35
  end
43
36
 
44
- should "parse multiline statements as literal expressions" do
37
+ def test_parse_multiline_statements_as_literal_expressions
45
38
  p = P.parse("2\n2")
46
- assert_equal "{{2} {2}}", Tickly.to_tcl(p)
39
+ assert_equal e(e("2"), e("2")), p
47
40
  end
48
41
 
49
- should 'parse expression' do
42
+ def test_parse_expr
50
43
  expr = '{4 + 5}'
51
44
  p = P.parse(expr)
52
- assert_equal le(le("4", "+", "5")), p
45
+ assert_equal e(le("4", "+", "5")), p
53
46
  end
54
47
 
55
- should 'parse a Nuke node' do
48
+ def test_parsing_a_nuke_node
56
49
  f = File.open(File.dirname(__FILE__) + "/test-data/nukenode.txt")
57
50
  p = P.parse(f)
58
- script = le(
59
- le("set", "cut_paste_input", se("stack", "0")),
60
- le("version", "6.3", "v4"),
61
- le("push", "$cut_paste_input"),
62
- le("Blur",
51
+ script = e(
52
+ e("set", "cut_paste_input", se("stack", "0")),
53
+ e("version", "6.3", "v4"),
54
+ e("push", "$cut_paste_input"),
55
+ e("Blur",
63
56
  le(
64
- le("size",
57
+ e("size",
65
58
  le(
66
59
  le("curve", "x1", "0", "x20", "1.7", "x33", "3.9")
67
60
  )
68
61
  ),
69
- le("name", "Blur1"),
70
- le("label", "With \"Escapes\""),
71
- le("selected", "true"),
72
- le("xpos", "-353"),
73
- le("ypos", "-33")
62
+ e("name", "Blur1"),
63
+ e("label", "With \"Escapes\""),
64
+ e("selected", "true"),
65
+ e("xpos", "-353"),
66
+ e("ypos", "-33")
74
67
  )
75
68
  )
76
69
  )
@@ -81,54 +74,54 @@ class TestParser < Test::Unit::TestCase
81
74
  f = File.open(File.dirname(__FILE__) + "/test-data/three_nodes_and_roto.txt")
82
75
  p = P.parse(f)
83
76
  # Should pass through the rotopaint node and get to the blur properly
84
- blur = le("Blur",
77
+ blur = e("Blur",
85
78
  le(
86
- le("size",
79
+ e("size",
87
80
  le(
88
81
  le("curve", "i", "x1", "0", "x20", "1.7", "x33", "3.9")
89
82
  )
90
83
  ),
91
- le("name", "Blur1"),
92
- le("label", "With \"Escapes\""),
93
- le("selected", "true"),
94
- le("xpos", "-212"),
95
- le("ypos", "-24")
84
+ e("name", "Blur1"),
85
+ e("label", "With \"Escapes\""),
86
+ e("selected", "true"),
87
+ e("xpos", "-212"),
88
+ e("ypos", "-24")
96
89
  )
97
90
  )
98
91
  assert_equal blur, p[4]
99
92
  end
100
93
 
101
- should 'parse a Nuke script with indentations' do
94
+ def test_parsing_nuke_script_with_indentations
102
95
  f = File.open(File.dirname(__FILE__) + "/test-data/nuke_group.txt")
103
96
  p = P.parse(f)
104
- grp = le(
105
- le("set", "cut_paste_input", se("stack", "0")),
106
- le("version", "6.3", "v4"),
107
- le("Group",
97
+ grp = e(
98
+ e("set", "cut_paste_input", se("stack", "0")),
99
+ e("version", "6.3", "v4"),
100
+ e("Group",
108
101
  le(
109
- le("inputs", "0"),
110
- le("name", "Group1"),
111
- le("selected", "true")
102
+ e("inputs", "0"),
103
+ e("name", "Group1"),
104
+ e("selected", "true")
112
105
  )
113
106
  ),
114
- le("CheckerBoard2",
107
+ e("CheckerBoard2",
115
108
  le(
116
- le("inputs", "0"),
117
- le("name", "CheckerBoard1")
109
+ e("inputs", "0"),
110
+ e("name", "CheckerBoard1")
118
111
  )
119
112
  ),
120
- le("Blur",
113
+ e("Blur",
121
114
  le(
122
- le("size", "42.5"),
123
- le("name", "Blur1")
115
+ e("size", "42.5"),
116
+ e("name", "Blur1")
124
117
  )
125
118
  ),
126
- le("Output",
119
+ e("Output",
127
120
  le(
128
- le("name", "Output1")
121
+ e("name", "Output1")
129
122
  )
130
123
  ),
131
- le("end_group")
124
+ e("end_group")
132
125
  )
133
126
  assert_equal grp, p
134
127
  end
@@ -136,9 +129,9 @@ class TestParser < Test::Unit::TestCase
136
129
  def test_one_node_parsing
137
130
  f = File.open(File.dirname(__FILE__) + "/test-data/one_node_with_one_param.txt")
138
131
  p = P.parse(f)
139
- ref = le("SomeNode",
132
+ ref = e("SomeNode",
140
133
  le(
141
- le("foo", "bar")
134
+ e("foo", "bar")
142
135
  )
143
136
  )
144
137
 
data/tickly.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "tickly"
8
- s.version = "0.0.3"
8
+ s.version = "0.0.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Julik Tarkhanov"]
12
- s.date = "2013-03-11"
12
+ s.date = "2013-03-12"
13
13
  s.description = "Parses the subset of the TCL grammar needed for Nuke scripts"
14
14
  s.email = "me@julik.nl"
15
15
  s.extra_rdoc_files = [
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  "Rakefile",
26
26
  "lib/tickly.rb",
27
27
  "lib/tickly/evaluator.rb",
28
+ "lib/tickly/node_extractor.rb",
28
29
  "lib/tickly/parser.rb",
29
30
  "test/helper.rb",
30
31
  "test/test-data/nuke7_tracker_2tracks.nk",
@@ -37,8 +38,8 @@ Gem::Specification.new do |s|
37
38
  "test/test-data/tracker_with_differing_gaps.nk",
38
39
  "test/test-data/tracker_with_repeating_gaps.nk",
39
40
  "test/test_evaluator.rb",
41
+ "test/test_node_extractor.rb",
40
42
  "test/test_parser.rb",
41
- "test/test_split_array.rb",
42
43
  "tickly.gemspec"
43
44
  ]
44
45
  s.homepage = "http://github.com/julik/tickly"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tickly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-11 00:00:00.000000000 Z
12
+ date: 2013-03-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: shoulda
@@ -91,6 +91,7 @@ files:
91
91
  - Rakefile
92
92
  - lib/tickly.rb
93
93
  - lib/tickly/evaluator.rb
94
+ - lib/tickly/node_extractor.rb
94
95
  - lib/tickly/parser.rb
95
96
  - test/helper.rb
96
97
  - test/test-data/nuke7_tracker_2tracks.nk
@@ -103,8 +104,8 @@ files:
103
104
  - test/test-data/tracker_with_differing_gaps.nk
104
105
  - test/test-data/tracker_with_repeating_gaps.nk
105
106
  - test/test_evaluator.rb
107
+ - test/test_node_extractor.rb
106
108
  - test/test_parser.rb
107
- - test/test_split_array.rb
108
109
  - tickly.gemspec
109
110
  homepage: http://github.com/julik/tickly
110
111
  licenses:
@@ -121,7 +122,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
122
  version: '0'
122
123
  segments:
123
124
  - 0
124
- hash: 592217362083330592
125
+ hash: -2196296843243875248
125
126
  required_rubygems_version: !ruby/object:Gem::Requirement
126
127
  none: false
127
128
  requirements:
@@ -1,28 +0,0 @@
1
- require 'helper'
2
-
3
- class TestSplitArray < Test::Unit::TestCase
4
- should "return a standard array unscathed" do
5
- assert_equal [1, 2, 3, 4], Tickly.split_array([1,2,3,4])
6
- end
7
-
8
- should "return a split array on nil" do
9
- assert_equal [[1, 2], [3, 4]], Tickly.split_array([1, 2, nil, 3, 4])
10
- end
11
-
12
- should "only generate sub-elements where they make sense" do
13
- assert_equal [[1, 2]], Tickly.split_array([nil, 1, 2, nil])
14
- end
15
-
16
- class Jock < Array; end
17
-
18
- should "properly use subclasses" do
19
- s = Tickly.split_array(Jock.new([1, 2, nil, 3, 4]))
20
- assert_kind_of Jock, s
21
- assert_kind_of Jock, s[0]
22
- end
23
-
24
- should 'squeeze nils out' do
25
- s = Tickly.singularize_nils_in([nil, nil, 1,2,3,4, nil, nil, 456, nil, 9,nil,nil])
26
- assert_equal [nil, 1,2,3,4, nil, 456, nil, 9, nil], s
27
- end
28
- end