Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  VLCInputItemTest.m  Sprache: unbekannt

 
Spracherkennung für: .m vermutete Sprache: Lisp {Lisp[45] Masm[45] Cobol[24]} [Methode: maximale Elemente, drei Dimensionen]

/****************************************************************************
 * VLCInputItemTest.m: VLC input item native tests
 ****************************************************************************
 * Copyright (C) 2026 VLC authors and VideoLAN
 *
 * Authors: Claudio Cambra <developer@claudiocambra.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any later
 * version.
 *****************************************************************************/


#import <XCTest/XCTest.h>

#import "library/VLCInputItem.h"
#import "tests/VLCInputItemTestSupport.h"

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnonnull"

@interface VLCInputItem (VLCInputItemTestPrivate)
- (void)parsingEnded:(int)status;
- (void)subTreeAdded:(input_item_node_t *)p_node;
@end

@interface VLCInputItemTest : XCTestCase
@end

@implementation VLCInputItemTest

- (input_item_t *)newFileInputItem
{
    return input_item_NewFile("file:///tmp/VLC%20Test.mp4",
                              "Original Name",
                              VLC_TICK_FROM_SEC(123),
                              ITEM_LOCAL);
}

- (void)testInitializationMapsCoreProperties
{
    input_item_t * const coreItem = [self newFileInputItem];
    XCTAssertNotEqual(coreItem, NULL);

    input_item_SetTitle(coreItem, "Metadata Title");
    input_item_SetArtist(coreItem, "Artist");
    input_item_SetAlbum(coreItem, "Album");
    input_item_SetTrackNumber(coreItem, "4");
    input_item_SetGenre(coreItem, "Genre");
    input_item_SetCopyright(coreItem, "Copyright");
    input_item_SetPublisher(coreItem, "Publisher");
    input_item_SetLanguage(coreItem, "en");
    input_item_SetDate(coreItem, "2026");
    input_item_SetDescription(coreItem, "Description");
    input_item_SetEncodedBy(coreItem, "Encoder");
    input_item_SetTrackID(coreItem, "track-id");
    input_item_SetTrackTotal(coreItem, "10");
    input_item_SetDirector(coreItem, "Director");
    input_item_SetSeason(coreItem, "2");
    input_item_SetEpisode(coreItem, "3");
    input_item_SetShowName(coreItem, "Show");
    input_item_SetActors(coreItem, "Actor");
    input_item_SetDiscNumber(coreItem, "1");
    input_item_SetDiscTotal(coreItem, "2");
    input_item_SetMetaExtra(coreItem, "custom", "value");
    input_item_AddOption(coreItem, "network-caching=1000", 0);
    input_item_AddOption(coreItem, "http-referrer=https://example.com", 0);
    input_item_SetArtworkURL(coreItem, "https://example.com/art.jpg");

    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    XCTAssertNotNil(inputItem);
    XCTAssertEqualObjects(inputItem.MRL, @"file:///tmp/VLC%20Test.mp4");
    XCTAssertEqualObjects(inputItem.decodedMRL, @"file:///tmp/VLC Test.mp4");
    XCTAssertEqualObjects(inputItem.path, @"/tmp/VLC Test.mp4");
    XCTAssertEqualObjects(inputItem.name, @"Original Name");
    XCTAssertEqualObjects(inputItem.title, @"Metadata Title");
    XCTAssertEqualObjects(inputItem.artist, @"Artist");
    XCTAssertEqualObjects(inputItem.album, @"Album");
    XCTAssertEqualObjects(inputItem.trackNumber, @"4");
    XCTAssertEqualObjects(inputItem.genre, @"Genre");
    XCTAssertEqualObjects(inputItem.copyright, @"Copyright");
    XCTAssertEqualObjects(inputItem.publisher, @"Publisher");
    XCTAssertEqualObjects(inputItem.language, @"en");
    XCTAssertEqualObjects(inputItem.date, @"2026");
    XCTAssertEqualObjects(inputItem.contentDescription, @"Description");
    XCTAssertEqualObjects(inputItem.encodedBy, @"Encoder");
    XCTAssertEqualObjects(inputItem.trackID, @"track-id");
    XCTAssertEqualObjects(inputItem.trackTotal, @"10");
    XCTAssertEqualObjects(inputItem.director, @"Director");
    XCTAssertEqualObjects(inputItem.season, @"2");
    XCTAssertEqualObjects(inputItem.episode, @"3");
    XCTAssertEqualObjects(inputItem.showName, @"Show");
    XCTAssertEqualObjects(inputItem.actors, @"Actor");
    XCTAssertEqualObjects(inputItem.discNumber, @"1");
    XCTAssertEqualObjects(inputItem.totalNumberOfDiscs, @"2");
    XCTAssertEqual(inputItem.duration, VLC_TICK_FROM_SEC(123));
    XCTAssertEqual(inputItem.inputType, ITEM_TYPE_FILE);
    XCTAssertFalse(inputItem.isStream);
    XCTAssertFalse(inputItem.preparsed);
    XCTAssertEqualObjects(inputItem.options,
                          (@[ @"network-caching=1000", @"http-referrer=https://example.com" ]));
    XCTAssertEqualObjects([inputItem extraMetaForKey:@"custom"], @"value");
    XCTAssertEqualObjects(inputItem.extraMetaNames, (@[ @"custom" ]));
    XCTAssertEqualObjects(inputItem.artworkURL.absoluteString, @"https://example.com/art.jpg");
    XCTAssertNil(inputItem.finderTags);
}

