@@ -831,6 +831,134 @@ describe('OrgFile', function()
831
831
end )
832
832
end )
833
833
834
+ describe (' get_headlines_shallow' , function ()
835
+ it (' should get all headlines with correct structure' , function ()
836
+ local file = load_file_sync ({
837
+ ' * TODO Headline 1' ,
838
+ ' ** [#A] Priority Headline :tag1:tag2:' ,
839
+ ' *** DONE Archived Headline :ARCHIVE:' ,
840
+ ' * Plain Headline' ,
841
+ })
842
+
843
+ local headlines = file :get_headlines_shallow ()
844
+
845
+ assert .are .same (4 , # headlines )
846
+
847
+ -- Verify data structure
848
+ local headline = headlines [1 ]
849
+ assert .is .not_nil (headline .title )
850
+ assert .is .not_nil (headline .level )
851
+ assert .is .not_nil (headline .line_number )
852
+ assert .is .not_nil (headline .all_tags )
853
+ assert .is .not_nil (headline .is_archived )
854
+
855
+ -- Verify specific values
856
+ assert .are .same (' Headline 1' , headlines [1 ].title )
857
+ assert .are .same (1 , headlines [1 ].level )
858
+ assert .are .same (1 , headlines [1 ].line_number )
859
+ assert .are .same ({}, headlines [1 ].all_tags )
860
+ assert .is .False (headlines [1 ].is_archived )
861
+
862
+ assert .are .same (' Priority Headline' , headlines [2 ].title )
863
+ assert .are .same (2 , headlines [2 ].level )
864
+ assert .are .same ({ ' tag1' , ' tag2' }, headlines [2 ].all_tags )
865
+
866
+ assert .are .same (' Archived Headline' , headlines [3 ].title )
867
+ assert .are .same ({ ' ARCHIVE' }, headlines [3 ].all_tags )
868
+ assert .is .True (headlines [3 ].is_archived )
869
+ end )
870
+
871
+ it (' should return same count as get_headlines for regular files' , function ()
872
+ local file = load_file_sync ({
873
+ ' * TODO Headline 1' ,
874
+ ' * TODO Headline 2' ,
875
+ ' ** Headline 2.1' ,
876
+ ' *** Headline 2.1.1' ,
877
+ ' * DONE Headline 3' ,
878
+ })
879
+
880
+ local shallow = file :get_headlines_shallow ()
881
+ local heavy = file :get_headlines ()
882
+
883
+ assert .are .same (# heavy , # shallow )
884
+ end )
885
+
886
+ -- Parameterized archive tests
887
+ local archive_test_cases = {
888
+ {
889
+ name = ' regular file without archived option' ,
890
+ filename = nil , -- will use .org
891
+ opts = {},
892
+ content = { ' * Headline' , ' * Archived :ARCHIVE:' },
893
+ expected_count = 2 ,
894
+ },
895
+ {
896
+ name = ' archive file without archived option' ,
897
+ filename = ' test.org_archive' ,
898
+ opts = {},
899
+ content = { ' * Headline' , ' * Archived :ARCHIVE:' },
900
+ expected_count = 0 ,
901
+ },
902
+ {
903
+ name = ' archive file with archived=true' ,
904
+ filename = ' test.org_archive' ,
905
+ opts = { archived = true },
906
+ content = { ' * Headline' , ' * Archived :ARCHIVE:' },
907
+ expected_count = 2 ,
908
+ },
909
+ }
910
+
911
+ for _ , case in ipairs (archive_test_cases ) do
912
+ it (' should handle archives: ' .. case .name , function ()
913
+ local filename = case .filename and (vim .fn .tempname () .. case .filename ) or nil
914
+ local file = load_file_sync (case .content , filename )
915
+ local headlines = file :get_headlines_shallow (case .opts )
916
+ assert .are .same (case .expected_count , # headlines )
917
+ end )
918
+ end
919
+
920
+ it (' should respect max_depth filtering' , function ()
921
+ local file = load_file_sync ({
922
+ ' * Level 1' ,
923
+ ' ** Level 2' ,
924
+ ' *** Level 3' ,
925
+ ' **** Level 4' ,
926
+ })
927
+
928
+ local all_headlines = file :get_headlines_shallow ()
929
+ local depth_2 = file :get_headlines_shallow ({ max_depth = 2 })
930
+
931
+ assert .are .same (4 , # all_headlines )
932
+ assert .are .same (2 , # depth_2 )
933
+ end )
934
+
935
+ it (' should match get_headlines filtering behavior' , function ()
936
+ local content = {
937
+ ' * TODO Headline 1' ,
938
+ ' ** Headline 1.1' ,
939
+ ' *** TODO Headline 1.1.1 :ARCHIVE:' ,
940
+ ' **** Headline 1.1.1.1' ,
941
+ ' * DONE Headline 2' ,
942
+ }
943
+ local file = load_file_sync (content )
944
+
945
+ -- Compare filtering with different options
946
+ local shallow_all = file :get_headlines_shallow ()
947
+ local heavy_all = file :get_headlines ()
948
+ assert .are .same (# heavy_all , # shallow_all )
949
+
950
+ local shallow_archived = file :get_headlines_shallow ({ archived = true })
951
+ local heavy_archived = file :get_headlines_including_archived ()
952
+ assert .are .same (# heavy_archived , # shallow_archived )
953
+ end )
954
+
955
+ it (' should handle empty files gracefully' , function ()
956
+ local file = load_file_sync ({})
957
+ local headlines = file :get_headlines_shallow ()
958
+ assert .are .same (0 , # headlines )
959
+ end )
960
+ end )
961
+
834
962
describe (' get_todos' , function ()
835
963
local has_correct_type = function (todos )
836
964
assert .are .same (' TODO' , todos .todo_keywords [1 ].type )
0 commit comments