You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildr.apache.org by vb...@apache.org on 2008/03/27 17:37:05 UTC

svn commit: r641877 [2/2] - in /incubator/buildr/trunk: lib/buildr/xmlbeans.rb lib/java/artifact.rb lib/java/artifact_namespace.rb lib/java/artifact_search.rb lib/java/groovyc.rb lib/java/version_requirement.rb spec/artifact_namespace_spec.rb

Modified: incubator/buildr/trunk/spec/artifact_namespace_spec.rb
URL: http://svn.apache.org/viewvc/incubator/buildr/trunk/spec/artifact_namespace_spec.rb?rev=641877&r1=641876&r2=641877&view=diff
==============================================================================
--- incubator/buildr/trunk/spec/artifact_namespace_spec.rb (original)
+++ incubator/buildr/trunk/spec/artifact_namespace_spec.rb Thu Mar 27 09:36:54 2008
@@ -16,196 +16,411 @@
 
 require File.join(File.dirname(__FILE__), 'spec_helpers')
 
-describe Buildr, '#artifacts' do 
-  before :each do 
-    ArtifactNamespace.clear
+require 'java/artifact_namespace'
+
+describe Buildr::ArtifactNamespace do
+
+  before(:each) { Buildr::ArtifactNamespace.clear }
+
+  def abc_module
+    Object.module_eval 'module A; module B; module C; end; end; end'
+    yield
+  ensure
+    Object.send :remove_const, :A
   end
-  
-  it 'should tap root namespace if given a block and called outside a project definition' do
-    expected = be_kind_of(ArtifactNamespace)
-    artifacts { |ns| ns.name.should == ArtifactNamespace::ROOT }
-    artifacts { |ns| ns.should expected }.should expected
+
+  describe '.root' do 
+    it 'should return the top level namespace' do
+      Buildr::ArtifactNamespace.root.should be_root
+    end
+    
+    it 'should yield the namespace if a block is given' do
+      Buildr::ArtifactNamespace.root { |ns| ns.should be_root }
+    end
   end
 
-  it 'should tap root namespace when given a block and nil argument' do
-    artifacts(nil) { |ns| ns.name.should == ArtifactNamespace::ROOT }
+  describe '.instance' do 
+    it 'should return the top level namespace when invoked outside a project definition' do
+      artifact_ns.should be_root
+    end
+    
+    it 'should return the current project namespace when invoked inside a project' do
+      define 'foo' do
+        artifact_ns.should_not be_root
+        artifact_ns.name.should == :foo
+        task :doit do 
+          artifact_ns.should_not be_root
+          artifact_ns.name.should == :foo
+        end.invoke
+      end
+    end
+  
+    it 'should return the root namespace if given :root' do
+      artifact_ns(:root).should be_root
+    end
+    
+    it 'should return the namespace for the given name' do 
+      artifact_ns(:foo).name.should == :foo
+      artifact_ns('foo:bar').name.should == 'foo:bar'.intern
+      artifact_ns(['foo', 'bar', 'baz']).name.should == 'foo:bar:baz'.intern
+      abc_module do 
+        artifact_ns(A::B::C).name.should == 'A:B:C'.intern
+      end
+      artifact_ns(:root).should be_root
+      artifact_ns(:current).should be_root
+      define 'foo' do
+        artifact_ns(:current).name.should == :foo
+        define 'baz' do
+          artifact_ns(:current).name.should == 'foo:baz'.intern
+        end
+      end
+    end
   end
 
