jinx 2.1.1
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.
- data/.gitignore +14 -0
- data/.rspec +3 -0
- data/.yardopts +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +27 -0
- data/History.md +6 -0
- data/LEGAL +5 -0
- data/LICENSE +22 -0
- data/README.md +44 -0
- data/Rakefile +41 -0
- data/examples/family/README.md +10 -0
- data/examples/family/ext/build.xml +35 -0
- data/examples/family/ext/src/family/Address.java +68 -0
- data/examples/family/ext/src/family/Child.java +24 -0
- data/examples/family/ext/src/family/DomainObject.java +26 -0
- data/examples/family/ext/src/family/Household.java +36 -0
- data/examples/family/ext/src/family/Parent.java +48 -0
- data/examples/family/ext/src/family/Person.java +42 -0
- data/examples/family/lib/family.rb +15 -0
- data/examples/family/lib/family/address.rb +6 -0
- data/examples/family/lib/family/domain_object.rb +6 -0
- data/examples/family/lib/family/household.rb +6 -0
- data/examples/family/lib/family/parent.rb +16 -0
- data/examples/family/lib/family/person.rb +6 -0
- data/examples/model/README.md +25 -0
- data/examples/model/ext/build.xml +35 -0
- data/examples/model/ext/src/domain/Child.java +192 -0
- data/examples/model/ext/src/domain/Dependent.java +29 -0
- data/examples/model/ext/src/domain/DomainObject.java +26 -0
- data/examples/model/ext/src/domain/Independent.java +83 -0
- data/examples/model/ext/src/domain/Parent.java +129 -0
- data/examples/model/ext/src/domain/Person.java +14 -0
- data/examples/model/lib/model.rb +13 -0
- data/examples/model/lib/model/child.rb +13 -0
- data/examples/model/lib/model/domain_object.rb +6 -0
- data/examples/model/lib/model/independent.rb +11 -0
- data/examples/model/lib/model/parent.rb +17 -0
- data/jinx.gemspec +22 -0
- data/lib/jinx.rb +3 -0
- data/lib/jinx/active_support/README.txt +2 -0
- data/lib/jinx/active_support/core_ext/string.rb +7 -0
- data/lib/jinx/active_support/core_ext/string/inflections.rb +167 -0
- data/lib/jinx/active_support/inflections.rb +55 -0
- data/lib/jinx/active_support/inflector.rb +398 -0
- data/lib/jinx/cli/application.rb +36 -0
- data/lib/jinx/cli/command.rb +214 -0
- data/lib/jinx/helpers/array.rb +108 -0
- data/lib/jinx/helpers/boolean.rb +42 -0
- data/lib/jinx/helpers/case_insensitive_hash.rb +39 -0
- data/lib/jinx/helpers/class.rb +149 -0
- data/lib/jinx/helpers/collection.rb +33 -0
- data/lib/jinx/helpers/collections.rb +11 -0
- data/lib/jinx/helpers/collector.rb +20 -0
- data/lib/jinx/helpers/conditional_enumerator.rb +21 -0
- data/lib/jinx/helpers/enumerable.rb +242 -0
- data/lib/jinx/helpers/enumerate.rb +35 -0
- data/lib/jinx/helpers/error.rb +15 -0
- data/lib/jinx/helpers/file_separator.rb +65 -0
- data/lib/jinx/helpers/filter.rb +52 -0
- data/lib/jinx/helpers/flattener.rb +38 -0
- data/lib/jinx/helpers/hash.rb +12 -0
- data/lib/jinx/helpers/hashable.rb +502 -0
- data/lib/jinx/helpers/inflector.rb +36 -0
- data/lib/jinx/helpers/key_transformer_hash.rb +43 -0
- data/lib/jinx/helpers/lazy_hash.rb +44 -0
- data/lib/jinx/helpers/log.rb +106 -0
- data/lib/jinx/helpers/math.rb +12 -0
- data/lib/jinx/helpers/merge.rb +60 -0
- data/lib/jinx/helpers/module.rb +18 -0
- data/lib/jinx/helpers/multi_enumerator.rb +31 -0
- data/lib/jinx/helpers/options.rb +92 -0
- data/lib/jinx/helpers/os.rb +19 -0
- data/lib/jinx/helpers/partial_order.rb +37 -0
- data/lib/jinx/helpers/pretty_print.rb +207 -0
- data/lib/jinx/helpers/set.rb +8 -0
- data/lib/jinx/helpers/stopwatch.rb +76 -0
- data/lib/jinx/helpers/transformer.rb +24 -0
- data/lib/jinx/helpers/transitive_closure.rb +55 -0
- data/lib/jinx/helpers/uniquifier.rb +50 -0
- data/lib/jinx/helpers/validation.rb +33 -0
- data/lib/jinx/helpers/visitor.rb +370 -0
- data/lib/jinx/import/class_path_modifier.rb +77 -0
- data/lib/jinx/import/java.rb +337 -0
- data/lib/jinx/importer.rb +240 -0
- data/lib/jinx/metadata.rb +155 -0
- data/lib/jinx/metadata/attribute_enumerator.rb +73 -0
- data/lib/jinx/metadata/dependency.rb +244 -0
- data/lib/jinx/metadata/id_alias.rb +23 -0
- data/lib/jinx/metadata/introspector.rb +179 -0
- data/lib/jinx/metadata/inverse.rb +170 -0
- data/lib/jinx/metadata/java_property.rb +169 -0
- data/lib/jinx/metadata/propertied.rb +500 -0
- data/lib/jinx/metadata/property.rb +401 -0
- data/lib/jinx/metadata/property_characteristics.rb +114 -0
- data/lib/jinx/resource.rb +862 -0
- data/lib/jinx/resource/copy_visitor.rb +36 -0
- data/lib/jinx/resource/inversible.rb +90 -0
- data/lib/jinx/resource/match_visitor.rb +180 -0
- data/lib/jinx/resource/matcher.rb +20 -0
- data/lib/jinx/resource/merge_visitor.rb +73 -0
- data/lib/jinx/resource/mergeable.rb +185 -0
- data/lib/jinx/resource/reference_enumerator.rb +49 -0
- data/lib/jinx/resource/reference_path_visitor.rb +38 -0
- data/lib/jinx/resource/reference_visitor.rb +55 -0
- data/lib/jinx/resource/unique.rb +35 -0
- data/lib/jinx/version.rb +3 -0
- data/spec/defaults_spec.rb +30 -0
- data/spec/definitions/model/alias/child.rb +5 -0
- data/spec/definitions/model/base/child.rb +5 -0
- data/spec/definitions/model/base/domain_object.rb +5 -0
- data/spec/definitions/model/base/independent.rb +5 -0
- data/spec/definitions/model/defaults/child.rb +5 -0
- data/spec/definitions/model/dependency/child.rb +5 -0
- data/spec/definitions/model/dependency/parent.rb +6 -0
- data/spec/definitions/model/inverse/child.rb +5 -0
- data/spec/definitions/model/inverse/independent.rb +5 -0
- data/spec/definitions/model/inverse/parent.rb +5 -0
- data/spec/definitions/model/mandatory/child.rb +6 -0
- data/spec/dependency_spec.rb +47 -0
- data/spec/family_spec.rb +64 -0
- data/spec/inverse_spec.rb +53 -0
- data/spec/mandatory_spec.rb +43 -0
- data/spec/metadata_spec.rb +68 -0
- data/spec/resource_spec.rb +30 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/model.rb +19 -0
- data/test/fixtures/line_separator/cr_line_sep.txt +1 -0
- data/test/fixtures/line_separator/crlf_line_sep.txt +3 -0
- data/test/fixtures/line_separator/lf_line_sep.txt +3 -0
- data/test/fixtures/mixed/ext/build.xml +35 -0
- data/test/fixtures/mixed/ext/src/mixed/Case/Example.java +5 -0
- data/test/helper.rb +7 -0
- data/test/lib/jinx/command_test.rb +41 -0
- data/test/lib/jinx/helpers/boolean_test.rb +27 -0
- data/test/lib/jinx/helpers/class_test.rb +60 -0
- data/test/lib/jinx/helpers/collections_test.rb +402 -0
- data/test/lib/jinx/helpers/file_separator_test.rb +29 -0
- data/test/lib/jinx/helpers/inflector_test.rb +11 -0
- data/test/lib/jinx/helpers/lazy_hash_test.rb +32 -0
- data/test/lib/jinx/helpers/module_test.rb +24 -0
- data/test/lib/jinx/helpers/options_test.rb +66 -0
- data/test/lib/jinx/helpers/partial_order_test.rb +41 -0
- data/test/lib/jinx/helpers/pretty_print_test.rb +83 -0
- data/test/lib/jinx/helpers/stopwatch_test.rb +16 -0
- data/test/lib/jinx/helpers/transitive_closure_test.rb +80 -0
- data/test/lib/jinx/helpers/visitor_test.rb +288 -0
- data/test/lib/jinx/import/java_test.rb +78 -0
- data/test/lib/jinx/import/mixed_case_test.rb +16 -0
- metadata +272 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
module Model
|
|
4
|
+
describe 'Mandatory' do
|
|
5
|
+
before(:all) do
|
|
6
|
+
Model.definitions BASE, MANDATORY
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should recognize the mandatory property" do
|
|
10
|
+
Child.property(:flag).mandatory?.should be true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should fail to validate a missing mandatory property value" do
|
|
14
|
+
c = Child.new
|
|
15
|
+
expect { c.validate }.to raise_error(Jinx::ValidationError)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should validate an existing mandatory property value" do
|
|
19
|
+
c = Child.new(:name => 'Sam')
|
|
20
|
+
c.flag = true
|
|
21
|
+
expect { c.validate }.to_not raise_error
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should validate a mandatory property set to false" do
|
|
25
|
+
c = Child.new(:name => 'Sam')
|
|
26
|
+
c.flag = false
|
|
27
|
+
expect { c.validate }.to_not raise_error
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should not revalidate a property" do
|
|
31
|
+
c = Child.new(:name => 'Sam')
|
|
32
|
+
c.flag = true
|
|
33
|
+
expect { c.validate }.to_not raise_error
|
|
34
|
+
c.flag = nil
|
|
35
|
+
expect { c.validate }.to_not raise_error
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
# The defaults fixture model definitions.
|
|
41
|
+
MANDATORY = File.dirname(__FILE__) + '/definitions/model/mandatory'
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
module Model
|
|
4
|
+
describe 'Metadata' do
|
|
5
|
+
before(:all) do
|
|
6
|
+
Model.definitions BASE, ALIAS
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should import a resource class" do
|
|
10
|
+
Parent.should be < Jinx::Resource
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should import a resource superclass in the same package" do
|
|
14
|
+
Child.superclass.should be < Jinx::Resource
|
|
15
|
+
Child.superclass.superclass.should_not be < Jinx::Resource
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should introspect the properties" do
|
|
19
|
+
expect { Child.property(:cardinal) }.to_not raise_error
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should alias the reserved id attribute" do
|
|
23
|
+
Child.attributes.should include :identifier
|
|
24
|
+
Child.attributes.should_not include :id
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should set the collection property flag" do
|
|
28
|
+
Parent.property(:children).collection?.should be true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should set the collection property type" do
|
|
32
|
+
Independent.property(:others).type.should be Independent
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should infer the collection property type" do
|
|
36
|
+
Parent.property(:children).type.should be Child
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should make an empty collection value" do
|
|
40
|
+
Parent.empty_value(:children).class.should < Java::JavaUtil::Collection
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should recognize a domain property type" do
|
|
44
|
+
Parent.domain_type(:children).should be Child
|
|
45
|
+
Child.domain_type(:cardinal).should be nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should recognize a property alias" do
|
|
49
|
+
Child.property(:pals).should be Child.property(:friends)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should set the primary key" do
|
|
53
|
+
DomainObject.primary_key_attributes.should == [:identifier]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should inherit the primary key" do
|
|
57
|
+
Child.primary_key_attributes.should be DomainObject.primary_key_attributes
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should set the secondary key" do
|
|
61
|
+
Child.secondary_key_attributes.should == [:name]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
ALIAS = File.dirname(__FILE__) + '/definitions/model/alias'
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
module Model
|
|
4
|
+
describe 'Resource' do
|
|
5
|
+
before(:all) do
|
|
6
|
+
Model.definitions BASE
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should have a resource attribute => value constructor" do
|
|
10
|
+
Child.new(:name => 'Test').name.should == 'Test'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should merge an attribute => value hash" do
|
|
14
|
+
c = Child.new(:name => 'Test')
|
|
15
|
+
p = Parent.new
|
|
16
|
+
c.merge({:name => 'Other', :cardinal => 1, :parent => p})
|
|
17
|
+
c.name.should == 'Test'
|
|
18
|
+
c.cardinal.should be 1
|
|
19
|
+
c.parent.should be p
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should merge another resource" do
|
|
23
|
+
c = Child.new(:name => 'Test')
|
|
24
|
+
other = Child.new(:name => 'Other', :cardinal => 1)
|
|
25
|
+
c.merge(other)
|
|
26
|
+
c.name.should == 'Test'
|
|
27
|
+
c.cardinal.should be 1
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Add the Java jar file to the Java path.
|
|
2
|
+
require File.dirname(__FILE__) + '/../../examples/model/ext/bin/model.jar'
|
|
3
|
+
|
|
4
|
+
# The Jinx Model example application domain module.
|
|
5
|
+
module Model
|
|
6
|
+
include Jinx::Resource
|
|
7
|
+
|
|
8
|
+
extend Jinx::Importer
|
|
9
|
+
|
|
10
|
+
# The Java package name.
|
|
11
|
+
packages 'domain'
|
|
12
|
+
|
|
13
|
+
# expose the definitions for testing
|
|
14
|
+
public_class_method :definitions
|
|
15
|
+
|
|
16
|
+
# The base fixture model definitions.
|
|
17
|
+
BASE = File.dirname(__FILE__) + '/../definitions/model/base'
|
|
18
|
+
end
|
|
19
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
A
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?xml version ="1.0"?>
|
|
2
|
+
|
|
3
|
+
<project name="import Jinx test fixture" default="jar">
|
|
4
|
+
|
|
5
|
+
<!--build locations -->
|
|
6
|
+
<property name="base.dir" value="." />
|
|
7
|
+
<property name="source.dir" value="src" />
|
|
8
|
+
<property name="target.dir" value="classes" />
|
|
9
|
+
<property name="bin.dir" value="bin" />
|
|
10
|
+
|
|
11
|
+
<target name="init">
|
|
12
|
+
<tstamp />
|
|
13
|
+
<mkdir dir="${target.dir}" />
|
|
14
|
+
<mkdir dir="${bin.dir}" />
|
|
15
|
+
</target>
|
|
16
|
+
|
|
17
|
+
<!-- Compile all files in the source directory -->
|
|
18
|
+
<target name="compile" depends="init">
|
|
19
|
+
<javac destdir="${target.dir}" includes="**/*.*">
|
|
20
|
+
<src path="${source.dir}" />
|
|
21
|
+
<compilerarg value="-Xlint:unchecked"/>
|
|
22
|
+
</javac>
|
|
23
|
+
</target>
|
|
24
|
+
|
|
25
|
+
<target name="jar" depends="compile">
|
|
26
|
+
<jar destfile="${bin.dir}/mixed_case.jar" basedir="${target.dir}" includes="**/*.*" />
|
|
27
|
+
</target>
|
|
28
|
+
|
|
29
|
+
<!-- Remove build directories -->
|
|
30
|
+
<target name="clean">
|
|
31
|
+
<delete dir="${bin.dir}" />
|
|
32
|
+
<delete dir="${target.dir}" />
|
|
33
|
+
</target>
|
|
34
|
+
|
|
35
|
+
</project>
|
data/test/helper.rb
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../helper'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'jinx/cli/command'
|
|
4
|
+
require 'set'
|
|
5
|
+
|
|
6
|
+
module Jinx
|
|
7
|
+
class CommandTest < Test::Unit::TestCase
|
|
8
|
+
def test_empty
|
|
9
|
+
verify_execution(CLI::Command.new, '', {})
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_arg
|
|
13
|
+
verify_execution(CLI::Command.new([[:arg, 'ARG']]), '4', {:arg => '4'})
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_option
|
|
17
|
+
verify_execution(CLI::Command.new([[:opt, '--opt N', 'option']]), '--opt 4', {:opt => '4'})
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_typed_option
|
|
21
|
+
verify_execution(CLI::Command.new([[:opt, '--opt N', Integer, 'option']]), '--opt 4', {:opt => 4})
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_both
|
|
25
|
+
verify_execution(CLI::Command.new([[:arg, 'ARG'], [:opt, '--opt N', 'option']]), '4 --opt 5', {:arg => '4', :opt => '5'})
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def verify_execution(cmd, s, expected)
|
|
31
|
+
ARGV.clear.concat(s.split)
|
|
32
|
+
cmd.start do |actual|
|
|
33
|
+
actual.each do |opt, aval|
|
|
34
|
+
eval = expected[opt]
|
|
35
|
+
assert_not_nil(aval, "Command option #{opt} not found.")
|
|
36
|
+
assert_equal(eval, aval, "Command option #{opt} parsed incorrectly.")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../helper'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'jinx/helpers/boolean'
|
|
4
|
+
|
|
5
|
+
class BooleanTest < Test::Unit::TestCase
|
|
6
|
+
def test_marker
|
|
7
|
+
assert(Jinx::Boolean === true, "true is not a Jinx::Boolean")
|
|
8
|
+
assert(Jinx::Boolean === false, "false is not a Jinx::Boolean")
|
|
9
|
+
assert(!nil.is_a?(Jinx::Boolean), "nil is a Jinx::Boolean")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_string
|
|
13
|
+
['true', 'True', 't', 'T', 'yes', 'Yes', 'y', 'Y', '1'].each do |s|
|
|
14
|
+
assert_equal(true, Jinx::Boolean.for(s), "#{s} is not converted to true")
|
|
15
|
+
end
|
|
16
|
+
['false', 'False', 'f', 'F', 'no', 'No', 'n', 'N', '0'].each do |s|
|
|
17
|
+
assert_equal(false, Jinx::Boolean.for(s), "#{s} is not converted to false")
|
|
18
|
+
end
|
|
19
|
+
assert_raises(ArgumentError, "Invalid boolean string was converted") { Jinx::Boolean.for('Maybe') }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_integer
|
|
23
|
+
assert_equal(true, Jinx::Boolean.for(1), "#{self} is not converted to true")
|
|
24
|
+
assert_equal(false, Jinx::Boolean.for(0), "#{self} is not converted to false")
|
|
25
|
+
assert_raises(ArgumentError, "Invalid boolean integer was converted") { Jinx::Boolean.for(3) }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../helper'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'jinx/helpers/class'
|
|
4
|
+
|
|
5
|
+
class ClassTest < Test::Unit::TestCase
|
|
6
|
+
def ssn
|
|
7
|
+
'555-55-555'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.redefine_ssn
|
|
11
|
+
redefine_method(:ssn) { |old_method| lambda { send(old_method).delete('-').to_i } }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_redefine_method
|
|
15
|
+
self.class.redefine_ssn
|
|
16
|
+
assert_equal(55555555, ssn, "Method not redefined correctly")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_class_hierarchy
|
|
20
|
+
assert_equal([Array, Object], Array.class_hierarchy.to_a, "Class ancestors incorrect")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class Person
|
|
24
|
+
attr_reader :social_security_number
|
|
25
|
+
attr_accessor :postal_code
|
|
26
|
+
alias_attribute(:ssn, :social_security_number)
|
|
27
|
+
alias_attribute(:zip_code, :postal_code)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_attribute_alias
|
|
31
|
+
assert(Person.method_defined?(:ssn), "Reader alias not defined")
|
|
32
|
+
assert(!Person.method_defined?(:ssn=), "Writer alias incorrectly defined")
|
|
33
|
+
assert(Person.method_defined?(:zip_code), "Reader alias not defined")
|
|
34
|
+
assert(Person.method_defined?(:zip_code=), "Writer alias not defined")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class A; end
|
|
38
|
+
class B < A; end
|
|
39
|
+
|
|
40
|
+
def test_range
|
|
41
|
+
assert_equal([B, A, Object], (B..Object).to_a, "Class range incorrect")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class OneBased
|
|
45
|
+
attr_accessor :index
|
|
46
|
+
offset_attr_accessor :zero_based_index => :index
|
|
47
|
+
offset_attr_accessor({:two_based_index => :index}, 1)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_offset_attr_accessor
|
|
51
|
+
x = OneBased.new
|
|
52
|
+
x.index = 1
|
|
53
|
+
assert_equal(0, x.zero_based_index, "Offset reader incorrect")
|
|
54
|
+
x.zero_based_index = 1
|
|
55
|
+
assert_equal(2, x.index, "Offset writer incorrect")
|
|
56
|
+
assert_equal(3, x.two_based_index, "Offset reader incorrect")
|
|
57
|
+
x.two_based_index = 1
|
|
58
|
+
assert_equal(0, x.index, "Offset writer incorrect")
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../helper'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'jinx/helpers/collections'
|
|
4
|
+
require 'jinx/helpers/lazy_hash'
|
|
5
|
+
require 'jinx/helpers/case_insensitive_hash'
|
|
6
|
+
require 'jinx/helpers/key_transformer_hash'
|
|
7
|
+
require 'jinx/helpers/conditional_enumerator'
|
|
8
|
+
require 'jinx/helpers/multi_enumerator'
|
|
9
|
+
|
|
10
|
+
class CollectionsTest < Test::Unit::TestCase
|
|
11
|
+
def test_collection_classifier
|
|
12
|
+
assert([].collection?, "array is not a collecton")
|
|
13
|
+
assert(!nil.collection?, "nil is a collecton")
|
|
14
|
+
assert(!'a'.collection?, "String is a collecton")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_hashify
|
|
18
|
+
actual = [1, 2, 3].hashify { |key| key + 1 unless key == 2 }
|
|
19
|
+
expected = {1 => 2, 2 => nil, 3 => 4}
|
|
20
|
+
assert_equal(expected, actual, 'Hashify result incorrect')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_to_compact_hash
|
|
24
|
+
actual = [1, 2, 3].to_compact_hash { |key| key + 1 unless key == 2 }
|
|
25
|
+
expected = {1 => 2, 3 => 4}
|
|
26
|
+
assert_equal(expected, actual, 'Compact hash incorrect')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_lazy_hash
|
|
30
|
+
hash = Jinx::LazyHash.new { |n| n * 2 }
|
|
31
|
+
assert_equal(2, hash[1], "Lazy hash value incorrect")
|
|
32
|
+
hash.merge!(2 => 3)
|
|
33
|
+
assert_equal({1 => 2, 2 => 3}, hash, "Lazy hash merge incorrect")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_array_operator_set_argument
|
|
37
|
+
array = [1, 2, 3]
|
|
38
|
+
set = [3, 4].to_set
|
|
39
|
+
assert_equal([3], array & set, "Array | Set result incorrect")
|
|
40
|
+
assert_equal([1, 2, 3, 4], array | set, "Array | Set result incorrect")
|
|
41
|
+
assert_equal([1, 2], array - set, "Array - Set result incorrect")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_empty_hash
|
|
45
|
+
assert_raises(NotImplementedError, "Assigment to empty hash succeeds") { Hash::EMPTY_HASH[:a] = 2 }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_set_first
|
|
49
|
+
assert_equal(1, [1, 2].to_set.first, "first of set incorrect")
|
|
50
|
+
assert_nil(Set.new.first, "first of empty set incorrect")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def test_assoc_values_single
|
|
54
|
+
expected = {:a => [1, 3], :b => [2, nil], :c => [nil, 4]}
|
|
55
|
+
actual = {:a => 1, :b => 2}.assoc_values({:a => 3, :c => 4})
|
|
56
|
+
assert_equal(expected, actual, "Association hash incorrect")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_assoc_values_multiple
|
|
60
|
+
expected = {:a => [1, 3, 4], :b => [2, nil, 5]}
|
|
61
|
+
actual = {:a => 1, :b => 2}.assoc_values({:a => 3}, { :a => 4, :b => 5 })
|
|
62
|
+
assert_equal(expected, actual, "Multiple association hash incorrect")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_detect_value
|
|
66
|
+
assert_equal(4, [1, 2, 3].detect_value { |item| item * 2 if item > 1 }, "Detect value incorrect")
|
|
67
|
+
assert_nil([1, 2, 3].detect_value { |item| item * 2 if item > 3 }, "Value incorrectly detected")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_detect_with_value
|
|
71
|
+
assert_equal([2, 1], [1, 2].detect_with_value { |item| item / 2 if item % 2 == 0 }, "Detect with value incorrect")
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def test_array_filter
|
|
75
|
+
base = [1, 2, 3]
|
|
76
|
+
filter = base.filter { |n| n != 2 }
|
|
77
|
+
assert_equal([1, 3], filter.to_a, 'Filter incorrect')
|
|
78
|
+
base << 4
|
|
79
|
+
assert_equal([1, 3, 4], filter.to_a, 'Filter does not reflect operand modification')
|
|
80
|
+
filter << 5
|
|
81
|
+
assert_equal([1, 2, 3, 4, 5], base.to_a, 'Filter does not modify the base')
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_enum_join
|
|
85
|
+
assert_equal("1", [1].filter { true }.join, "Enumerable singleton join incorrect")
|
|
86
|
+
assert_equal("1,2", [1, 2].filter { true }.join(','), "Enumerable join incorrect")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def test_array_filter_without_block
|
|
90
|
+
assert_equal([1, 3], [1, nil, 3, false].filter.to_a, 'Filter incorrect')
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def test_set_filter_include
|
|
94
|
+
assert([1, 2, 3].to_set.filter { |n| n > 1 }.include?(2), 'Set filter include? incorrect')
|
|
95
|
+
assert(false == [1, 2, 3].to_set.filter { |n| n > 1 }.include?(1), 'Set filter include? incorrect')
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def test_union
|
|
99
|
+
base = [1, 2]
|
|
100
|
+
sum = base.union([4])
|
|
101
|
+
assert_equal([1, 2, 4], sum.to_a, 'Enumerator union incorrect')
|
|
102
|
+
assert(sum.include?(2), "Enumerator union missing first array element")
|
|
103
|
+
assert(sum.include?(4), "Enumerator union missing second array element")
|
|
104
|
+
base << 3
|
|
105
|
+
assert_equal([1, 2, 3, 4], sum.to_a, 'Enumerator union does not reflect operand modification')
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_intersection
|
|
109
|
+
base = [1, 2, 3, 4]
|
|
110
|
+
other = [3]
|
|
111
|
+
intersection = base.intersect(other)
|
|
112
|
+
assert_equal([3], intersection.to_a, 'Enumerator intersection incorrect')
|
|
113
|
+
other << 4 << 5
|
|
114
|
+
assert_equal([3, 4], intersection.to_a, 'Enumerator intersection does not reflect operand modification')
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def test_difference
|
|
118
|
+
base = [1, 2, 3]
|
|
119
|
+
diff = base.difference([3])
|
|
120
|
+
assert_equal([1, 2], diff.to_a, 'Enumerator subtraction incorrect')
|
|
121
|
+
base << 4
|
|
122
|
+
assert_equal([1, 2, 4], diff.to_a, 'Enumerator subtraction does not reflect operand modification')
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_wrap
|
|
126
|
+
assert_equal([2, 4, 6], [1, 2, 3].wrap { |n| n * 2 }.to_a, 'Wrap incorrect')
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def test_enum_addition
|
|
130
|
+
a = [1, 2].filter { true }
|
|
131
|
+
b = [3, 4].filter { true }
|
|
132
|
+
ab = a + b
|
|
133
|
+
assert_equal([1, 2, 3, 4], ab.to_a, "Composite array incorrect")
|
|
134
|
+
a << 3
|
|
135
|
+
assert_equal([1, 2, 3, 3, 4], ab.to_a, "Addition does not reflect change to first enumerable")
|
|
136
|
+
b << 5
|
|
137
|
+
assert_equal([1, 2, 3, 3, 4, 5], ab.to_a, "Addition does not reflect change to second enumerable")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def test_partial_sort
|
|
141
|
+
sorted = [Array, Object, Numeric, Enumerable, Set].partial_sort
|
|
142
|
+
assert(sorted.index(Array) < sorted.index(Enumerable), "Partial sort order incorrect")
|
|
143
|
+
assert(sorted.index(Set) < sorted.index(Enumerable), "Partial sort order incorrect")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def test_hash_union
|
|
147
|
+
a = {:a => 1, :b => 2}
|
|
148
|
+
b = {:b => 3, :c => 4}
|
|
149
|
+
ab = a + b
|
|
150
|
+
assert_equal({:a => 1, :b => 2, :c => 4}, ab.keys.to_compact_hash { |k| ab[k] }, "Hash union incorrect")
|
|
151
|
+
assert_equal([1, 2, 4], ab.values.sort, "Hash union values incorrect")
|
|
152
|
+
a.delete(:b)
|
|
153
|
+
assert_equal({:a => 1, :b => 3, :c => 4}, ab.keys.to_compact_hash { |k| ab[k] }, "Hash union does not reflect underlying change")
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def test_hash_compose
|
|
157
|
+
x = {:a => :c, :b => :d}
|
|
158
|
+
y = {:c => 1}
|
|
159
|
+
xy = x.compose(y)
|
|
160
|
+
assert_equal({:a => {:c => 1}}, xy.keys.to_compact_hash { |k| xy[k] }, "Composed hash incorrect")
|
|
161
|
+
y[:d] = 2
|
|
162
|
+
assert_equal({:a => {:c => 1}, :b => {:d => 2}}, xy.keys.to_compact_hash { |k| xy[k] }, "Composed hash does not reflect underlying change")
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def test_hash_join
|
|
166
|
+
x = {:a => :c, :b => :d}
|
|
167
|
+
y = {:c => 1}
|
|
168
|
+
xy = x.join(y)
|
|
169
|
+
assert_equal({:a => 1}, xy.keys.to_compact_hash { |k| xy[k] }, "Joined hash incorrect")
|
|
170
|
+
y[:d] = 2
|
|
171
|
+
assert_equal({:a => 1, :b => 2}, xy.keys.to_compact_hash { |k| xy[k] }, "Joined hash does not reflect underlying change")
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def test_hash_diff
|
|
175
|
+
x = {:a => 1, :b => 2, :c => 3}
|
|
176
|
+
y = {:b => 2, :c => 4, :d => 5}
|
|
177
|
+
assert_equal({:a => [1,nil], :c => [3,4], :d => [nil,5]}, x.diff(y), "Hash diff incorrect")
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_to_assoc_hash
|
|
181
|
+
actual = [[:a, 1], [:b, 2, 3], [:c], []].to_assoc_hash
|
|
182
|
+
expected = {:a => 1, :b => [2,3], :c => nil}
|
|
183
|
+
assert_equal(expected, actual, 'Association hash incorrect')
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def test_hashable_equal
|
|
187
|
+
assert_equal({:a => 1}, {:a => 1}.filter, "Hash equal incorrect")
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def test_hash_enum_keys
|
|
191
|
+
hash = { 1 => :a, 2 => :b }
|
|
192
|
+
ek = hash.enum_keys
|
|
193
|
+
assert_equal([1, 2], ek.sort, "Hash key enumerator incorrect")
|
|
194
|
+
hash[3] = :c
|
|
195
|
+
assert_equal([1, 2, 3], ek.sort, "Hash key enumerator does not reflect hash change")
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def test_hash_enum_keys_with_value
|
|
199
|
+
assert_equal([:b, :c], {:a => 1, :b => 2, :c => 2}.enum_keys_with_value(2).to_a, "Hash filtered value keys incorrect")
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def test_hash_enum_keys_with_value_block
|
|
203
|
+
assert_equal([:b, :c], {:a => 1, :b => 2, :c => 3}.enum_keys_with_value { |v| v > 1 }.to_a, "Hash filtered value block keys incorrect")
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def test_hash_enum_values
|
|
207
|
+
hash = { :a => 1, :b => 2 }
|
|
208
|
+
ev = hash.enum_values
|
|
209
|
+
assert_equal([1, 2], ev.sort, "Hash value enumerator incorrect")
|
|
210
|
+
hash[:c] = 3
|
|
211
|
+
assert_equal([1, 2, 3], ev.sort, "Hash value enumerator does not reflect hash change")
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def test_hash_flatten
|
|
215
|
+
assert_equal([:a, :b, :c, :d, :e, :f, :g], {:a => {:b => :c}, :d => :e, :f => [:g]}.flatten, "Hash flatten incorrect")
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def test_hash_first
|
|
219
|
+
assert_equal([:a, 1], {:a => 1, :b => 2}.first, "Hash first incorrect")
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def test_hash_filter
|
|
223
|
+
assert_equal({:a => 1, :c => 3}, {:a => 1, :b => 2, :c => 3}.filter { |k, v| k != :b }, "Hash filter incorrect")
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def test_hash_sort
|
|
227
|
+
assert_equal([['a', 1], ['b', 2]], {'a'=>1, 'b'=>2}.sort.to_a, "Hash sort incorrect")
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def test_hash_sort_with_comparator
|
|
231
|
+
assert_equal([[:a, 1], [:b, 2]], {:a => 1, :b => 2}.sort { |k1, k2| k1.to_s <=> k2.to_s }, "Hash sort with comparator incorrect")
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def test_hash_default_filter
|
|
235
|
+
assert_equal({:a => 1, :c => 3}, {:a => 1, :b => nil, :c => 3}.filter, "Hash default filter incorrect")
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def test_hash_partition
|
|
239
|
+
assert_equal([{:a => 1, :c => 3}, {:b => 2}], {:a => 1, :b => 2, :c => 3}.split { |k, v| k == :a or v == 3 }, "Hash partition incorrect")
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def test_hash_filter_on_key
|
|
243
|
+
filtered = {:a => 1, :b => 2, :c => 3}.filter_on_key { |k| k != :b }
|
|
244
|
+
assert_equal({:a => 1, :c => 3}, filtered.to_hash, "Hash on key filter incorrect")
|
|
245
|
+
assert_equal(1, filtered[:a], "Access on key filter inclusion incorrect")
|
|
246
|
+
assert_nil(filtered[:b], "Access on key filter exclusion incorrect")
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def test_hash_filter_on_value
|
|
250
|
+
filtered = {:a => 1, :b => 2, :c => 3}.filter_on_value { |v| v != 2 }
|
|
251
|
+
assert_equal({:a => 1, :c => 3}, filtered.to_hash, "Hash on value filter incorrect")
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def test_hash_compact
|
|
255
|
+
assert_equal({:a => 1, :c => 3}, {:a => 1, :b => nil, :c => 3}.compact.to_hash, "Compact hash incorrect")
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def test_set_flatten
|
|
259
|
+
inner = Set.new << :a
|
|
260
|
+
actual = [inner, 'b'].flatten
|
|
261
|
+
expected = [:a, 'b']
|
|
262
|
+
assert_equal(expected, actual, 'Inner set not flattened')
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def test_to_compact_hash
|
|
266
|
+
assert_equal({1 => 2, 2 => 3}, [1, 2].to_compact_hash { |item| item + 1 }, 'to_compact_hash result incorrect')
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def test_to_compact_hash_with_index
|
|
270
|
+
assert_equal({:a => 1, :b => 2}, [:a, :b].to_compact_hash_with_index { |item, index| index + 1 }, 'to_compact_hash_with_index result incorrect')
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def test_to_compact_hash_reject_missing
|
|
274
|
+
assert_equal({1 => 2, 2 => 3}, [1, 2, 3].to_compact_hash { |item| item + 1 unless item > 2 }, 'to_compact_hash maps a key with a nil value')
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def test_series
|
|
278
|
+
actual = [1, 2, 3].to_series
|
|
279
|
+
assert_equal('1, 2 and 3', actual, 'Print string incorrect')
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def test_empty_series
|
|
283
|
+
actual = [].to_series
|
|
284
|
+
assert_equal('', actual, 'Print string incorrect')
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def test_singleton_series
|
|
288
|
+
actual = [1].to_series
|
|
289
|
+
assert_equal('1', actual, 'Print string incorrect')
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def test_copy_recursive
|
|
293
|
+
hash = {1 => { 2 => 3 }, 4 => 5 }
|
|
294
|
+
copy = hash.copy_recursive
|
|
295
|
+
assert_equal(hash, copy, 'Copy not equal')
|
|
296
|
+
hash[1][2] = 6
|
|
297
|
+
assert_equal(3, copy[1][2], 'Copy reflects change to original')
|
|
298
|
+
hash[4] = 7
|
|
299
|
+
assert_equal(5, copy[4], 'Copy reflects change to original')
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def test_case_insensitive_hash
|
|
303
|
+
hash = Jinx::CaseInsensitiveHash.new
|
|
304
|
+
hash[:UP] = :down
|
|
305
|
+
assert_equal(:down, hash['up'], "Case-insensitive hash look-up incorrect")
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def test_key_transformer_hash
|
|
309
|
+
hash = Jinx::KeyTransformerHash.new { |k| k % 2 }
|
|
310
|
+
hash[1] = :a
|
|
311
|
+
assert_equal(:a, hash[1], 'Key transformer hash entered value not found')
|
|
312
|
+
assert_nil(hash[2], 'Transformed hash unentered value found')
|
|
313
|
+
assert_equal(:a, hash[3], 'Key transformer hash equivalent value not found')
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
def test_transformed_hash
|
|
317
|
+
hash = {:a => 1, :b => 2}
|
|
318
|
+
xfm = hash.transform_value { |v| v * 2 }
|
|
319
|
+
assert_equal(2, xfm[:a], 'Transformed hash accessor incorrect')
|
|
320
|
+
assert_equal([2, 4], xfm.values.sort, 'Transformed hash values incorrect')
|
|
321
|
+
assert(xfm.has_value?(4), 'Transformed hash value query incorrect')
|
|
322
|
+
assert(!xfm.has_value?(1), 'Transformed hash value query incorrect')
|
|
323
|
+
# base hash should be reflected in transformed hash
|
|
324
|
+
hash[:b] = 3; hash[:c] = 4
|
|
325
|
+
assert_equal(6, xfm[:b], 'Transformed hash does not reflect base hash change')
|
|
326
|
+
assert_equal(8, xfm[:c], 'Transformed hash does not reflect base hash change')
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
def test_hashinator
|
|
330
|
+
base = {:a => 1, :b => 2}.to_a
|
|
331
|
+
hash = Jinx::Hashinator.new(base)
|
|
332
|
+
assert_equal(base.to_set, hash.to_set, "Hashinator enumeration invalid")
|
|
333
|
+
assert_equal(1, hash[:a], "Hashinator a value invalid")
|
|
334
|
+
assert_equal(2, hash[:b], "Hashinator b value invalid")
|
|
335
|
+
assert_nil(hash[:c], "Hashinator has association not in the base")
|
|
336
|
+
base.first[1] = 3
|
|
337
|
+
assert_equal(3, hash[:a], "Hashinator does not reflect change to underlying Enumerator")
|
|
338
|
+
assert_equal(base, hash.to_hash.to_a, "Hashable to_hash incorrect")
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def test_collector
|
|
342
|
+
assert_equal([2, [3, 4]], Jinx::Collector.on([1, [2, 3]]) { |n| n + 1 }, "Collector on nested array incorrect")
|
|
343
|
+
assert_nil(Jinx::Collector.on(nil) { |n| n + 1 }, "Collector on nil incorrect")
|
|
344
|
+
assert_equal(2, Jinx::Collector.on(1) { |n| n + 1 }, "Collector on non-collection incorrect")
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
def test_enumerate
|
|
348
|
+
counter = 0
|
|
349
|
+
nil.enumerate { |item| counter += item }
|
|
350
|
+
assert_equal(0, counter, "Enumerate on nil incorrect")
|
|
351
|
+
[1, 2, 3].enumerate { |item| counter += item }
|
|
352
|
+
assert_equal(6, counter, "Enumerate on array incorrect")
|
|
353
|
+
[1, [2, 3]].enumerate { |item| counter += 1 }
|
|
354
|
+
assert_equal(8, counter, "Enumerate on nested array incorrect")
|
|
355
|
+
2.enumerate { |item| counter += item }
|
|
356
|
+
assert_equal(10, counter, "Enumerate on non-collection incorrect")
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
def test_to_enum
|
|
360
|
+
assert_equal([], nil.to_enum.to_a, "to_enum on nil incorrect")
|
|
361
|
+
assert_equal([1], 1.to_enum.to_a, "to_enum on non-collection incorrect")
|
|
362
|
+
array = [1, 2]
|
|
363
|
+
assert_same(array, array.to_enum, "to_enum on array incorrect")
|
|
364
|
+
s = 'a'
|
|
365
|
+
assert_same(s, s.to_enum, "to_enum on String incorrect")
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def test_flattener
|
|
369
|
+
assert_equal([1, 2, 3], Jinx::Flattener.new([1, [2, 3]]).to_a, "Flattener on nested array incorrect")
|
|
370
|
+
assert_equal([], Jinx::Flattener.new(nil).to_a, "Flattener on nil incorrect")
|
|
371
|
+
assert_equal([1], Jinx::Flattener.new(1).to_a, "Flattener on non-collection incorrect")
|
|
372
|
+
assert(Jinx::Flattener.new(nil).all?, "Flattener all? on nil incorrect")
|
|
373
|
+
assert_equal([:b, :c, :e], {:a => {:b => :c}, :d => [:e]}.enum_values.flatten.to_a, "Enumerable flatten incorrect")
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def test_hash_flattener
|
|
377
|
+
assert_equal([:a, :b, :c], {:a => {:b => :c}}.flatten.to_a, "Hash flatten incorrect")
|
|
378
|
+
assert_equal([:b, :c, :e], {:a => {:b => :c}, :d => [:e]}.enum_values.flatten.to_a, "Enumerable flatten incorrect")
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def test_conditional_enumerator
|
|
383
|
+
assert_equal([1, 2], Jinx::ConditionalEnumerator.new([1, 2, 3]) { |i| i < 3 }.to_a, "ConditionalEnumerator filter not applied")
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
def test_enumerable_size
|
|
387
|
+
assert_equal(2, {:a => 1, :b => 2}.enum_keys.size, "Enumerable size incorrect")
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
def test_set_merge
|
|
391
|
+
set = [1, 2].to_set
|
|
392
|
+
merged = set.merge!([3])
|
|
393
|
+
assert_equal([1, 2, 3].to_set, merged, "Merged set incorrect")
|
|
394
|
+
assert_same(set, merged, "Set merge! did not return same set")
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def test_set_add_all
|
|
398
|
+
actual = [1, 2].add_all([3])
|
|
399
|
+
expected = [1, 2, 3]
|
|
400
|
+
assert_equal(expected, actual, 'Set content not added')
|
|
401
|
+
end
|
|
402
|
+
end
|