sequitur 0.1.07 → 0.1.09

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NzBkNjMyMWI2NjUxNDUxMWE0ZDg0Y2MxOTQ5NDViMThkZjk5NDlhNQ==
4
+ M2JmMGMzOGFjNjg3YmQzZDNlMWNjODI2ZmIzNjA4MTM4ZDNkMzUzZA==
5
5
  data.tar.gz: !binary |-
6
- NmFjODAxMDdiODNmNDdiYmQwNTMzOGJiMmY5NDVhOTFkMjUyOTEyMw==
6
+ ZTAyMGI0MDYzMDBkMDJlNWFhNjE2Yjc5NTUyZjhiNDEzZjEzYzg1ZQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZTBhYzNkMmM2ZTExOTQwNmIzMTlmYmUxNTVlZTY1MjJjYmMwMzYxZmEwMjhm
10
- MWY1MDJhZDY3ZTdhZWEwZjRiY2M3Yjc1NTY4ZjkxYzZiMWNkYjY2YTA3Zjhh
11
- MTY0ZmMxZTAyYTMxYWE3MmJhMjE0MDFiMWViMWUxYmQ1ZDQwOWU=
9
+ OGQ1YjVhY2M2MmM2YWNiODYyYzQxMmRjNmFmYWY2NjYyMGYyMWM5YjVjNzFh
10
+ OTVmMDhhZTE2YTRhMWNmODVhYTJjMDUyMDNlYjk0NmJjMjRkN2Q0ODcyYTRj
11
+ YzAyZDA2ZDJiY2E1YWE5ZTYyYWExNmJkMzI3ODYyZDgwZGUyMzI=
12
12
  data.tar.gz: !binary |-
13
- NjBkYmE4MjYwNGQxODFkMjJlZGFkNWI1Yzc3YmE0OWY5OWQyNGZmZTZhNzQ5
14
- ZTA4NDhiMWQwMGFiM2EzODczOTJkZTA4OTlhZmY0NzUwMDBlMTJmZDM2MjY1
15
- OWU0MzM3NjdhYWNhNDAyOTQ1MDc5YzQ5ZWJkZTY3YjcxMDkzNjI=
13
+ N2EyZmU3NTNiMTc1YmZkZjk4ODNmMzYyY2ExYzI0YTNmNTFlYWY4OWUxZTQ4
14
+ NjJmMWUzYzM3Yjc4ZDU5YzIyNTEwZTI5OWI1ZDlhY2RiYzQ3Yzc5OTgxZDZk
15
+ MzY1MzEwMDBjYTliYmQxYTEwYzQ4MjQzYzFjYjVhNDgxMGE4YTA=
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ### 0.1.09 / 2014-10-03
2
+ * [NEW] Class `SymbolSequence`. Part of code refactoring that reduces code complexity reported by CodeClimate.
3
+ * [CHANGE] Class `Production` refactored to use a SymbolSequence instance as its rhs.
4
+ * [CHANGE] File `README.md`: Minor cosmetic enhancements.
5
+
6
+ ### 0.1.08 / 2014-09-30
7
+ * [CHANGE] Method `SequiturGrammar#restore_unicity` Code refactored to reduce code complexity reported by CodeClimate.
8
+ * [CHANGE] File `README.md`: Minor cosmetic enhancements.
9
+
1
10
  ### 0.1.07 / 2014-09-29
2
11
  * [CHANGE] File `README.md`: Fixed bad Markdown syntax in badge part.
3
12
 