-  it 'should return an array whose non-numeric indices are namespaces' do
-    ary = artifacts("foo:bar:jar:1.0")
-    ary.should be_kind_of(Array)
-    ary[0].should be_kind_of(Artifact)
-    ary[nil].should be_kind_of(ArtifactNamespace)
-    ary[nil].name.should === ArtifactNamespace::ROOT
-    ary['some:addon'].should be_kind_of(ArtifactNamespace)
-    ary['some:addon'].name.should === 'some:addon'.intern
+  describe '#parent' do 
+    it 'should be nil for root namespace' do 
+      artifact_ns(:root).parent.should be_nil
+    end
+    
+    it 'should be the parent namespace for nested modules' do 
+      abc_module do
+        artifact_ns(A::B::C).parent.should == artifact_ns(A::B)
+        artifact_ns(A::B).parent.should == artifact_ns(A)
+        artifact_ns(A).parent.should == artifact_ns(:root)
+      end
+    end
+
+    it 'should be the parent namespace for nested projects' do
+      define 'a' do 
+        define 'b' do 
+          define 'c' do
+            artifact_ns.parent.should == artifact_ns(parent)
+          end
+          artifact_ns.parent.should == artifact_ns(parent)
+        end
+        artifact_ns.parent.should == artifact_ns(:root)
+      end
+    end
+  end
+  
+  describe '#parent=' do
+    it 'should reject to set parent for root namespace' do 
+      lambda { artifact_ns(:root).parent = :foo }.should raise_error(Exception, /cannot set parent/i)
+    end
+
+    it 'should allow to set parent' do
+      artifact_ns(:bar).parent = :foo
+      artifact_ns(:bar).parent.should == artifact_ns(:foo)
+      artifact_ns(:bar).parent = artifact_ns(:baz)
+      artifact_ns(:bar).parent.should == artifact_ns(:baz)
+    end
+
+    it 'should allow to set parent to :current' do
+      abc_module do 
+        mod = A::B
+        artifact_ns(mod).parent = :current
+        def mod.stuff 
+          Buildr::artifact_ns(self)
+        end
+        define 'a' do
+          define 'b' do
+            mod.stuff.parent.should == artifact_ns
+          end
+          mod.stuff.parent.should == artifact_ns
+        end
+      end
+    end
   end
+  
+  describe '#need' do 
+    it 'should accept an artifact spec' do
+      define 'one' do
+        artifact_ns.need 'a:b:c:1'
+        # referenced by spec
+        artifact_ns['a:b:c'].should_not be_selected
+        
+        # referenced by name
+        artifact_ns[:b].should_not be_selected
+        artifact_ns[:b].should be_satisfied_by('a:b:c:1')
+        artifact_ns[:b].should_not be_satisfied_by('a:b:c:2')
+        artifact_ns[:b].should_not be_satisfied_by('d:b:c:1')
+        artifact_ns[:b].version.should == '1'
+      end
+    end
+
+    it 'should accept a requirement_spec' do
+      define 'one' do
+        artifact_ns.need 'thing -> a:b:c:2.1 -> ~>2.0'
+        # referenced by spec
+        artifact_ns['a:b:c'].should_not be_selected
+        
+        # referenced by name
+        artifact_ns.key?(:b).should be_false
+        artifact_ns[:thing].should_not be_selected
+        artifact_ns[:thing].should be_satisfied_by('a:b:c:2.5')
+        artifact_ns[:thing].should_not be_satisfied_by('a:b:c:3')
+        artifact_ns[:thing].version.should == '2.1'
+      end
+    end
+
+    it 'should accept a hash :name -> requirement_spec' do 
+      define 'one' do
+        artifact_ns.need :thing => 'a:b:c:2.1 -> ~>2.0'
+        artifact_ns[:thing].should be_satisfied_by('a:b:c:2.5')
+        artifact_ns[:thing].should_not be_satisfied_by('a:b:c:3')
+        artifact_ns[:thing].version.should == '2.1'
+      end
 
