#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/auto_unit_test.hpp>
+#include "TestSetup.h"
#include "zypp/Arch.h"
#include "zypp/Capability.h"
#include "zypp/Capabilities.h"
using namespace std;
using namespace zypp;
+static TestSetup test( Arch_x86_64 );
+
BOOST_AUTO_TEST_CASE(capabilities_test)
{
//////////////////////////////////////////////////////////////////////
BOOST_CHECK_EQUAL( Capability( Arch_i386, "na.me == 1" ), naoe );
}
+BOOST_AUTO_TEST_CASE(guessPackageSpec)
+{
+ BOOST_CHECK_EQUAL( Capability::guessPackageSpec( "" ),
+ Capability( "", "", "", "" ) );
+
+ // With no libzypp in the pool, no guess should succeed:
+ BOOST_REQUIRE( sat::WhatProvides(Capability("libzypp")).empty() );
+
+ BOOST_CHECK_EQUAL( Capability::guessPackageSpec( "libzypp-1-2" ), Capability( "", "libzypp-1-2", "", "" ) );
+ BOOST_CHECK_EQUAL( Capability::guessPackageSpec( "libzypp-1-2.i586" ), Capability( "i586", "libzypp-1-2", "", "" ) );
+ BOOST_CHECK_EQUAL( Capability::guessPackageSpec( "libzypp.i586-1-2" ), Capability( "", "libzypp.i586-1-2", "", "" ) );
+
+ // now load some repo prividing libzypp and csee how the guessing
+ // changes:
+ test.loadRepo( TESTS_SRC_DIR "/data/openSUSE-11.1", "opensuse" );
+
+ BOOST_REQUIRE( ! sat::WhatProvides(Capability("libzypp")).empty() );
+
+ BOOST_CHECK_EQUAL( Capability::guessPackageSpec( "libzypp-1-2" ), Capability( "", "libzypp", "=", "1-2" ) );
+ BOOST_CHECK_EQUAL( Capability::guessPackageSpec( "libzypp-1-2.i586" ), Capability( "i586", "libzypp", "=", "1-2" ) );
+ BOOST_CHECK_EQUAL( Capability::guessPackageSpec( "libzypp.i586-1-2" ), Capability( "i586", "libzypp", "=", "1-2" ) );
+
+ // Double arch spec: the trailing one succeeds, the other one gets part of the name.
+ // As "libzypp.i586' is not in the pool, guessing fails. Result is a named cap.
+ BOOST_CHECK_EQUAL( Capability::guessPackageSpec( "libzypp.i586-1-2.ppc" ),
+ Capability( "ppc", "libzypp.i586-1-2", "", "" ) );
+}
+
+
return str::regex_match( name_r, what, filenameRegex );
}
+ Capability Capability::guessPackageSpec( const std::string & str_r )
+ {
+ Capability cap( str_r );
+ CapDetail detail( cap.detail() );
+
+ // str_r might be the form "libzypp-1.2.3-4.5(.arch)'
+ // correctly parsed as name capability by the ctor.
+ if ( detail.isNamed() && ::strrchr( detail.name().c_str(), '-' ) && sat::WhatProvides( cap ).empty() )
+ {
+ Arch origArch( detail.arch() ); // to support a trailing .arch
+
+ std::string guess( detail.name().asString() );
+ std::string::size_type pos( guess.rfind( '-' ) );
+ guess[pos] = '=';
+
+ Capability guesscap( origArch, guess );
+ detail = guesscap.detail();
+
+ if ( ! sat::WhatProvides( Capability(detail.name().id()) ).empty() )
+ return guesscap;
+
+ // try the one but last '-'
+ if ( pos )
+ {
+ guess[pos] = '-';
+ if ( (pos = guess.rfind( '-', pos-1 )) != std::string::npos )
+ {
+ guess[pos] = '=';
+
+ guesscap = Capability( origArch, guess );
+ detail = guesscap.detail();
+
+ if ( ! sat::WhatProvides( Capability(detail.name().id()) ).empty() )
+ return guesscap;
+ }
+ }
+ }
+ return cap;
+ }
+
/******************************************************************
**
** FUNCTION NAME : operator<<
static bool isInterestingFileSpec( const std::string & name_r ) { return isInterestingFileSpec( name_r.c_str() ); }
static bool isInterestingFileSpec( const char * name_r );
+ /** \ref Capability parser also guessing \c "libzypp-1.2.3-4.5.x86_64" formats.
+ *
+ * The argument might be in the form \c "libzypp-devel-1.2.3.x86_64".
+ * Passed to the Capability ctor, this would correctly be parsed as name
+ * capability, because actually the edition part had to be separated by a
+ * \c '=', and the architecture had to be appended to the name.
+ * So this is how it actually had to look like: \c "libzypp-devel.x86_64=1.2.3"
+ *
+ * Obviously we have to guess if, and where to split name and edition. In
+ * fact \c "devel" could also be the version and \c "1.2.3" would be the
+ * release then.
+ *
+ * Assuming this Capability should be provided by some package in
+ * the \ref ResPool, we check this. If unprovided, we substitute the last,
+ * (or one but last) \c '-' by a \c '='. If the name part
+ * (without version) of the resulting Capability is provided
+ * by the \ref ResPool, this Capability is returned.
+ *
+ * Otherwise we return the Capability originally created from
+ * \a str_r.
+ *
+ * \note: As this method will access the global pool, the returned
+ * result depends on the pools content.
+ */
+ static Capability guessPackageSpec( const std::string & str_r );
+
public:
/** Expert backdoor. */
sat::detail::IdType id() const