winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

TestSource.cpp (15973B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "TestCommon.h"
      5 #include "TestSource.h"
      6 
      7 using namespace AppInstaller;
      8 using namespace AppInstaller::Repository;
      9 
     10 namespace TestCommon
     11 {
     12     namespace
     13     {
     14         size_t GetNextTestPackageId()
     15         {
     16             static std::atomic_size_t packageId(0);
     17             return ++packageId;
     18         }
     19 
     20         TestSource* GetTestSourceFromWeakPtr(const std::weak_ptr<const ISource>& weakSource)
     21         {
     22             if (auto source = weakSource.lock())
     23             {
     24                 if (auto testSource = const_cast<ISource*>(source.get())->CastTo(TestSource::SourceType))
     25                 {
     26                     return reinterpret_cast<TestSource*>(testSource);
     27                 }
     28             }
     29 
     30             return nullptr;
     31         }
     32     }
     33 
     34     TestPackageVersion::TestPackageVersion(const Manifest& manifest, MetadataMap installationMetadata, std::weak_ptr<const ISource> source) :
     35         VersionManifest(manifest), Metadata(std::move(installationMetadata)), Source(source) {}
     36 
     37     TestPackageVersion::TestPackageVersion(const Manifest& manifest, std::weak_ptr<const ISource> source, bool hideSystemReferenceStrings) :
     38         VersionManifest(manifest), Source(source), HideSystemReferenceStrings(hideSystemReferenceStrings) {}
     39 
     40     TestPackageVersion::LocIndString TestPackageVersion::GetProperty(PackageVersionProperty property) const
     41     {
     42         switch (property)
     43         {
     44         case PackageVersionProperty::Id:
     45             return LocIndString{ VersionManifest.Id };
     46         case PackageVersionProperty::Name:
     47             return LocIndString{ VersionManifest.DefaultLocalization.Get<AppInstaller::Manifest::Localization::PackageName>() };
     48         case PackageVersionProperty::Version:
     49             return LocIndString{ VersionManifest.Version };
     50         case PackageVersionProperty::Channel:
     51             return LocIndString{ VersionManifest.Channel };
     52         case PackageVersionProperty::SourceIdentifier:
     53             return LocIndString{ Source.lock()->GetIdentifier() };
     54         case PackageVersionProperty::Publisher:
     55             return LocIndString{ VersionManifest.DefaultLocalization.Get<AppInstaller::Manifest::Localization::Publisher>() };
     56         case PackageVersionProperty::ArpMinVersion:
     57             return LocIndString{ VersionManifest.GetArpVersionRange().IsEmpty() ? "" : VersionManifest.GetArpVersionRange().GetMinVersion().ToString() };
     58         case PackageVersionProperty::ArpMaxVersion:
     59             return LocIndString{ VersionManifest.GetArpVersionRange().IsEmpty() ? "" : VersionManifest.GetArpVersionRange().GetMaxVersion().ToString() };
     60         default:
     61             return {};
     62         }
     63     }
     64 
     65     std::vector<TestPackageVersion::LocIndString> TestPackageVersion::GetMultiProperty(PackageVersionMultiProperty property) const
     66     {
     67         std::vector<LocIndString> result;
     68 
     69         switch (property)
     70         {
     71         case PackageVersionMultiProperty::PackageFamilyName:
     72             if (!HideSystemReferenceStrings)
     73             {
     74                 for (const auto& installer : VersionManifest.Installers)
     75                 {
     76                     AddIfHasValueAndNotPresent(installer.PackageFamilyName, result, true);
     77                 }
     78             }
     79             break;
     80         case PackageVersionMultiProperty::ProductCode:
     81             if (!HideSystemReferenceStrings)
     82             {
     83                 for (const auto& installer : VersionManifest.Installers)
     84                 {
     85                     bool shouldFoldCaseForNonPortable = installer.EffectiveInstallerType() != AppInstaller::Manifest::InstallerTypeEnum::Portable;
     86                     AddIfHasValueAndNotPresent(installer.ProductCode, result, shouldFoldCaseForNonPortable);
     87                 }
     88             }
     89             break;
     90         case PackageVersionMultiProperty::Name:
     91             for (auto name : VersionManifest.GetPackageNames())
     92             {
     93                 result.emplace_back(std::move(name));
     94             }
     95             break;
     96         case PackageVersionMultiProperty::Publisher:
     97             for (auto publisher : VersionManifest.GetPublishers())
     98             {
     99                 result.emplace_back(std::move(publisher));
    100             }
    101             break;
    102         case PackageVersionMultiProperty::Locale:
    103             result.emplace_back(VersionManifest.DefaultLocalization.Locale);
    104             for (const auto& loc : VersionManifest.Localizations)
    105             {
    106                 result.emplace_back(loc.Locale);
    107             }
    108             break;
    109         }
    110 
    111         return result;
    112     }
    113 
    114     TestPackageVersion::Manifest TestPackageVersion::GetManifest()
    115     {
    116         if (auto source = GetTestSource())
    117         {
    118             source->IncrementCountOfCallsRequiringManifestData();
    119         }
    120 
    121         return VersionManifest;
    122     }
    123 
    124     Repository::Source TestPackageVersion::GetSource() const
    125     {
    126         return std::const_pointer_cast<TestPackageVersion::ISource>(Source.lock());
    127     }
    128 
    129     TestPackageVersion::MetadataMap TestPackageVersion::GetMetadata() const
    130     {
    131         return Metadata;
    132     }
    133 
    134     void TestPackageVersion::AddIfHasValueAndNotPresent(const Utility::NormalizedString& value, std::vector<LocIndString>& target, bool folded)
    135     {
    136         if (!value.empty())
    137         {
    138             std::string valueString = folded ? FoldCase(value) : value;
    139             auto itr = std::find(target.begin(), target.end(), valueString);
    140             if (itr == target.end())
    141             {
    142                 target.emplace_back(std::move(valueString));
    143             }
    144         }
    145     }
    146 
    147     TestSource* TestPackageVersion::GetTestSource() const
    148     {
    149         return GetTestSourceFromWeakPtr(Source);
    150     }
    151 
    152     TestPackage::TestPackage(const std::vector<Manifest>& available, std::weak_ptr<const ISource> source, bool hideSystemReferenceStringsOnVersion) :
    153         Source(source)
    154     {
    155         DefaultIsSameIdentity = GetNextTestPackageId();
    156         for (const auto& manifest : available)
    157         {
    158             Versions.emplace_back(TestPackageVersion::Make(manifest, source, hideSystemReferenceStringsOnVersion));
    159         }
    160     }
    161 
    162     TestPackage::TestPackage(const Manifest& installed, MetadataMap installationMetadata, std::weak_ptr<const ISource> source) :
    163         Source(source)
    164     {
    165         DefaultIsSameIdentity = GetNextTestPackageId();
    166         Versions.emplace_back(TestPackageVersion::Make(installed, std::move(installationMetadata), source));
    167     }
    168 
    169     TestPackage::LocIndString TestPackage::GetProperty(PackageProperty property) const
    170     {
    171         std::shared_ptr<IPackageVersion> truth;
    172 
    173         if (!Versions.empty())
    174         {
    175             truth = Versions[0];
    176         }
    177 
    178         if (!truth)
    179         {
    180             THROW_HR(E_NOT_VALID_STATE);
    181         }
    182 
    183         switch (property)
    184         {
    185         case PackageProperty::Id:
    186             return truth->GetProperty(PackageVersionProperty::Id);
    187         case PackageProperty::Name:
    188             return truth->GetProperty(PackageVersionProperty::Name);
    189         default:
    190             return {};
    191         }
    192     }
    193 
    194     std::vector<TestPackage::LocIndString> TestPackage::GetMultiProperty(PackageMultiProperty property) const
    195     {
    196         std::vector<LocIndString> result;
    197         PackageVersionMultiProperty mappedProperty = PackageMultiPropertyToPackageVersionMultiProperty(property);
    198 
    199         for (const auto& version : Versions)
    200         {
    201             for (auto&& string : version->GetMultiProperty(mappedProperty))
    202             {
    203                 auto itr = std::lower_bound(result.begin(), result.end(), string);
    204 
    205                 if (itr == result.end() || *itr != string)
    206                 {
    207                     result.emplace(itr, std::move(string));
    208                 }
    209             }
    210         }
    211 
    212         return result;
    213     }
    214 
    215     std::vector<PackageVersionKey> TestPackage::GetVersionKeys() const
    216     {
    217         if (auto source = GetTestSource())
    218         {
    219             source->IncrementCountOfCallsRequiringVersionData();
    220         }
    221 
    222         std::vector<PackageVersionKey> result;
    223         for (const auto& version : Versions)
    224         {
    225             result.emplace_back(PackageVersionKey(version->GetSource().GetIdentifier(), version->GetProperty(PackageVersionProperty::Version).get(), version->GetProperty(PackageVersionProperty::Channel).get()));
    226         }
    227         return result;
    228     }
    229 
    230     std::shared_ptr<IPackageVersion> TestPackage::GetLatestVersion() const
    231     {
    232         if (Versions.empty())
    233         {
    234             return {};
    235         }
    236 
    237         return Versions[0];
    238     }
    239 
    240     std::shared_ptr<IPackageVersion> TestPackage::GetVersion(const PackageVersionKey& versionKey) const
    241     {
    242         if (!versionKey.IsDefaultLatest())
    243         {
    244             if (auto source = GetTestSource())
    245             {
    246                 source->IncrementCountOfCallsRequiringVersionData();
    247             }
    248         }
    249 
    250         for (const auto& version : Versions)
    251         {
    252             if ((versionKey.Version.empty() || versionKey.Version == version->GetProperty(PackageVersionProperty::Version).get()) && 
    253                 (versionKey.Channel.empty() || versionKey.Channel == version->GetProperty(PackageVersionProperty::Channel).get()))
    254             {
    255                 return version;
    256             }
    257         }
    258 
    259         return {};
    260     }
    261 
    262     Repository::Source TestPackage::GetSource() const
    263     {
    264         return std::const_pointer_cast<TestPackage::ISource>(Source.lock());
    265     }
    266 
    267     bool TestPackage::IsSame(const IPackage* other) const
    268     {
    269         if (IsSameOverride)
    270         {
    271             return IsSameOverride(this, other);
    272         }
    273 
    274         const TestPackage* otherPackage = PackageCast<const TestPackage*>(other);
    275 
    276         if (otherPackage && DefaultIsSameIdentity == otherPackage->DefaultIsSameIdentity)
    277         {
    278             return true;
    279         }
    280 
    281         return false;
    282     }
    283 
    284     const void* TestPackage::CastTo(IPackageType type) const
    285     {
    286         if (type == PackageType)
    287         {
    288             return this;
    289         }
    290 
    291         return nullptr;
    292     }
    293 
    294     TestSource* TestPackage::GetTestSource() const
    295     {
    296         return GetTestSourceFromWeakPtr(Source);
    297     }
    298 
    299     TestCompositePackage::TestCompositePackage(const std::vector<Manifest>& available, std::weak_ptr<const ISource> source, bool hideSystemReferenceStringsOnVersion)
    300     {
    301         if (!available.empty())
    302         {
    303             Available.emplace_back(TestPackage::Make(available, source, hideSystemReferenceStringsOnVersion));
    304         }
    305     }
    306 
    307     TestCompositePackage::TestCompositePackage(const Manifest& installed, MetadataMap installationMetadata, const std::vector<Manifest>& available, std::weak_ptr<const ISource> source) :
    308         Installed(TestPackage::Make(installed, std::move(installationMetadata), source))
    309     {
    310         if (!available.empty())
    311         {
    312             Available.emplace_back(TestPackage::Make(available, source));
    313         }
    314     }
    315 
    316     TestCompositePackage::LocIndString TestCompositePackage::GetProperty(PackageProperty property) const
    317     {
    318         std::shared_ptr<IPackage> truth;
    319 
    320         if (!Available.empty())
    321         {
    322             truth = Available[0];
    323         }
    324         else
    325         {
    326             truth = Installed;
    327         }
    328 
    329         if (!truth)
    330         {
    331             THROW_HR(E_NOT_VALID_STATE);
    332         }
    333 
    334         switch (property)
    335         {
    336         case PackageProperty::Id:
    337             return truth->GetProperty(PackageProperty::Id);
    338         case PackageProperty::Name:
    339             return truth->GetProperty(PackageProperty::Name);
    340         default:
    341             return {};
    342         }
    343     }
    344 
    345     std::shared_ptr<AppInstaller::Repository::IPackage> TestCompositePackage::GetInstalled()
    346     {
    347         return Installed;
    348     }
    349 
    350     std::vector<std::shared_ptr<AppInstaller::Repository::IPackage>> TestCompositePackage::GetAvailable()
    351     {
    352         return { Available.begin(), Available.end() };
    353     }
    354 
    355     const SourceDetails& TestSource::GetDetails() const
    356     {
    357         return Details;
    358     }
    359 
    360     const std::string& TestSource::GetIdentifier() const
    361     {
    362         return Details.Identifier;
    363     }
    364 
    365     SourceInformation TestSource::GetInformation() const
    366     {
    367         return Information;
    368     }
    369 
    370     bool TestSource::QueryFeatureFlag(SourceFeatureFlag flag) const
    371     {
    372         return (QueryFeatureFlagFunction ? QueryFeatureFlagFunction(flag) : false);
    373     }
    374 
    375     SearchResult TestSource::Search(const SearchRequest& request) const
    376     {
    377         if (SearchFunction)
    378         {
    379             return SearchFunction(request);
    380         }
    381         else
    382         {
    383             return {};
    384         }
    385     }
    386 
    387     void* TestSource::CastTo(AppInstaller::Repository::ISourceType type)
    388     {
    389         if (type == SourceType)
    390         {
    391             return this;
    392         }
    393 
    394         return nullptr;
    395     }
    396 
    397     void TestSource::IncrementCountOfCallsRequiringVersionData()
    398     {
    399         ++CountOfCallsRequiringVersionData;
    400     }
    401 
    402     void TestSource::IncrementCountOfCallsRequiringManifestData()
    403     {
    404         ++CountOfCallsRequiringManifestData;
    405     }
    406 
    407     std::string_view TestSourceFactory::TypeName() const
    408     {
    409         return "*TestSource"sv;
    410     }
    411 
    412     std::shared_ptr<ISourceReference> TestSourceFactory::Create(const SourceDetails& details)
    413     {
    414         std::shared_ptr<TestSourceReference> result;
    415 
    416         if (OnOpenWithCustomHeader)
    417         {
    418             result = std::make_shared<TestSourceReference>(details, OnOpenWithCustomHeader);
    419         }
    420         else
    421         {
    422             result = std::make_shared<TestSourceReference>(details, OnOpen);
    423         }
    424 
    425         result->ShouldUpdateBeforeOpenResult = ShouldUpdateBeforeOpenResult;
    426 
    427         return result;
    428     }
    429 
    430     bool TestSourceFactory::Add(SourceDetails& details, IProgressCallback&)
    431     {
    432         if (OnAdd)
    433         {
    434             OnAdd(details);
    435         }
    436         return true;
    437     }
    438 
    439     bool TestSourceFactory::Update(const SourceDetails& details, IProgressCallback&)
    440     {
    441         if (OnUpdate)
    442         {
    443             OnUpdate(details);
    444         }
    445         return true;
    446     }
    447 
    448     bool TestSourceFactory::Remove(const SourceDetails& details, IProgressCallback&)
    449     {
    450         if (OnRemove)
    451         {
    452             OnRemove(details);
    453         }
    454         return true;
    455     }
    456 
    457     // Make copies of self when requested.
    458     TestSourceFactory::operator std::function<std::unique_ptr<ISourceFactory>()>()
    459     {
    460         return [this]() { return std::make_unique<TestSourceFactory>(*this); };
    461     }
    462 
    463     bool AddSource(const AppInstaller::Repository::SourceDetails& details, AppInstaller::IProgressCallback& progress)
    464     {
    465         Repository::Source source{ details.Name, details.Arg, details.Type, Repository::SourceTrustLevel::None, false };
    466         return source.Add(progress);
    467     }
    468 
    469     bool UpdateSource(std::string_view name, AppInstaller::IProgressCallback& progress)
    470     {
    471         Repository::Source source{ name };
    472         return source.Update(progress).empty();
    473     }
    474 
    475     bool RemoveSource(std::string_view name, AppInstaller::IProgressCallback& progress)
    476     {
    477         Repository::Source source{ name };
    478         return source.Remove(progress);
    479     }
    480 
    481     std::vector<AppInstaller::Repository::SourceDetails> GetSources()
    482     {
    483         return Repository::Source::GetCurrentSources();
    484     }
    485 
    486     AppInstaller::Repository::Source OpenSource(std::string_view name, AppInstaller::IProgressCallback& progress)
    487     {
    488         Repository::Source source{ name };
    489         source.Open(progress);
    490         return source;
    491     }
    492 
    493     void DropSource(std::string_view name)
    494     {
    495         Source::DropSource(name);
    496     }
    497 }