- (void)testMetadataSettersUpdateCoreItem
{
    input_item_t * const coreItem = [self newFileInputItem];
    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    inputItem.name = @"New Name";
    inputItem.title = @"New Title";
    inputItem.artist = @"New Artist";
    inputItem.album = @"New Album";
    inputItem.trackNumber = @"8";
    inputItem.genre = @"New Genre";
    inputItem.copyright = @"New Copyright";
    inputItem.publisher = @"New Publisher";
    inputItem.language = @"fr";
    inputItem.date = @"2027";
    inputItem.contentDescription = @"New Description";
    inputItem.director = @"New Director";
    inputItem.showName = @"New Show";
    inputItem.actors = @"New Actor";

    XCTAssertEqualObjects(inputItem.name, @"New Name");
    XCTAssertEqualObjects(inputItem.title, @"New Title");
    XCTAssertEqualObjects(inputItem.artist, @"New Artist");
    XCTAssertEqualObjects(inputItem.album, @"New Album");
    XCTAssertEqualObjects(inputItem.trackNumber, @"8");
    XCTAssertEqualObjects(inputItem.genre, @"New Genre");
    XCTAssertEqualObjects(inputItem.copyright, @"New Copyright");
    XCTAssertEqualObjects(inputItem.publisher, @"New Publisher");
    XCTAssertEqualObjects(inputItem.language, @"fr");
    XCTAssertEqualObjects(inputItem.date, @"2027");
    XCTAssertEqualObjects(inputItem.contentDescription, @"New Description");
    XCTAssertEqualObjects(inputItem.director, @"New Director");
    XCTAssertEqualObjects(inputItem.showName, @"New Show");
    XCTAssertEqualObjects(inputItem.actors, @"New Actor");
}

- (void)testDefaultValuesAndTitleFallback
{
    input_item_t * const coreItem = [self newFileInputItem];
    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    XCTAssertEqualObjects(inputItem.title, @"Original Name");
    XCTAssertEqualObjects(inputItem.options, @[]);
    XCTAssertEqualObjects(inputItem.extraMetaNames, @[]);
    XCTAssertEqualObjects([inputItem extraMetaForKey:@"missing"], @"");
    XCTAssertNil(inputItem.finderTags);
}

- (void)testCancelParsingWithoutParser
{
    input_item_t * const coreItem = [self newFileInputItem];
    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    XCTAssertNoThrow([inputItem cancelParsing]);
}

- (void)testParsingEndedPostsSuccessAndFailureNotifications
{
    input_item_t * const coreItem = [self newFileInputItem];
    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    NSMutableArray<NSString *> * const notificationNames = [NSMutableArray array];
    id const observer = [NSNotificationCenter.defaultCenter
        addObserverForName:nil
                    object:inputItem
                     queue:nil
                usingBlock:^(NSNotification * const notification) {
        [notificationNames addObject:notification.name];
    }];

    [inputItem parsingEnded:1];
    [inputItem parsingEnded:0];

    [NSNotificationCenter.defaultCenter removeObserver:observer];

    XCTAssertEqual(notificationNames.count, (NSUInteger)2);
    XCTAssertTrue([notificationNames[0] isEqualToString:VLCInputItemParsingSucceeded]);
    XCTAssertTrue([notificationNames[1] isEqualToString:VLCInputItemParsingFailed]);
}