-  it 'should take symbols, searching for them on the current namespace' do 
-    artifacts[nil][:bar] = 'foo:bar:jar:1.0'
-    artifacts[nil].use 'foo:moo:jar:2.0'
-    artifacts[nil][:bat] = 'foo:bar:jar:0.9'
-    define 'foo' do
-      artifacts[project][:baz] = 'foo:baz:jar:1.0'
-      compile.with :bar, :baz, :'foo:moo:jar:-', 'some:other:jar:1.0'
-      classpath = compile.classpath.map(&:to_spec)
-      classpath.should include('foo:baz:jar:1.0', 'foo:bar:jar:1.0', 
-                               'foo:moo:jar:2.0', 'some:other:jar:1.0')
-      classpath.should_not include('foo:bar:jar:0.9')
+      define 'two' do
+        artifact_ns.need :thing => 'a:b:c:(~>2.0 | 2.1)'
+        artifact_ns[:thing].should be_satisfied_by('a:b:c:2.5')
+        artifact_ns[:thing].should_not be_satisfied_by('a:b:c:3')
+        artifact_ns[:thing].version.should == '2.1'
+      end
+    end
+
+    it 'should take a hash :name -> specs_array' do 
+      define 'one' do 
+        artifact_ns.need :things => ['foo:bar:jar:1.0',
+                                     'foo:baz:jar:2.0',]
+        artifact_ns['foo:bar:jar'].should_not be_selected
+        artifact_ns['foo:baz:jar'].should_not be_selected
+        artifact_ns[:bar, :baz].should == [nil, nil]
+        artifact_ns[:things].map(&:unversioned_spec).should include('foo:bar:jar', 'foo:baz:jar')
+        artifact_ns.alias :baz, 'foo:baz:jar'
+        artifact_ns[:baz].should == artifact_ns['foo:baz:jar']
+      end
+    end
+
+    it 'should select best matching version if defined' do 
+      define 'one' do 
+        artifact_ns.use :a => 'foo:bar:jar:1.5'
+        artifact_ns.use :b => 'foo:baz:jar:2.0'
+        define 'two' do
+          artifact_ns[:a].requirement.should be_nil
+          artifact_ns[:a].should be_selected
+
+          artifact_ns.need :c => 'foo:bat:jar:3.0'
+          artifact_ns['foo:bat:jar'].should_not be_selected
+          artifact_ns[:c].should_not be_selected
+          
+          artifact_ns.need :one => 'foo:bar:jar:>=1.0'
+          artifact_ns[:one].version.should == '1.5'
+          artifact_ns[:one].should be_selected
+          artifact_ns[:a].requirement.should be_nil
+
+          artifact_ns.need :two => 'foo:baz:jar:>2'
+          artifact_ns[:two].version.should be_nil
+          artifact_ns[:two].should_not be_selected
+          artifact_ns[:b].requirement.should be_nil
+        end
+      end
     end
   end
 
-  it 'should return the namespace for the current project if given a block' do
-    define 'foo' do
-      artifacts { |ns| ns.name.should == name.intern }
-      define 'bar' do 
-        artifacts { |ns| ns.name.should == name.intern }
+  describe '#use' do 
+    it 'should register the artifact on namespace' do
+      define 'one' do
+        artifact_ns.use :thing => 'a:b:c:1'
+        artifact_ns[:thing].requirement.should be_nil
+        artifact_ns[:thing].version.should == '1'
+        artifact_ns[:thing].id.should == 'b'
+        define 'one' do
+          artifact_ns.use :thing => 'a:d:c:2'
+          artifact_ns[:thing].requirement.should be_nil
+          artifact_ns[:thing].version.should == '2'
+          artifact_ns[:thing].id.should == 'd'
+          
+          artifact_ns.use :copied => artifact_ns.parent[:thing]
+          artifact_ns[:copied].should_not == artifact_ns.parent[:thing]
+          artifact_ns[:copied].requirement.should be_nil
+          artifact_ns[:copied].version.should == '1'
+          artifact_ns[:copied].id.should == 'b'
+
+          artifact_ns.use :aliased => :copied
+          artifact_ns[:aliased].should == artifact_ns[:copied]
+
+          lambda { artifact_ns.use :invalid => :unknown }.should raise_error(NameError, /undefined/i)
+        end
+        artifact_ns[:copied].should be_nil
+      end
+    end
+    
+    it 'should complain if namespace requirement is not satisfied' do
+      define 'one' do
+        artifact_ns.need :bar => 'foo:bar:baz:~>1.5'
+        lambda { artifact_ns.use :bar => '1.4' }.should raise_error(Exception, /unsatisfied/i)
       end
     end
+
+    it 'should be able to register a group' do 
+      specs = ['its:me:here:1', 'its:you:there:2']
+      artifact_ns.use :them => specs
+      artifact_ns[:them].map(&:to_spec).should == specs
+      artifact_ns['its:me:here'].should_not be_nil
+      artifact_ns[:you].should be_nil
+    end
+
+    it 'should be able to assign sub namespaces' do 
+      artifact_ns(:foo).bar = "foo:bar:baz:0"
+      artifact_ns(:moo).foo = artifact_ns(:foo)
+      artifact_ns(:moo).foo.should == artifact_ns(:foo)
+      artifact_ns(:moo).foo_bar.should == artifact_ns(:foo).bar
+    end
+
   end
 