data/README.md CHANGED
@@ -8,7 +8,7 @@ _Ruby gem implementing the Sequitur algorithm_
8
8
  [![Gem Version](https://badge.fury.io/rb/sequitur.svg)](http://badge.fury.io/rb/sequitur)
9
9
  [![Dependency Status](https://gemnasium.com/famished-tiger/Sequitur.png)](https://gemnasium.com/famished-tiger/Sequitur)
10
10
  [![Inline docs](http://inch-ci.org/github/famished-tiger/Sequitur.svg?branch=master)](http://inch-ci.org/github/famished-tiger/Sequitur)
11
-
11
+ [![Code Climate](https://codeclimate.com/github/famished-tiger/Sequitur.png)](https://codeclimate.com/github/famished-tiger/Sequitur)
12
12
 
13
13
  ### What is the Sequitur algorithm? ###
14
14
  The following are good entry points to learn about the algorithm:
@@ -23,7 +23,7 @@ in a very compact way.
23
23
  Of interest is the fact that the algorithm runs in time linear in the length of the input sequence.
24
24
 
25
25
  **Can you give a simple example?**
26
- Sure. Let's begin with a very basic case. Assume that 'abcabcabc' is our input string.
26
+ Sure. Let's begin with a very basic case. Assume that *'abcabcabc'* is our input string.
27
27
  Notice that it is the same as the text 'abc' repeated three times. The Sequitur algorithm captures
28
28
  this repetition and will generate the two following rules:
29
29
 
@@ -32,13 +32,13 @@ start : P1 P1 P1.
32
32
  P1 : a b c.
33
33
  ```
34
34
 
35
- In plain English:
35
+ In plain English:
36
36
  -The first rule (named start) always represents the whole input. Here, it indicates that the input
37
- is three time the pattern encoded by the rule called P1.
38
- -The second rule (named P1) represents the sequence a b c.
37
+ is three time the pattern encoded by the rule called P1.
38
+ -The second rule (named P1) represents the sequence a b c.
39
39
 
40
40
  **Can you give another example?**
41
- Yep. Assume this time that the input is 'ababcabcdabcde'.
41
+ Yep. Assume this time that the input is *'ababcabcdabcde'*.
42
42
  Then Sequitur algorithm will generate the rule set:
43
43
  ```
44
44
  start : P1 P2 P3 P3 e.
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Sequitur # Module used as a namespace
5
5
  # The version number of the gem.
6
- Version = '0.1.07'
6
+ Version = '0.1.09'
7
7
 
8
8
  # Brief description of the gem.
9
9
  Description = 'Ruby implementation of the Sequitur algorithm'
@@ -47,7 +47,12 @@ class GrammarVisitor
47
47
  # @param aProduction [Production] the production to visit.
48
48
  def start_visit_production(aProduction)
49
49
  broadcast(:before_production, aProduction)
50
- broadcast(:before_rhs, aProduction.rhs)
50
+ end
51
+
52
+ # Visit event. The visitor is about to visit the given rhs of production.
53
+ # @param rhs [SymbolSequence] the rhs of a production to visit.
54
+ def start_visit_rhs(rhs)
55
+ broadcast(:before_rhs, rhs)
51
56
  end
52
57
 
53
58
  # Visit event. The visitor is visiting the
@@ -66,13 +71,17 @@ class GrammarVisitor
66
71
  broadcast(:before_terminal, aTerminal)
67
72
  broadcast(:after_terminal, aTerminal)
68
73
  end
74
+
75
+ # Visit event. The visitor has completed its visit of the given rhs.
76
+ # @param rhs [SymbolSequence] the rhs of a production to visit.
77
+ def end_visit_rhs(rhs)
78
+ broadcast(:after_rhs, rhs)
79
+ end
69
80
 
70
81
  # Visit event. The visitor has completed its visit of the given production.
71
82
  # @param aProduction [Production] the production to visit.
72
83
  def end_visit_production(aProduction)
73
- broadcast(:after_rhs, aProduction.rhs)
74
84
  broadcast(:after_production, aProduction)
75
-
76
85
  end
77
86
 
78
87
  # Visit event. The visitor has completed the visit of the grammar.
@@ -1,4 +1,5 @@
1
1
  require_relative 'digram'
2
+ require_relative 'symbol_sequence'
2
3
  require_relative 'production_ref'
3
4
 
4
5
  module Sequitur # Module for classes implementing the Sequitur algorithm
@@ -25,10 +26,12 @@ class Production
25
26
  # Constructor.
26
27
  # Build a production with an empty RHS.
27
28
  def initialize()
28
- clear_rhs
29
+ @rhs = SymbolSequence.new
29
30
  @refcount = 0
30
31
  @digrams = []
31
32
  end
33
+
34
+
32
35
 
33
36
  public
34
37
 
@@ -69,7 +72,7 @@ class Production
69
72
  # Select the references to production appearing in the rhs.
70
73
  # @return [Array of ProductionRef]
71
74
  def references()
72
- return rhs.select { |symb| symb.is_a?(ProductionRef) }
75
+ return rhs.references
73
76
  end
74
77
 
75
78
  # Look in the rhs all the references to a production passed a argument.
@@ -87,8 +90,7 @@ class Production
87
90
  return [] if rhs.size < 2
88
91
 
89
92
  result = []
90
- rhs.each_cons(2) { |couple| result << Digram.new(*couple, self) }
91
-
93
+ rhs.symbols.each_cons(2) { |couple| result << Digram.new(*couple, self) }
92
94
  @digrams = result
93
95
  end
94
96
 
@@ -129,14 +131,7 @@ class Production
129
131
  # object id of production : rhs as space-separated sequence of symbols.
130
132
  # @return [String]
131
133
  def to_string()
132
- rhs_text = rhs.map do |elem|
133
- case elem
134
- when String then "'#{elem}'"
135
- else elem.to_s
136
- end
137
- end
138
-
139
- return "#{object_id} : #{rhs_text.join(' ')}."
134
+ return "#{object_id} : #{rhs.to_string}."
140
135
  end
141
136
 
142
137
  # Add a (grammar) symbol at the end of the RHS.
@@ -163,11 +158,7 @@ class Production
163
158
  # Clear the right-hand side.
164
159
  # Any referenced production has its reference counter decremented.
165
160
  def clear_rhs()
166
- if rhs
167
- refs = references
168
- refs.each(&:unbind)
169
- end
170
- @rhs = []
161
+ rhs.clear()
171
162
  end
172
163
 
173
164
  # Find all the positions where the digram occurs in the rhs
@@ -203,20 +194,11 @@ class Production
203
194
  # @param another [Production or ProductionRef] a production that
204
195
  # consists exactly of one digram (= 2 symbols).
205
196
  def reduce_step(another)
206
- (symb1, symb2) = another.rhs
197
+ (symb1, symb2) = another.rhs.symbols
207
198
  pos = positions_of(symb1, symb2).reverse
208
199
 
209
200
  # Replace the two symbol sequence by the production
210
- pos.each do |index|
211
- if rhs[index].is_a?(ProductionRef)
212
- rhs[index].bind_to(another)
213
- else
214
- rhs[index] = ProductionRef.new(another)
215
- end
216
- index1 = index + 1
217
- rhs[index1].unbind if rhs[index1].is_a?(ProductionRef)
218
- rhs.delete_at(index1)
219
- end
201
+ pos.each { |index| rhs.reduce_step(index, another) }
220
202
 
221
203
  recalc_digrams
222
204
  end
@@ -235,11 +217,7 @@ class Production
235
217
  (0...rhs.size).to_a.reverse.each do |index|
236
218
  next unless rhs[index] == another
237
219
 
238
- # Avoid the aliasing of production reference
239
- other_rhs = another.rhs.map do |symb|
240
- symb.is_a?(ProductionRef) ? symb.dup : symb
241
- end
242
- rhs.insert(index + 1, *other_rhs)
220
+ rhs.insert_at(index + 1, another.rhs)
243
221
  another.decr_refcount
244
222
  rhs.delete_at(index)
245
223
  end
@@ -253,13 +231,7 @@ class Production
253
231
  def accept(aVisitor)
254
232
  aVisitor.start_visit_production(self)
255
233
 
256
- rhs.each do |a_symb|
257
- if a_symb.is_a?(ProductionRef)
258
- a_symb.accept(aVisitor)
259
- else
260
- aVisitor.visit_terminal(a_symb)
261
- end
262
- end
234
+ rhs.accept(aVisitor)
263
235
 
264
236
  aVisitor.end_visit_production(self)
265
237
  end
@@ -97,7 +97,6 @@ CollisionDiagnosis = Struct.new(
97
97
  # Then create a new production that will have
98
98
  # the symbols of d as its rhs members.
99
99
  def restore_unicity(aDiagnosis)
100
- digr = aDiagnosis.digram
101
100
  prods = aDiagnosis.productions
102
101
  if prods.any?(&:single_digram?)
103
102
  (simple, compound) = prods.partition(&:single_digram?)
@@ -105,14 +104,9 @@ CollisionDiagnosis = Struct.new(
105
104
  else
106
105
  # Create a new production with the digram's symbols as its
107
106
  # sole rhs members.
108
- new_prod = Production.new
109
- digr.symbols.each { |sym| new_prod.append_symbol(sym) }
110
- add_production(new_prod)
111
- if prods[0] == prods[1]
112
- prods[0].reduce_step(new_prod)
113
- else
114
- prods.each { |a_prod| a_prod.reduce_step(new_prod) }
115
- end
107
+ new_prod = build_production_for(aDiagnosis.digram)
108
+ prods[0].reduce_step(new_prod)
109
+ prods[1].reduce_step(new_prod) unless prods[1] == prods[0]
116
110
  end
117
111
  end
118
112
 
@@ -145,7 +139,15 @@ CollisionDiagnosis = Struct.new(
145
139
  remove_production(index)
146
140
  end
147
141
 
148
-
142
+ # Create a new production that will have the symbols from digram
143
+ # as its rhs members.
144
+ def build_production_for(aDigram)
145
+ new_prod = Production.new
146
+ aDigram.symbols.each { |sym| new_prod.append_symbol(sym) }
147
+ add_production(new_prod)
148
+
149
+ return new_prod
150
+ end
149
151
  end # class
150
152
 
151
153
  end # module
@@ -0,0 +1,150 @@
1
+ module Sequitur # Module for classes implementing the Sequitur algorithm
2
+ # Represents a sequence (concatenation) of grammar symbols
3
+ # as they appear in rhs of productions
4
+ class SymbolSequence
5
+ # The sequence of symbols itself
6
+ attr_reader(:symbols)
7
+
8
+ # Create an empty sequence
9
+ def initialize()
10
+ @symbols = []
11
+ end
12
+
13
+ # Copy constructor invoked by dup or clone methods.
14
+ # @param orig [SymbolSequence]
15
+ def initialize_copy(orig)
16
+ # Deep copy to avoid the aliasing of production reference
17
+ @symbols = orig.symbols.map do |sym|
18
+ sym.is_a?(Symbol) ? sym : sym.dup
19
+ end
20
+ end
21
+
22
+ public
23
+
24
+ # Clear the symbol sequence.
25
+ def clear()
26
+ refs = references
27
+ refs.each(&:unbind)
28
+ @symbols = []
29
+ end
30
+
31
+ # Tell whether the sequence is empty.
32
+ # @return [true / false] true only if the sequence has no symbol in it.
33
+ def empty?()
34
+ return symbols.empty?
35
+ end
36
+
37
+ # Count the number of elements in the sequence.
38
+ # @return [Fixnum] the number of elements
39
+ def size()
40
+ return symbols.size
41
+ end
42
+
43
+ # Append a grammar symbol at the end of the sequence.
44
+ # @param aSymbol [Object] The symbol to append.
45
+ def <<(aSymbol)
46
+ symbols << aSymbol
47
+ end
48
+
49
+ # Retrieve the element from the sequence at given position.
50
+ # @param anIndex [Fixnum] A zero-based index of the element to access.
51
+ def [](anIndex)
52
+ return symbols[anIndex]
53
+ end
54
+
55
+ # Equality testing.
56
+ # @param other [SymbolSequence or Array] the other other sequence
57
+ # to compare to.
58
+ # @return true when an item from self equals the corresponding
59
+ # item from 'other'
60
+ def ==(other)
61
+ return true if self.object_id == other.object_id
62
+
63
+ case other
64
+ when SymbolSequence
65
+ same = self.symbols == other.symbols
66
+ when Array
67
+ same = self.symbols == other
68
+ else
69
+ same = false
70
+ end
71
+
72
+ return same
73
+ end
74
+
75
+
76
+ # Select the references to production appearing in the rhs.
77
+ # @return [Array of ProductionRef]
78
+ def references()
79
+ return symbols.select { |symb| symb.is_a?(ProductionRef) }
80
+ end
81
+
82
+
83
+ # Emit a text representation of the symbol sequence.
84
+ # Text is of the form: space-separated sequence of symbols.
85
+ # @return [String]
86
+ def to_string()
87
+ rhs_text = symbols.map do |elem|
88
+ case elem
89
+ when String then "'#{elem}'"
90
+ else elem.to_s
91
+ end
92
+ end
93
+
94
+ return rhs_text.join(' ')
95
+ end
96
+
97
+ # Insert at position the elements from another sequence.
98
+ # @param position [Fixnum] A zero-based index of the symbols to replace.
99
+ # @param another [Production] A production with a two-elements rhs
100
+ # (a single digram).
101
+ def insert_at(position, another)
102
+ klone = another.dup
103
+ symbols.insert(position, *klone.symbols)
104
+ end
105
+
106
+ # Given that the production P passed as argument has exactly 2 symbols
107
+ # in its rhs s1 s2, substitute in the rhs of self all occurrences of
108
+ # s1 s2 by a reference to P.
109
+ # @param index [Fixnum] the position of a two symbol sequence to be replaced
110
+ # by the production
111
+ # @param aProduction [Production or ProductionRef] a production that
112
+ # consists exactly of one digram (= 2 symbols).
113
+ def reduce_step(index, aProduction)
114
+ if symbols[index].is_a?(ProductionRef)
115
+ symbols[index].bind_to(aProduction)
116
+ else
117
+ symbols[index] = ProductionRef.new(aProduction)
118
+ end
119
+ index1 = index + 1
120
+ symbols[index1].unbind if symbols[index1].is_a?(ProductionRef)
121
+ delete_at(index1)
122
+ end
123
+
124
+ # Remove the element at given position
125
+ # @param position [Fixnum] a zero-based index.
126
+ def delete_at(position)
127
+ symbols.delete_at(position)
128
+ end
129
+
130
+
131
+ # Part of the 'visitee' role in Visitor design pattern.
132
+ # @param aVisitor[GrammarVisitor]
133
+ def accept(aVisitor)
134
+ aVisitor.start_visit_rhs(self)
135
+
136
+ # Let's proceed with the visit of productions
137
+ symbols.each do |a_symb|
138
+ if a_symb.is_a?(ProductionRef)
139
+ a_symb.accept(aVisitor)
140
+ else
141
+ aVisitor.visit_terminal(a_symb)
142
+ end
143
+ end
144
+
145
+ aVisitor.end_visit_rhs(self)
146
+ end
147
+
148
+ end # class
149
+
150
+ end # module
@@ -108,9 +108,12 @@ describe DynamicGrammar do
108
108
  a_visitor.subscribe(fake_formatter)
109
109
 
110
110
  expect(fake_formatter).to receive(:before_grammar).with(subject).ordered
111
- expect(fake_formatter).to receive(:before_production).with(subject.start)
112
- expect(fake_formatter).to receive(:before_rhs).with([]).ordered
113
- expect(fake_formatter).to receive(:after_rhs).with([]).ordered
111
+ expect(fake_formatter).to receive(:before_production)
112
+ .with(subject.start).ordered
113
+ expect(fake_formatter).to receive(:before_rhs)
114
+ .with(subject.start.rhs).ordered
115
+ expect(fake_formatter).to receive(:after_rhs)
116
+ .with(subject.start.rhs).ordered
114
117
  expect(fake_formatter).to receive(:after_production).with(subject.start)
115
118
  expect(fake_formatter).to receive(:before_production).with(p_a)
116
119
  expect(fake_formatter).to receive(:before_rhs).with(p_a.rhs)
@@ -78,16 +78,6 @@ describe GrammarVisitor do
78
78
 
79
79
  subject.start_visit_grammar(fake)
80
80
  end
81
-
82
- it 'should react to the start_visit_production message' do
83
- expect(mock_production).to receive(:rhs).and_return([1, 2, 3])
84
-
85
- # Notify subscribers when start the visit of the production
86
- expect(listener1).to receive(:before_production).with(mock_production)
87
- expect(listener1).to receive(:before_rhs).with([1, 2, 3])
88
-
89
- subject.start_visit_production(mock_production)
90
- end
91
81
 
92
82
  end # context
93
83
 
@@ -330,6 +330,8 @@ describe Production do
330
330
 
331
331
  # Empty production: visitor will receive a start and end visit messages
332
332
  expect(fake).to receive(:start_visit_production).once.ordered
333
+ expect(fake).to receive(:start_visit_rhs).once.ordered
334
+ expect(fake).to receive(:end_visit_rhs).once.ordered
333
335
  expect(fake).to receive(:end_visit_production).once.ordered
334
336
 
335
337
  expect { subject.accept(fake) }.not_to raise_error
@@ -339,8 +341,10 @@ describe Production do
339
341
  # Use a mock visitor
340
342
  fake = double('fake_visitor')
341
343
  expect(fake).to receive(:start_visit_production).once.ordered
344
+ expect(fake).to receive(:start_visit_rhs).once.ordered
342
345
  expect(fake).to receive(:visit_terminal).with('b').ordered
343
346
  expect(fake).to receive(:visit_terminal).with('c').ordered
347
+ expect(fake).to receive(:end_visit_rhs).once.ordered
344
348
  expect(fake).to receive(:end_visit_production).once.ordered
345
349
 
346
350
  expect { p_bc.accept(fake) }.not_to raise_error
@@ -353,8 +357,10 @@ describe Production do
353
357
 
354
358
  fake = double('fake_visitor')
355
359
  expect(fake).to receive(:start_visit_production).once.ordered
360
+ expect(fake).to receive(:start_visit_rhs).once.ordered
356
361
  expect(fake).to receive(:visit_prod_ref).with(p_a).ordered
357
362
  expect(fake).to receive(:visit_prod_ref).with(p_bc).ordered
363
+ expect(fake).to receive(:end_visit_rhs).once.ordered
358
364
  expect(fake).to receive(:end_visit_production).once.ordered
359
365
 
360
366
  expect { subject.accept(fake) }.not_to raise_error
@@ -0,0 +1,95 @@
1
+ require_relative '../spec_helper'
2
+
3
+ # Load the class under test
4
+ require_relative '../../lib/sequitur/symbol_sequence'
5
+ require_relative '../../lib/sequitur/production_ref'
6
+ require_relative '../../lib/sequitur/production'
7
+
8
+ module Sequitur # Re-open the module to get rid of qualified names
9
+
10
+ describe SymbolSequence do
11
+
12
+ let(:instance) { SymbolSequence.new }
13
+
14
+ context 'Creation and initialization:' do
15
+
16
+ it 'should be created without argument' do
17
+ expect { SymbolSequence.new }.not_to raise_error
18
+ end
19
+
20
+ it 'should be empty at creation' do
21
+ expect(subject).to be_empty
22
+ end
23
+
24
+ end # context
25
+
26
+ context 'Provided services:' do
27
+ subject do
28
+ an_instance = SymbolSequence.new
29
+ [:a, :b, :c].each { |a_sym| an_instance << a_sym }
30
+ an_instance
31
+ end
32
+
33
+ it 'should deep-copy clone itself' do
34
+ a_prod = Production.new
35
+ ref = ProductionRef.new(a_prod)
36
+
37
+ a, c = 'a', 'c'
38
+ [a, ref, c].each { |ch| instance << ch }
39
+ clone_a = instance.clone
40
+
41
+ # Check that cloning works
42
+ expect(clone_a).to eq(instance)
43
+
44
+ # Reference objects are distinct but points to same production
45
+ expect(clone_a.symbols[1].object_id).not_to eq(instance.symbols[1])
46
+
47
+ # Modifying the clone...
48
+ clone_a.symbols[1] = 'diff'
49
+ expect(clone_a).not_to eq(instance)
50
+
51
+ # ... should leave original unchanged
52
+ expect(instance.symbols[1]).to eq(ref)
53
+ end
54
+
55
+
56
+ it 'should tell that it is equal to itself' do
57
+ # Case: Non-empty sequence
58
+ expect(subject).to eq(subject)
59
+
60
+ # Case: empty sequence
61
+ expect(instance).to eq(instance)
62
+ end
63
+
64
+ it 'should know whether it is equal to another instance' do
65
+ expect(instance).to eq(instance)
66
+
67
+ expect(subject).not_to eq(instance)
68
+ [:a, :b, :c].each { |a_sym| instance << a_sym }
69
+ expect(subject).to eq(instance)
70
+
71
+ # Check that element order is relevant
72
+ instance.symbols.rotate!
73
+ expect(subject).not_to eq(instance)
74
+ end
75
+
76
+ it 'should know whether it is equal to an array' do
77
+ expect(subject).to eq([:a, :b, :c])
78
+
79
+ # Check that element order is relevant
80
+ expect(subject).not_to eq([:c, :b, :a])
81
+ end
82
+
83
+ it 'should know that is not equal to something else' do
84
+ expect(subject).not_to eq(:abc)
85
+ end
86
+
87
+ end # context
88
+
89
+
90
+
91
+ end # describe
92
+
93
+ end # module
94
+
95
+ # End of file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequitur
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.07
4
+ version: 0.1.09
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-29 00:00:00.000000000 Z
11
+ date: 2014-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -114,6 +114,7 @@ files:
114
114
  - lib/sequitur/production.rb
115
115
  - lib/sequitur/production_ref.rb
116
116
  - lib/sequitur/sequitur_grammar.rb
117
+ - lib/sequitur/symbol_sequence.rb
117
118
  - spec/sequitur/digram_spec.rb
118
119
  - spec/sequitur/dynamic_grammar_spec.rb
119
120
  - spec/sequitur/formatter/base_text_spec.rb
@@ -122,6 +123,7 @@ files:
122
123
  - spec/sequitur/production_ref_spec.rb
123
124
  - spec/sequitur/production_spec.rb
124
125
  - spec/sequitur/sequitur_grammar_spec.rb
126
+ - spec/sequitur/symbol_sequence_spec.rb
125
127
  - spec/spec_helper.rb
126
128
  homepage: https://github.com/famished-tiger/Sequitur
127
129
  licenses:
@@ -163,3 +165,4 @@ test_files:
163
165
  - spec/sequitur/production_ref_spec.rb
164
166
  - spec/sequitur/production_spec.rb
165
167
  - spec/sequitur/sequitur_grammar_spec.rb
168
+ - spec/sequitur/symbol_sequence_spec.rb