- (void)testSubtreeReplacementPostsNotifications
{
    input_item_t * const coreItem = [self newFileInputItem];
    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    input_item_node_t * const firstSubtree = input_item_node_Create(inputItem.vlcInputItem);
    input_item_node_t * const secondSubtree = input_item_node_Create(inputItem.vlcInputItem);
    NSMutableArray<NSNotification *> * const notifications = [NSMutableArray array];
    id const observer = [NSNotificationCenter.defaultCenter
        addObserverForName:VLCInputItemSubtreeAdded
                    object:inputItem
                     queue:nil
                usingBlock:^(NSNotification * const notification) {
        [notifications addObject:notification];
    }];

    [inputItem subTreeAdded:firstSubtree];
    XCTAssertEqual(inputItem.subTree, firstSubtree);
    [inputItem subTreeAdded:secondSubtree];
    XCTAssertEqual(inputItem.subTree, secondSubtree);

    [NSNotificationCenter.defaultCenter removeObserver:observer];

    XCTAssertEqual(notifications.count, (NSUInteger)2);
    XCTAssertEqual(notifications[0].object, inputItem);
    XCTAssertEqual(notifications[1].object, inputItem);
}

- (void)testURLFactoryAndRadioCountryCode
{
    NSURL * const url = [NSURL URLWithString:@"file:///tmp/Example%20Video.mkv"];
    VLCInputItem * const inputItem = [VLCInputItem inputItemFromURL:url];

    XCTAssertNotNil(inputItem);
    XCTAssertEqualObjects(inputItem.MRL, @"file:///tmp/Example%20Video.mkv");
    XCTAssertEqualObjects(inputItem.name, @"Example Video");
    XCTAssertNil(inputItem.radioCountryCodeForFlagArtwork);

    VLCInputItem * const radioItem =
        [VLCInputItem inputItemFromURL:[NSURL URLWithString:@"radio://us/station"]];
    XCTAssertEqualObjects(radioItem.radioCountryCodeForFlagArtwork, @"US");

    VLCInputItem * const invalidRadioItem =
        [VLCInputItem inputItemFromURL:[NSURL URLWithString:@"radio://u1/station"]];
    XCTAssertNil(invalidRadioItem.radioCountryCodeForFlagArtwork);
}

- (void)testStreamAndArtworkState
{
    input_item_t * const coreItem = input_item_NewStream("https://example.com/live", 
                                                        "Live stream",
                                                        INPUT_DURATION_INDEFINITE);
    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    XCTAssertNotNil(inputItem);
    XCTAssertTrue(inputItem.isStream);
    XCTAssertEqual(inputItem.inputType, ITEM_TYPE_STREAM);
    XCTAssertEqualObjects(inputItem.decodedMRL, @"https://example.com/live");
    XCTAssertEqualObjects(inputItem.path, @"");
    XCTAssertEqualObjects(inputItem.options, @[]);
    XCTAssertNil(inputItem.finderTags);

    inputItem.artworkURL = [NSURL URLWithString:@"https://example.com/live.jpg"];
    XCTAssertEqualObjects(inputItem.artworkURL.absoluteString, @"https://example.com/live.jpg");

    [(id)inputItem setArtworkURL:nil];
    XCTAssertNil(inputItem.artworkURL);
}

- (void)testStreamThumbnailCompletesWithoutImage
{
    input_item_t * const coreItem = input_item_NewStream("https://example.com/live",
                                                        "Live stream",
                                                        INPUT_DURATION_INDEFINITE);
    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    XCTestExpectation * const completionExpectation =
        [self expectationWithDescription:@"stream thumbnail completion"];
    [inputItem thumbnailWithSize:NSMakeSize(128, 128)
                completionHandler:^(NSImage *image) {
        XCTAssertNil(image);
        [completionExpectation fulfill];
    }];
    [self waitForExpectations:@[completionExpectation] timeout:1.0];
}