-  it 'should take the first argument as the namespace when given a block' do 
-    artifacts('moo') { |ns| ns.name.should == :moo }
-    artifacts(:mooo) { |ns| ns.name.should == :mooo }
-    a = Module.new { def self.name; "Some::Module::A"; end }
-    artifacts(a) { |ns| ns.name.should == "Some:Module:A".intern }
-  end  
-end
+  describe '#values' do 
+    it 'returns the artifacts defined on namespace' do 
+      define 'foo' do
+        artifact_ns.use 'foo:one:baz:1.0'
+        define 'bar' do
+          artifact_ns.use 'foo:two:baz:1.0'
+          
+          specs = artifact_ns.values.map(&:to_spec)
+          specs.should include('foo:two:baz:1.0')
+          specs.should_not include('foo:one:baz:1.0')
+
+          specs = artifact_ns.values(true).map(&:to_spec)
+          specs.should include('foo:two:baz:1.0', 'foo:one:baz:1.0')
+        end
+      end
+    end
+  end
+  
+  describe '#method_missing' do 
+    it 'should use cool_aid! to create a requirement' do 
+      define 'foo' do
+        artifact_ns.cool_aid!('cool:aid:jar:2').should be_kind_of(ArtifactNamespace::ArtifactRequirement)
+        artifact_ns[:cool_aid].version.should == '2'
+        artifact_ns[:cool_aid].should_not be_selected
+        define 'bar' do 
+          artifact_ns.cool_aid! 'cool:aid:man:3', '>2'
+          artifact_ns[:cool_aid].version.should == '3'
+          artifact_ns[:cool_aid].requirement.should be_satisfied_by('2.5')
+          artifact_ns[:cool_aid].should_not be_selected
+        end
+      end
+    end
 
-describe Buildr::ArtifactNamespace do 
-  before :each do 
-    ArtifactNamespace.clear
+    it 'should use cool_aid= as shorhand for [:cool_aid]=' do 
+      artifact_ns.cool_aid = 'cool:aid:jar:1'
+      artifact_ns[:cool_aid].should be_selected
+    end
+    
+    it 'should use cool_aid as shorthand for [:cool_aid]' do
+      artifact_ns.need :cool_aid => 'cool:aid:jar:1'
+      artifact_ns.cool_aid.should_not be_selected
+    end
+
+    it 'should use cool_aid? to test if artifact has been defined and selected' do
+      artifact_ns.need :cool_aid => 'cool:aid:jar:>1'
+      artifact_ns.should_not have_cool_aid
+      artifact_ns.should_not have_unknown
+      artifact_ns.cool_aid = '2'
+      artifact_ns.should have_cool_aid
+    end
+  end
+
+  describe '#ns' do 
+    it 'should create a sub namespace' do
+      artifact_ns.ns :foo
+      artifact_ns[:foo].should be_kind_of(ArtifactNamespace)
+      artifact_ns(:foo).should_not === artifact_ns.foo
+      artifact_ns.foo.parent.should == artifact_ns
+    end
+    
+    it 'should take any use arguments' do
+      artifact_ns.ns :foo, :bar => 'foo:bar:jar:0', :baz => 'foo:baz:jar:0'
+      artifact_ns.foo.bar.should be_selected
+      artifact_ns.foo[:baz].should be_selected
+    end
+    
+    it 'should access sub artifacts using with foo_bar like syntax' do 
+      artifact_ns.ns :foo, :bar => 'foo:bar:jar:0', :baz => 'foo:baz:jar:0'
+      artifact_ns[:foo_baz].should be_selected
+      artifact_ns.foo_bar.should be_selected
+      
+      artifact_ns.foo.ns :bat, 'bat:man:jar:>1'
+      batman = artifact_ns.foo.bat.man
+      batman.should be_selected
+      artifact_ns[:foo_bat_man] = '3'
+      artifact_ns[:foo_bat_man].should == batman
+      artifact_ns[:foo_bat_man].version.should == '3'
+    end
+
+    it 'should include sub artifacts when calling #values' do 
+      artifact_ns.ns :bat, 'bat:man:jar:>1'
+      artifact_ns.values.should_not be_empty
+      artifact_ns.values.first.unversioned_spec.should == 'bat:man:jar'
+    end
+
+    it 'should reopen a sub-namespace' do
+      artifact_ns.ns :bat, 'bat:man:jar:>1'
+      bat = artifact_ns[:bat]
+      bat.should == artifact_ns.ns(:bat)
+    end
+
+    it 'should fail reopening if not a sub-namespace' do
+      artifact_ns.foo = 'foo:bar:baz:0'
+      lambda { artifact_ns.ns(:foo) }.should raise_error(TypeError, /not a sub/i)
+    end
+
+    it 'should clone artifacts when assigned' do 
+      artifact_ns(:foo).bar = "foo:bar:jar:0"
+      artifact_ns(:moo).ns :muu, :miu => artifact_ns(:foo).bar
+      artifact_ns(:moo).muu.miu.should_not == artifact_ns(:foo).bar
+      artifact_ns(:moo).muu.miu.to_spec.should == artifact_ns(:foo).bar.to_spec
+    end
+    
+    it 'should clone parent artifacts by name' do
+      define 'foo' do
+        artifact_ns.bar = "foo:bar:jar:0"
+        define 'moo' do
+          artifact_ns.ns(:muu).use :bar
+          artifact_ns.muu_bar.should be_selected
+          artifact_ns.muu.bar.should_not == artifact_ns.bar
+        end
+      end
+    end
   end
 