- (void)testLocalThumbnailCompletes
{
    VLCInputItemTestResetAppKitState();

    NSString * const path = [NSTemporaryDirectory()
        stringByAppendingPathComponent:@"VLCInputItemThumbnailTest.txt"];
    NSData * const contents = [@"VLC thumbnail test" dataUsingEncoding:NSUTF8StringEncoding];
    XCTAssertTrue([contents writeToFile:path atomically:YES]);

    NSURL * const url = [NSURL fileURLWithPath:path];
    input_item_t * const coreItem = input_item_NewFile(url.absoluteString.UTF8String,
                                                       "Thumbnail Test",
                                                       INPUT_DURATION_UNSET,
                                                       ITEM_LOCAL);
    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    NSImage * const testImage = [[NSImage alloc] initWithSize:NSMakeSize(1, 1)];
    VLCInputItemTestSetWorkspaceImage(testImage);
    XCTestExpectation * const completionExpectation =
        [self expectationWithDescription:@"workspace thumbnail completion"];
    [inputItem thumbnailWithSize:NSMakeSize(128, 128)
                completionHandler:^(NSImage *image) {
        XCTAssertEqualObjects(image, testImage);
        [completionExpectation fulfill];
    }];
    [self waitForExpectations:@[completionExpectation] timeout:2.0];

    VLCInputItemTestSetWorkspaceImage(nil);
    VLCInputItemTestSetQuickLookImage(testImage);
    XCTestExpectation * const quickLookExpectation =
        [self expectationWithDescription:@"Quick Look thumbnail completion"];
    [inputItem thumbnailWithSize:NSMakeSize(128, 128)
                completionHandler:^(NSImage *image) {
        XCTAssertEqualObjects(image, testImage);
        [quickLookExpectation fulfill];
    }];
    [self waitForExpectations:@[quickLookExpectation] timeout:2.0];

    VLCInputItemTestSetQuickLookImage(nil);
    XCTestExpectation * const emptyExpectation =
        [self expectationWithDescription:@"empty thumbnail completion"];
    [inputItem thumbnailWithSize:NSMakeSize(128, 128)
                completionHandler:^(NSImage *image) {
        XCTAssertNil(image);
        [emptyExpectation fulfill];
    }];
    [self waitForExpectations:@[emptyExpectation] timeout:2.0];

    [NSFileManager.defaultManager removeItemAtPath:path error:nil];
    VLCInputItemTestResetAppKitState();
}

- (void)testLocalFileOperationsUseTheirApplicationServices
{
    VLCInputItemTestResetAppKitState();
    VLCInputItem * const inputItem =
        [VLCInputItem inputItemFromURL:[NSURL fileURLWithPath:@"/tmp/VLCInputItemTest.mkv"]];

    XCTAssertNotNil(inputItem);
    [inputItem moveToTrash];
    XCTAssertTrue(VLCInputItemTestDidReload());

    [inputItem revealInFinder];
    XCTAssertTrue(VLCInputItemTestDidReveal());

    VLCInputItemTestResetAppKitState();
}

- (void)testMissingURIShortCircuitsLocalOperations
{
    input_item_t * const coreItem = input_item_New(NULL, "No URI");
    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    XCTAssertNotNil(inputItem);
    XCTAssertEqualObjects(inputItem.path, @"");
    XCTAssertNil(inputItem.finderTags);

    XCTestExpectation * const completionExpectation =
        [self expectationWithDescription:@"missing URI thumbnail completion"];
    [inputItem thumbnailWithSize:NSMakeSize(128, 128)
                completionHandler:^(NSImage *image) {
        XCTAssertNil(image);
        [completionExpectation fulfill];
    }];
    [self waitForExpectations:@[completionExpectation] timeout:1.0];
}

- (void)testMalformedLocalURIProducesNoFinderTags
{
    input_item_t * const coreItem = input_item_NewFile("file://[",
                                                       "Malformed",
                                                       INPUT_DURATION_UNSET,
                                                       ITEM_LOCAL);
    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    XCTAssertNotNil(inputItem);
    XCTAssertEqualObjects(inputItem.path, @"");
    XCTAssertNil(inputItem.finderTags);

    XCTestExpectation * const completionExpectation =
        [self expectationWithDescription:@"malformed URI thumbnail completion"];
    [inputItem thumbnailWithSize:NSMakeSize(128, 128)
                completionHandler:^(NSImage *image) {
        XCTAssertNil(image);
        [completionExpectation fulfill];
    }];
    [self waitForExpectations:@[completionExpectation] timeout:1.0];
}

- (void)testWritingMetadataForStreamFailsWithoutTouchingTheFilesystem
{
    input_item_t * const coreItem = input_item_NewStream("https://example.com/live",
                                                         "Live stream",
                                                         INPUT_DURATION_INDEFINITE);
    VLCInputItem * const inputItem = [[VLCInputItem alloc] initWithInputItem:coreItem];
    input_item_Release(coreItem);

    XCTAssertNotEqual([inputItem writeMetadataToFile], VLC_SUCCESS);
}

- (void)testCommonInputItemData
{
    XCTAssertEqualObjects(commonInputItemData(@[]), @{});

    input_item_t * const firstCoreItem = [self newFileInputItem];
    VLCInputItem * const firstInputItem = [[VLCInputItem alloc] initWithInputItem:firstCoreItem];
    input_item_Release(firstCoreItem);

    XCTAssertEqualObjects(commonInputItemData(@[firstInputItem]),
                          (@{ @"inputItem": firstInputItem }));

    input_item_t * const secondCoreItem = [self newFileInputItem];
    VLCInputItem * const secondInputItem = [[VLCInputItem alloc] initWithInputItem:secondCoreItem];
    input_item_Release(secondCoreItem);

    NSDictionary<NSString *, id> *commonData =
        commonInputItemData(@[ firstInputItem, secondInputItem ]);
    XCTAssertEqualObjects(commonData[@"MRL"], firstInputItem.MRL);
    XCTAssertEqualObjects(commonData[@"title"], firstInputItem.title);
    XCTAssertEqualObjects(commonData[@"artist"], @"");
    XCTAssertEqualObjects(commonData[@"artworkURL"], @"");

    secondInputItem.artist = @"Different artist";
    secondInputItem.artworkURL = [NSURL URLWithString:@"https://example.com/art.jpg"];
    commonData = commonInputItemData(@[ firstInputItem, secondInputItem ]);
    XCTAssertEqualObjects(commonData[@"artist"], VLCInputItemCommonDataDifferingFlagString);
    XCTAssertEqualObjects(commonData[@"artworkURL"], VLCInputItemCommonDataDifferingFlagString);
}

- (void)testCommonInputItemDataMarksEveryDifferingStringProperty
{
    input_item_t * const firstCoreItem = [self newFileInputItem];
    VLCInputItem * const firstInputItem = [[VLCInputItem alloc] initWithInputItem:firstCoreItem];
    input_item_Release(firstCoreItem);

    input_item_t * const secondCoreItem = input_item_NewFile("file:///tmp/Other.mp4",
                                                             "Other Name",
                                                             VLC_TICK_FROM_SEC(123),
                                                             ITEM_LOCAL);
    input_item_SetTitle(secondCoreItem, "Other Title");
    input_item_SetArtist(secondCoreItem, "Other Artist");
    input_item_SetAlbum(secondCoreItem, "Other Album");
    input_item_SetTrackNumber(secondCoreItem, "9");
    input_item_SetTrackTotal(secondCoreItem, "11");
    input_item_SetGenre(secondCoreItem, "Other Genre");
    input_item_SetDate(secondCoreItem, "2027");
    input_item_SetEpisode(secondCoreItem, "4");
    input_item_SetActors(secondCoreItem, "Other Actor");
    input_item_SetDirector(secondCoreItem, "Other Director");
    input_item_SetShowName(secondCoreItem, "Other Show");
    input_item_SetCopyright(secondCoreItem, "Other Copyright");
    input_item_SetPublisher(secondCoreItem, "Other Publisher");
    input_item_SetNowPlaying(secondCoreItem, "Other Now Playing");
    input_item_SetLanguage(secondCoreItem, "de");
    input_item_SetDescription(secondCoreItem, "Other Description");
    input_item_SetEncodedBy(secondCoreItem, "Other Encoder");
    input_item_SetArtworkURL(secondCoreItem, "https://example.com/other-art.jpg");
    input_item_SetTrackID(secondCoreItem, "other-track-id");
    VLCInputItem * const secondInputItem = [[VLCInputItem alloc] initWithInputItem:secondCoreItem];
    input_item_Release(secondCoreItem);

    NSDictionary<NSString *, id> * const commonData =
        commonInputItemData(@[ firstInputItem, secondInputItem, secondInputItem ]);
    NSArray<NSString *> * const differingProperties = @[
        @"MRL", @"decodedMRL", @"title", @"artist", @"album", @"trackNumber",
        @"trackTotal", @"genre", @"date", @"episode", @"actors", @"director",
        @"showName", @"copyright", @"publisher", @"nowPlaying", @"language",
        @"contentDescription", @"encodedBy", @"artworkURL"
    ];
    for (NSString * const property in differingProperties) {
        XCTAssertEqualObjects(commonData[property], VLCInputItemCommonDataDifferingFlagString,
                              @"%@ should be marked as differing", property);
    }
}

- (void)testRejectsNilInputItem
{
    input_item_t * const nilInputItem = NULL;
    XCTAssertNil([[VLCInputItem alloc] initWithInputItem:nilInputItem]);
}

@end

#pragma clang diagnostic pop

[Dauer der Verarbeitung: 0.4 Sekunden, vorverarbeitet 2026-10-24]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104857
#Domains=418204