-  it 'should have no parent if its the root namespace' do
-    root = artifacts[nil]
-    root.parent.should be_nil
+  it 'should be an Enumerable' do
+    Enumerable === artifact_ns
+    artifact_ns.use 'foo:bar:baz:1.0'
+    artifact_ns.map(&:artifact).should include(artifact('foo:bar:baz:1.0'))
   end
 
-  it 'should reference it\'s parent' do
-    root = artifacts[nil]
-    define 'foo' do
-      foo = artifacts { |ns| ns.parent.should == root }
+end # ArtifactNamespace
+
+describe Buildr, '.artifact' do
+  before(:each) { Buildr::ArtifactNamespace.clear }
+  
+  it 'should search current namespace if given a symbol' do 
+    define 'foo' do 
+      artifact_ns.use :cool => 'cool:aid:jar:1.0'
       define 'bar' do
-        artifacts { |ns| ns.parent.should == foo }
+        artifact(:cool).should == artifact_ns[:cool].artifact
       end
     end
   end
 
-  it 'should take the artifact id attribute as name' do
-     artifacts do |ns|
-        ns.need 'foo:bar:jar:>1.0'
-        ns.default :bar => '1.1'
-        ns.spec('foo:bar:jar:-')[:version].should == '1.1'
-        ns.use 'some:thing:jar:2.0'
-        ns.spec(:thing)[:version].should == '2.0'
-        ns.spec('some:thing:jar:-')[:version].should == '2.0'
-     end
-  end
-
-  it 'should register a requirement with the #need method' do
-    artifacts do |ns|
-      ns.need 'foo:bar:jar:>1.0'
-      ns.should_not be_satisfied('foo:bar:jar:?')
-      ns.need :bat => 'foo:bat:jar:>1.0'
-      ns.should_not be_satisfied(:bat)
-    end
-    artifacts('foo') do |ns|
-      ns.need 'foo:baz:jar:>1.0' => '2.0'
-      ns.spec('foo:baz:jar:-').values_at(:id, :version).should == ['baz', '2.0']
-      ns.spec(:baz).values_at(:id, :version).should == ['baz', '2.0']
-    end
-  end
-
-  it 'should register an artifact with the #use method' do
-    artifacts do |ns|
-      ns.use :bat => 'bat:bar:jar:2.0'
-      ns.spec(:bat).should_not be_nil
-      ns.spec(:bat)[:version].should == '2.0'
-      ns.spec(:bat)[:group].should == 'bat'
-      artifacts(:bat).should_not be_empty
-      ns.use 'bat:man:jar:3.0'
-      ns.spec('bat:man:jar:?')[:version].should == '3.0'
-      artifacts('bat:man:jar:?').should_not be_empty
-    end
-  end
-
-  it 'should set defaults witht the #default method' do 
-    artifacts do |ns|
-      ns.use :bar => 'foo:bar:jar:2.0'
-      ns.spec(:bar)[:version].should == '2.0'
-      ns.default :bar => 'foo:bar:jar:1.9'
-      ns.spec(:bar)[:version].should == '2.0'
-      ns.default :baz => 'foo:baz:jar:1.8'
-      ns.spec(:baz)[:version].should == '1.8'
-      ns.need :bat => 'foo:bat:jar:>1.0'
-      ns.default :bat => 'foo:bat:jar:1.5'
-      ns.spec(:bat)[:version].should == '1.5'
-    end
-  end
-
-  it 'should complain if requirement is not met' do 
-    artifacts do |ns|
-      ns.need :foo => 'foo:bar:jar:>3.0'
-      lambda { ns.use :foo => '2.0' }.should raise_error(Exception)
-      lambda { ns.use :foo => 'foo:baz:jar:3.1' }.should raise_error(Exception)
-      ns.use :foo => '3.2'
-      ns.spec(:foo)[:version].should == '3.2'
-      ns.use :bat => '2.0'
-      lambda { ns.need :bat => 'foo:bat:jar:>2.0' }.should raise_error(Exception)
-      ns.use :baz => 'foo:ban:jar:2.1'
-      lambda { ns.need :baz => 'foo:baz:jar:>2.0' }.should raise_error(Exception)
-    end
-  end
-
-  it 'should be populated with ArtifactNamespace.load given a hash of hashes' do 
-    hash = {}
-    hash[nil] = Hash[:foo => 'foo:bar:jar:1.0']
-    hash['one'] = Hash[:foo => 'foo:bar:jar:2.0']
-    ArtifactNamespace.load(hash)
-    artifacts[nil].spec(:foo)[:version].should == '1.0'
-    artifacts['one'].spec(:foo)[:version].should == '2.0'
-  end
-
-  it 'should select compatible artifacts defined on parent namespaces' do
-    artifacts do |ns|
-      ns.use :foo => 'foo:bar:jar:3.0'
-      ns.use :baz => 'foo:baz:jar:1.0'
-      ns.use 'foo:bat:jar:1.5.6.7'
-    end
-    module Some
-      Buildr.artifacts(self) do |ns|
-        ns.need :foo => 'foo:bar:jar:>=1.0'
-        ns.need :baz => 'foo:baz:jar:>=2.0'
-        ns.need :bat => 'foo:bat:jar:>1.5 & <1.6'
-        ns.default :foo => '2.0'
-        ns.default :baz => '2.0'
-        ns.default :bat => '1.5.5'
-      end
-    end
-    artifacts[Some].spec(:foo)[:version].should == '3.0'
-    artifacts[Some].spec(:baz)[:version].should == '2.0'
-    artifacts[Some].spec(:bat)[:version].should == '1.5.6.7'
-  end
-
-  it 'should return its artifacts when called the #values method' do
-    artifacts do |ns|
-      ns.use "num:one:jar:1.1", "num:two:jar:2.2"
-    end
-    artifacts('foo') do |ns|
-      ns.need :one => 'num:one:jar:>=1.0'
-      ns.default :one => '1.0'
-      ns.need :three => 'num:three:jar:>=3.0'
-      ns.default :three => '3.0'
-    end
-    foo = artifacts['foo'].values.map(&:to_spec)
-    foo.should include("num:one:jar:1.1", "num:three:jar:3.0")
-    foo = artifacts['foo'].values(true).map(&:to_spec) # including parents
-    foo.should include("num:one:jar:1.1", "num:three:jar:3.0", "num:two:jar:2.2")
-    artifacts['foo'].need :four => 'num:four:jar:>4.0'
-    lambda { artifacts[:foo].values }.should raise_error(Exception, /no version/i)
-    foo = artifacts['foo'].values(false, true).map(&:to_spec) # ignore missing
-    foo.should include("num:one:jar:1.1", "num:three:jar:3.0")
+  it 'should search current namespace if given a symbol spec' do 
+    define 'foo' do 
+      artifact_ns.use 'cool:aid:jar:1.0'
+      define 'bar' do
+        artifact(:'cool:aid:jar').should == artifact_ns[:aid].artifact
+      end
+    end
+  end
+  
+  it 'should fail when no artifact by that name is found' do
+    define 'foo' do 
+      artifact_ns.use 'cool:aid:jar:1.0'
+      define 'bar' do
+        lambda { artifact(:cool) }.should raise_error(IndexError, /artifact/)
+      end
+    end
   end
-
 end
+