diff --git a/.gitignore b/.gitignore index f2a869e..182687a 100644 --- a/.gitignore +++ b/.gitignore @@ -208,3 +208,4 @@ __marimo__/ # Test results directory .test-results/ +.idea/ diff --git a/Dockerfile b/Dockerfile index 4cc6b71..843e9ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,10 +24,7 @@ WORKDIR /app COPY --from=builder /root/.local /home/testrunner/.local # Copy application code -COPY tests/ tests/ -COPY result_analyzer/ result_analyzer/ -COPY conftest.py . -COPY pytest.ini . +COPY documentdb_tests/ documentdb_tests/ COPY setup.py . # Create directory for test results and set ownership @@ -45,5 +42,5 @@ ENV PYTHONUNBUFFERED=1 # Default command: run all tests # Users can override with command line arguments -ENTRYPOINT ["pytest"] +ENTRYPOINT ["pytest", "--rootdir", "documentdb_tests"] CMD ["--help"] diff --git a/docs/feature-tree.csv b/docs/feature-tree.csv new file mode 100644 index 0000000..19e5b47 --- /dev/null +++ b/docs/feature-tree.csv @@ -0,0 +1,470 @@ +core,-,-,-,-,collation +core,aggregation,commands,-,-,aggregate +core,aggregation,commands,-,-,count +core,aggregation,commands,-,-,distinct +core,aggregation,commands,-,-,mapReduce +core,collections,-,-,-,capped_collections +core,collections,-,-,-,clustered-collections +core,collections,-,-,-,materialized-views +core,collections,-,-,-,timeseries +core,collections,-,-,-,views +core,collections,commands,-,-,cloneCollectionAsCapped +core,collections,commands,-,-,collMod +core,collections,commands,-,-,compact +core,collections,commands,-,-,convertToCapped +core,collections,commands,-,-,create +core,collections,commands,-,-,drop +core,collections,commands,-,-,dropDatabase +core,collections,commands,-,-,listCollections +core,collections,commands,-,-,listDatabases +core,collections,commands,-,-,renameCollection +core,collections,commands,-,-,validateDBMetadata +core,cursors,-,-,-,tailable-cursors +core,cursors,commands,-,-,getMore +core,cursors,commands,-,-,killCursors +core,data-types,-,-,-,bson-types +core,data-types,-,-,-,mongodb-extended-json +core,indexes,commands,-,-,createIndexes +core,indexes,commands,-,-,dropIndexes +core,indexes,commands,-,-,listIndexes +core,indexes,commands,-,-,reIndex +core,indexes,properties,-,-,case-insensitive +core,indexes,properties,-,-,hidden +core,indexes,properties,-,-,partial +core,indexes,properties,-,-,sparse +core,indexes,properties,-,-,ttl +core,indexes,properties,-,-,unique +core,indexes,types,-,-,compound +core,indexes,types,-,-,geospatial +core,indexes,types,-,-,hashed +core,indexes,types,-,-,multikey +core,indexes,types,-,-,single +core,indexes,types,-,-,text +core,indexes,types,-,-,wildcard +core,operator,accumulators,-,-,addToSet +core,operator,accumulators,-,-,avg +core,operator,accumulators,-,-,bottom +core,operator,accumulators,-,-,bottomN +core,operator,accumulators,-,-,concatArrays +core,operator,accumulators,-,-,count +core,operator,accumulators,-,-,first +core,operator,accumulators,-,-,firstN +core,operator,accumulators,-,-,last +core,operator,accumulators,-,-,lastN +core,operator,accumulators,-,-,max +core,operator,accumulators,-,-,maxN +core,operator,accumulators,-,-,median +core,operator,accumulators,-,-,mergeObjects +core,operator,accumulators,-,-,min +core,operator,accumulators,-,-,minN +core,operator,accumulators,-,-,percentile +core,operator,accumulators,-,-,push +core,operator,accumulators,-,-,setUnion +core,operator,accumulators,-,-,stdDevPop +core,operator,accumulators,-,-,stdDevSamp +core,operator,accumulators,-,-,sum +core,operator,accumulators,-,-,top +core,operator,accumulators,-,-,topN +core,operator,expressions,-,-,literal +core,operator,expressions,-,-,text +core,operator,expressions,accumulator,-,avg +core,operator,expressions,accumulator,-,first +core,operator,expressions,accumulator,-,last +core,operator,expressions,accumulator,-,max +core,operator,expressions,accumulator,-,median +core,operator,expressions,accumulator,-,min +core,operator,expressions,accumulator,-,percentile +core,operator,expressions,accumulator,-,setUnion +core,operator,expressions,accumulator,-,stdDevPop +core,operator,expressions,accumulator,-,stdDevSamp +core,operator,expressions,accumulator,-,sum +core,operator,expressions,arithmetic,-,abs +core,operator,expressions,arithmetic,-,add +core,operator,expressions,arithmetic,-,ceil +core,operator,expressions,arithmetic,-,divide +core,operator,expressions,arithmetic,-,exp +core,operator,expressions,arithmetic,-,floor +core,operator,expressions,arithmetic,-,ln +core,operator,expressions,arithmetic,-,log +core,operator,expressions,arithmetic,-,log10 +core,operator,expressions,arithmetic,-,mod +core,operator,expressions,arithmetic,-,multiply +core,operator,expressions,arithmetic,-,pow +core,operator,expressions,arithmetic,-,round +core,operator,expressions,arithmetic,-,sigmoid +core,operator,expressions,arithmetic,-,sqrt +core,operator,expressions,arithmetic,-,subtract +core,operator,expressions,arithmetic,-,trunc +core,operator,expressions,array,-,arrayElemAt +core,operator,expressions,array,-,arrayToObject +core,operator,expressions,array,-,concatArrays +core,operator,expressions,array,-,filter +core,operator,expressions,array,-,firstN +core,operator,expressions,array,-,in +core,operator,expressions,array,-,indexOfArray +core,operator,expressions,array,-,isArray +core,operator,expressions,array,-,lastN +core,operator,expressions,array,-,map +core,operator,expressions,array,-,maxN-array-element +core,operator,expressions,array,-,minN-array-element +core,operator,expressions,array,-,objectToArray +core,operator,expressions,array,-,range +core,operator,expressions,array,-,reduce +core,operator,expressions,array,-,reverseArray +core,operator,expressions,array,-,size +core,operator,expressions,array,-,slice +core,operator,expressions,array,-,sortArray +core,operator,expressions,array,-,zip +core,operator,expressions,bitwise,-,bitAnd +core,operator,expressions,bitwise,-,bitNot +core,operator,expressions,bitwise,-,bitOr +core,operator,expressions,bitwise,-,bitXor +core,operator,expressions,boolean,-,and +core,operator,expressions,boolean,-,not +core,operator,expressions,boolean,-,or +core,operator,expressions,comparisons,-,cmp +core,operator,expressions,comparisons,-,eq +core,operator,expressions,comparisons,-,gt +core,operator,expressions,comparisons,-,gte +core,operator,expressions,comparisons,-,lt +core,operator,expressions,comparisons,-,lte +core,operator,expressions,comparisons,-,ne +core,operator,expressions,conditional,-,cond +core,operator,expressions,conditional,-,ifNull +core,operator,expressions,conditional,-,switch +core,operator,expressions,custom,-,function +core,operator,expressions,custom,-,operator_accumulator +core,operator,expressions,date,-,dateAdd +core,operator,expressions,date,-,dateDiff +core,operator,expressions,date,-,dateFromParts +core,operator,expressions,date,-,dateFromString +core,operator,expressions,date,-,dateSubtract +core,operator,expressions,date,-,dateToParts +core,operator,expressions,date,-,dateToString +core,operator,expressions,date,-,dateTrunc +core,operator,expressions,date,-,dayOfMonth +core,operator,expressions,date,-,dayOfWeek +core,operator,expressions,date,-,dayOfYear +core,operator,expressions,date,-,hour +core,operator,expressions,date,-,isoDayOfWeek +core,operator,expressions,date,-,isoWeek +core,operator,expressions,date,-,isoWeekYear +core,operator,expressions,date,-,millisecond +core,operator,expressions,date,-,minute +core,operator,expressions,date,-,month +core,operator,expressions,date,-,second +core,operator,expressions,date,-,toDate +core,operator,expressions,date,-,week +core,operator,expressions,date,-,year +core,operator,expressions,misc,-,binarySize +core,operator,expressions,misc,-,bsonSize +core,operator,expressions,misc,-,getField +core,operator,expressions,misc,-,rand +core,operator,expressions,misc,-,sampleRate +core,operator,expressions,misc,-,toHashedIndexKey +core,operator,expressions,object,-,mergeObjects +core,operator,expressions,object,-,setField +core,operator,expressions,object,-,unsetField +core,operator,expressions,set,-,allElementsTrue +core,operator,expressions,set,-,anyElementTrue +core,operator,expressions,set,-,setDifference +core,operator,expressions,set,-,setEquals +core,operator,expressions,set,-,setIntersection +core,operator,expressions,set,-,setIsSubset +core,operator,expressions,string,-,concat +core,operator,expressions,string,-,indexOfBytes +core,operator,expressions,string,-,indexOfCP +core,operator,expressions,string,-,ltrim +core,operator,expressions,string,-,regexFind +core,operator,expressions,string,-,regexFindAll +core,operator,expressions,string,-,regexMatch +core,operator,expressions,string,-,replaceAll +core,operator,expressions,string,-,replaceOne +core,operator,expressions,string,-,rtrim +core,operator,expressions,string,-,split +core,operator,expressions,string,-,strcasecmp +core,operator,expressions,string,-,strLenBytes +core,operator,expressions,string,-,strLenCP +core,operator,expressions,string,-,substr +core,operator,expressions,string,-,substrBytes +core,operator,expressions,string,-,substrCP +core,operator,expressions,string,-,toLower +core,operator,expressions,string,-,toString +core,operator,expressions,string,-,toUpper +core,operator,expressions,string,-,trim +core,operator,expressions,timestamp,-,tsIncrement +core,operator,expressions,timestamp,-,tsSecond +core,operator,expressions,trigonometry,-,acos +core,operator,expressions,trigonometry,-,acosh +core,operator,expressions,trigonometry,-,asin +core,operator,expressions,trigonometry,-,asinh +core,operator,expressions,trigonometry,-,atan +core,operator,expressions,trigonometry,-,atan2 +core,operator,expressions,trigonometry,-,atanh +core,operator,expressions,trigonometry,-,cos +core,operator,expressions,trigonometry,-,cosh +core,operator,expressions,trigonometry,-,degreesToRadians +core,operator,expressions,trigonometry,-,radiansToDegrees +core,operator,expressions,trigonometry,-,sin +core,operator,expressions,trigonometry,-,sinh +core,operator,expressions,trigonometry,-,tan +core,operator,expressions,trigonometry,-,tanh +core,operator,expressions,type,-,convert +core,operator,expressions,type,-,isNumber +core,operator,expressions,type,-,toBool +core,operator,expressions,type,-,toDecimal +core,operator,expressions,type,-,toDouble +core,operator,expressions,type,-,toInt +core,operator,expressions,type,-,toLong +core,operator,expressions,type,-,toObjectId +core,operator,expressions,type,-,toUUID +core,operator,expressions,type,-,type +core,operator,expressions,variable,-,let +core,operator,projection,-,-,elemMatch +core,operator,projection,-,-,positional +core,operator,projection,-,-,slice +core,operator,query,-,-,text +core,operator,query,arrays,-,all +core,operator,query,arrays,-,elemMatch +core,operator,query,arrays,-,size +core,operator,query,bitwise,-,bitsAllClear +core,operator,query,bitwise,-,bitsAllSet +core,operator,query,bitwise,-,bitsAnyClear +core,operator,query,bitwise,-,bitsAnySet +core,operator,query,comparison,-,eq +core,operator,query,comparison,-,gt +core,operator,query,comparison,-,gte +core,operator,query,comparison,-,in +core,operator,query,comparison,-,lt +core,operator,query,comparison,-,lte +core,operator,query,comparison,-,ne +core,operator,query,comparison,-,nin +core,operator,query,geospatial,-,geoIntersects +core,operator,query,geospatial,-,geoWithin +core,operator,query,geospatial,-,near +core,operator,query,geospatial,-,nearSphere +core,operator,query,geospatial,specifiers,box +core,operator,query,geospatial,specifiers,center +core,operator,query,geospatial,specifiers,centerSphere +core,operator,query,geospatial,specifiers,geometry +core,operator,query,geospatial,specifiers,maxDistance +core,operator,query,geospatial,specifiers,minDistance +core,operator,query,geospatial,specifiers,polygon +core,operator,query,logical,-,and +core,operator,query,logical,-,nor +core,operator,query,logical,-,not +core,operator,query,logical,-,or +core,operator,query,misc,-,exists +core,operator,query,misc,-,expr +core,operator,query,misc,-,jsonSchema +core,operator,query,misc,-,mod +core,operator,query,misc,-,regex +core,operator,query,misc,-,type +core,operator,query,misc,-,where +core,operator,stages,-,-,addFields +core,operator,stages,-,-,bucket +core,operator,stages,-,-,bucketAuto +core,operator,stages,-,-,changeStreamSplitLargeEvent +core,operator,stages,-,-,collStats +core,operator,stages,-,-,count +core,operator,stages,-,-,densify +core,operator,stages,-,-,facet +core,operator,stages,-,-,fill +core,operator,stages,-,-,geoNear +core,operator,stages,-,-,graphLookup +core,operator,stages,-,-,group +core,operator,stages,-,-,indexStats +core,operator,stages,-,-,limit +core,operator,stages,-,-,listClusterCatalog +core,operator,stages,-,-,listSampledQueries +core,operator,stages,-,-,listSearchIndexes +core,operator,stages,-,-,listSessions +core,operator,stages,-,-,lookup +core,operator,stages,-,-,match +core,operator,stages,-,-,merge +core,operator,stages,-,-,out +core,operator,stages,-,-,planCacheStats +core,operator,stages,-,-,project +core,operator,stages,-,-,querySettings +core,operator,stages,-,-,queryStats +core,operator,stages,-,-,rankFusion +core,operator,stages,-,-,redact +core,operator,stages,-,-,replaceRoot +core,operator,stages,-,-,replaceWith +core,operator,stages,-,-,sample +core,operator,stages,-,-,search +core,operator,stages,-,-,searchMeta +core,operator,stages,-,-,set +core,operator,stages,-,-,setWindowFields +core,operator,stages,-,-,skip +core,operator,stages,-,-,sort +core,operator,stages,-,-,sortByCount +core,operator,stages,-,-,unionWith +core,operator,stages,-,-,unset +core,operator,stages,-,-,unwind +core,operator,stages,-,-,vectorSearch +core,operator,system-stages,-,-,changeStream +core,operator,system-stages,-,-,currentOp +core,operator,system-stages,-,-,documents +core,operator,system-stages,-,-,listLocalSessions +core,operator,update,array,-,addToSet +core,operator,update,array,-,pop +core,operator,update,array,-,positional +core,operator,update,array,-,positional-all +core,operator,update,array,-,positional-filtered +core,operator,update,array,-,pull +core,operator,update,array,-,pullAll +core,operator,update,array,-,push +core,operator,update,bitwise,-,bit +core,operator,update,fields,-,currentDate +core,operator,update,fields,-,inc +core,operator,update,fields,-,max +core,operator,update,fields,-,min +core,operator,update,fields,-,mul +core,operator,update,fields,-,rename +core,operator,update,fields,-,set +core,operator,update,fields,-,setOnInsert +core,operator,update,fields,-,unset +core,operator,update,modifiers,-,each +core,operator,update,modifiers,-,position +core,operator,update,modifiers,-,slice +core,operator,update,modifiers,-,sort +core,operator,window,-,-,addToSet +core,operator,window,-,-,avg +core,operator,window,-,-,bottom +core,operator,window,-,-,bottomN +core,operator,window,-,-,count +core,operator,window,-,-,covariancePop +core,operator,window,-,-,covarianceSamp +core,operator,window,-,-,denseRank +core,operator,window,-,-,derivative +core,operator,window,-,-,documentNumber +core,operator,window,-,-,expMovingAvg +core,operator,window,-,-,first +core,operator,window,-,-,integral +core,operator,window,-,-,last +core,operator,window,-,-,linearFill +core,operator,window,-,-,locf +core,operator,window,-,-,max +core,operator,window,-,-,maxN +core,operator,window,-,-,min +core,operator,window,-,-,minN +core,operator,window,-,-,push +core,operator,window,-,-,rank +core,operator,window,-,-,shift +core,operator,window,-,-,stdDevPop +core,operator,window,-,-,stdDevSamp +core,operator,window,-,-,sum +core,operator,window,-,-,top +core,operator,window,-,-,topN +core,query-and-write,-,-,-,read-concern +core,query-and-write,-,-,-,write-concern +core,query-and-write,commands,-,-,bulkWrite +core,query-and-write,commands,-,-,delete +core,query-and-write,commands,-,-,find +core,query-and-write,commands,-,-,findAndModify +core,query-and-write,commands,-,-,insert +core,query-and-write,commands,-,-,update +core,query-planning,commands,-,-,planCacheClear +core,query-planning,commands,-,-,planCacheClearFilters +core,query-planning,commands,-,-,planCacheListFilters +core,query-planning,commands,-,-,planCacheSetFilter +core,query-planning,commands,-,-,removeQuerySettings +core,query-planning,commands,-,-,setQuerySettings +core,sessions,commands,-,-,abortTransaction +core,sessions,commands,-,-,commitTransaction +core,sessions,commands,-,-,endSessions +core,sessions,commands,-,-,killAllSessions +core,sessions,commands,-,-,killAllSessionsByPattern +core,sessions,commands,-,-,killSessions +core,sessions,commands,-,-,refreshSessions +core,sessions,commands,-,-,startSession +system,administration,commands,-,-,autoCompact +system,administration,commands,-,-,compactStructuredEncryptionData +system,administration,commands,-,-,currentOp +system,administration,commands,-,-,dropConnections +system,administration,commands,-,-,filemd5 +system,administration,commands,-,-,fsync +system,administration,commands,-,-,fsyncUnlock +system,administration,commands,-,-,getClusterParameter +system,administration,commands,-,-,getDefaultRWConcern +system,administration,commands,-,-,getParameter +system,administration,commands,-,-,killOp +system,administration,commands,-,-,logRotate +system,administration,commands,-,-,rotateCertificates +system,administration,commands,-,-,setClusterParameter +system,administration,commands,-,-,setDefaultRWConcern +system,administration,commands,-,-,setFeatureCompatibilityVersion +system,administration,commands,-,-,setIndexCommitQuorum +system,administration,commands,-,-,setParameter +system,administration,commands,-,-,setUserWriteBlockMode +system,administration,commands,-,-,shutdown +system,changeStreams,-,-,-,create +system,changeStreams,-,-,-,createIndexes +system,changeStreams,-,-,-,delete +system,changeStreams,-,-,-,drop +system,changeStreams,-,-,-,dropDatabase +system,changeStreams,-,-,-,dropIndexes +system,changeStreams,-,-,-,insert +system,changeStreams,-,-,-,invalidate +system,changeStreams,-,-,-,modify +system,changeStreams,-,-,-,refineCollectionShardKey +system,changeStreams,-,-,-,rename +system,changeStreams,-,-,-,replace +system,changeStreams,-,-,-,reshardCollection +system,changeStreams,-,-,-,shardCollection +system,changeStreams,-,-,-,update +system,diagnostic,commands,-,-,buildInfo +system,diagnostic,commands,-,-,collStats +system,diagnostic,commands,-,-,connectionStatus +system,diagnostic,commands,-,-,connPoolStats +system,diagnostic,commands,-,-,dataSize +system,diagnostic,commands,-,-,dbHash +system,diagnostic,commands,-,-,dbStats +system,diagnostic,commands,-,-,explain +system,diagnostic,commands,-,-,getCmdLineOpts +system,diagnostic,commands,-,-,getLog +system,diagnostic,commands,-,-,hostInfo +system,diagnostic,commands,-,-,listCommands +system,diagnostic,commands,-,-,lockInfo +system,diagnostic,commands,-,-,ping +system,diagnostic,commands,-,-,profile +system,diagnostic,commands,-,-,serverStatus +system,diagnostic,commands,-,-,top +system,diagnostic,commands,-,-,validate +system,diagnostic,commands,-,-,whatsmyuri +system,replication,commands,-,-,appendOplogNote +system,replication,commands,-,-,applyOps +system,replication,commands,-,-,hello +system,replication,commands,-,-,replSetAbortPrimaryCatchUp +system,replication,commands,-,-,replSetFreeze +system,replication,commands,-,-,replSetGetConfig +system,replication,commands,-,-,replSetGetStatus +system,replication,commands,-,-,replSetInitiate +system,replication,commands,-,-,replSetMaintenance +system,replication,commands,-,-,replSetReconfig +system,replication,commands,-,-,replSetResizeOplog +system,replication,commands,-,-,replSetStepDown +system,replication,commands,-,-,replSetSyncFrom +system,security,-,-,-,encryption +system,security,auditing,commands,-,logApplicationMessage +system,security,authentication,commands,-,authenticate +system,security,authentication,commands,-,logout +system,security,authorization,role,commands,createRole +system,security,authorization,role,commands,dropAllRolesFromDatabase +system,security,authorization,role,commands,dropRole +system,security,authorization,role,commands,grantPrivilegesToRole +system,security,authorization,role,commands,grantRolesToRole +system,security,authorization,role,commands,invalidateUserCache +system,security,authorization,role,commands,revokePrivilegesFromRole +system,security,authorization,role,commands,revokeRolesFromRole +system,security,authorization,role,commands,rolesInfo +system,security,authorization,role,commands,updateRole +system,security,authorization,user,commands,createUser +system,security,authorization,user,commands,dropAllUsersFromDatabase +system,security,authorization,user,commands,dropUser +system,security,authorization,user,commands,grantRolesToUser +system,security,authorization,user,commands,revokeRolesFromUser +system,security,authorization,user,commands,updateUser +system,security,authorization,user,commands,usersInfo + diff --git a/docs/testing/FOLDER_STRUCTURE.md b/docs/testing/FOLDER_STRUCTURE.md new file mode 100644 index 0000000..5d4561f --- /dev/null +++ b/docs/testing/FOLDER_STRUCTURE.md @@ -0,0 +1,70 @@ +# Folder Structure Guide + +## Core Principles + +1. **Feature-specific tests** → dedicated subfolders. Test only the feature's own inputs and edge cases, not lower-level features it contains (those are tested in their own directories). +2. **Cross-cutting features** (rbac, transactions, collation, etc.) → own top-level folders, NOT under feature-specific folders (e.g., rbac with find goes under `/tests/rbac/`, not `/tests/find/`). +3. **Feature levels** — higher-level features (e.g., `find`, `$group`, `$lookup`) contain lower-level features (e.g., `projection`, `$sum`, `$unwind`). Higher-level tests only verify lower-level features are supported (1-2 cases) and test combinations of lower-level features. Lower-level features test their own edge cases in their own directories. +4. **Integration tests** (multiple same-level features interacting) → parent folders. Example: `{$add: [{$subtract: [2, 1]}, 3]}` tests multiple operators working together (operator combination/nesting), not a single operator's edge cases — goes in `expressions/test_expression_combination.py`, not `expressions/arithmetic/add/`. Single operator edge cases (null handling, type errors, boundary values) stay in the operator's own folder. +5. **Operators** → comprehensive tests in `/tests/operators/{type}/$operator/`, only 1-2 integration cases elsewhere. + +6. **File organization** — a feature folder can have multiple files if a single file would exceed ~200 lines. Group test cases logically by aspect (e.g., by parameter, by error type). Example: +``` +/tests/aggregate/unwind/ +├── test_unwind_path.py # path parameter +├── test_unwind_preserve_null_and_empty_arrays.py # preserveNullAndEmptyArrays option +└── test_unwind_combined_options.py # multiple options together +``` + +## Decision Tree + +**Step 1: Cross-cutting feature?** (rbac, transactions, collation, geospatial, text_search, validation, ttl) +→ YES: `/tests/{feature}/` + +**Step 2: Operator?** ($in, $gt, $sum, $add, etc.) +→ YES comprehensive: `/tests/operators/{type}/$operator/` +→ YES integration: 1-2 cases in the higher-level feature that uses it (e.g., `$sum` in `$group/`, `$add` in `$project/`, `$gt` in `$match/`+`$expr/`) + +**Step 3: Single parameter/option of a feature?** +→ YES: feature subfolder (e.g., `/tests/aggregate/unwind/`) + +**Container features** ($expr, $match, $lookup): under the container's directory, only test that sub-features work inside it — one test case per sub-feature, no edge cases. Edge cases belong in each sub-feature's own directory. +- `$expr/` → one test per operator usable inside $expr +- `$lookup/` → 1-2 cases per pipeline sub-stage + +**Step 4: Interaction between multiple same-level features?** +→ YES: parent folder (e.g., `{$add: [{$subtract: ...}]}` tests expression nesting, not `$add` itself — goes in `expressions/`, not `add/`) + + +**Step 5: Basic operation behavior?** +→ operation folder (e.g., `/tests/find/test_basic_queries.py`) + +## Anti-patterns + +- ❌ Cross-cutting tests in operation folders +- ❌ Comprehensive operator tests outside `/operators/` +- ❌ Integration tests in feature subfolders (they belong in parent) +- ❌ 200+ test functions in one file (split by feature) + + +## Feature Tree + +The test directory structure maps to the DocumentDB feature taxonomy defined in [`docs/feature-tree.csv`](../feature-tree.csv). + +Each row in the CSV represents a feature path: +``` +Category,Subcategory1,Subcategory2,Subcategory3,Subcategory4,Item +``` + +Example mappings: +| Feature | CSV Path | Test Directory | +|---------|----------|----------------| +| `$group` stage | `core,operator,aggregation,pipeline,-,group` | `tests/core/operator/stages/group/` | +| `$sum` accumulator | `core,operator,aggregation,accumulators,-,sum` | `tests/core/operator/accumulators/sum/` | +| `$mul` update | `core,operator,update,fields,-,mul` | `tests/core/operator/update/fields/mul/` | +| `find` command | `core,crud,commands,-,-,find` | `tests/find/` | + +Use the feature tree to: +- Determine where a new test file should go +- Find related tests by feature hierarchy +- Ensure complete coverage across feature areas diff --git a/documentdb_tests/__init__.py b/documentdb_tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/documentdb_tests/compatibility/__init__.py b/documentdb_tests/compatibility/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/result_analyzer/README.md b/documentdb_tests/compatibility/result_analyzer/README.md similarity index 100% rename from result_analyzer/README.md rename to documentdb_tests/compatibility/result_analyzer/README.md diff --git a/result_analyzer/__init__.py b/documentdb_tests/compatibility/result_analyzer/__init__.py similarity index 100% rename from result_analyzer/__init__.py rename to documentdb_tests/compatibility/result_analyzer/__init__.py diff --git a/result_analyzer/analyzer.py b/documentdb_tests/compatibility/result_analyzer/analyzer.py similarity index 100% rename from result_analyzer/analyzer.py rename to documentdb_tests/compatibility/result_analyzer/analyzer.py diff --git a/result_analyzer/cli.py b/documentdb_tests/compatibility/result_analyzer/cli.py similarity index 100% rename from result_analyzer/cli.py rename to documentdb_tests/compatibility/result_analyzer/cli.py diff --git a/result_analyzer/report_generator.py b/documentdb_tests/compatibility/result_analyzer/report_generator.py similarity index 100% rename from result_analyzer/report_generator.py rename to documentdb_tests/compatibility/result_analyzer/report_generator.py diff --git a/tests/__init__.py b/documentdb_tests/compatibility/tests/__init__.py similarity index 90% rename from tests/__init__.py rename to documentdb_tests/compatibility/tests/__init__.py index e23aa21..91b3213 100644 --- a/tests/__init__.py +++ b/documentdb_tests/compatibility/tests/__init__.py @@ -7,7 +7,7 @@ DocumentDB functionality. """ -from framework.assertions import ( +from documentdb_tests.framework.assertions import ( assert_count, assert_document_match, assert_documents_match, diff --git a/tests/collection/test_capped_collections.py b/documentdb_tests/compatibility/tests/core/collections/capped_collections/test_capped_collections.py similarity index 100% rename from tests/collection/test_capped_collections.py rename to documentdb_tests/compatibility/tests/core/collections/capped_collections/test_capped_collections.py diff --git a/tests/aggregate/test_group_stage.py b/documentdb_tests/compatibility/tests/core/operator/stages/group/test_group_stage.py similarity index 100% rename from tests/aggregate/test_group_stage.py rename to documentdb_tests/compatibility/tests/core/operator/stages/group/test_group_stage.py diff --git a/tests/aggregate/test_match_stage.py b/documentdb_tests/compatibility/tests/core/operator/stages/match/test_match_stage.py similarity index 100% rename from tests/aggregate/test_match_stage.py rename to documentdb_tests/compatibility/tests/core/operator/stages/match/test_match_stage.py diff --git a/tests/find/test_basic_queries.py b/documentdb_tests/compatibility/tests/core/query-and-write/commands/find/test_basic_queries.py similarity index 98% rename from tests/find/test_basic_queries.py rename to documentdb_tests/compatibility/tests/core/query-and-write/commands/find/test_basic_queries.py index 748bc65..ba40c61 100644 --- a/tests/find/test_basic_queries.py +++ b/documentdb_tests/compatibility/tests/core/query-and-write/commands/find/test_basic_queries.py @@ -6,7 +6,7 @@ import pytest -from framework.assertions import assert_document_match +from documentdb_tests.framework.assertions import assert_document_match @pytest.mark.find diff --git a/tests/find/test_projections.py b/documentdb_tests/compatibility/tests/core/query-and-write/commands/find/test_projections.py similarity index 97% rename from tests/find/test_projections.py rename to documentdb_tests/compatibility/tests/core/query-and-write/commands/find/test_projections.py index 47d605a..6853e67 100644 --- a/tests/find/test_projections.py +++ b/documentdb_tests/compatibility/tests/core/query-and-write/commands/find/test_projections.py @@ -6,7 +6,7 @@ import pytest -from framework.assertions import assert_field_exists, assert_field_not_exists +from documentdb_tests.framework.assertions import assert_field_exists, assert_field_not_exists @pytest.mark.find diff --git a/tests/find/test_query_operators.py b/documentdb_tests/compatibility/tests/core/query-and-write/commands/find/test_query_operators.py similarity index 100% rename from tests/find/test_query_operators.py rename to documentdb_tests/compatibility/tests/core/query-and-write/commands/find/test_query_operators.py diff --git a/tests/insert/test_insert_operations.py b/documentdb_tests/compatibility/tests/core/query-and-write/commands/insert/test_insert_operations.py similarity index 98% rename from tests/insert/test_insert_operations.py rename to documentdb_tests/compatibility/tests/core/query-and-write/commands/insert/test_insert_operations.py index 3ff30ae..21cdd31 100644 --- a/tests/insert/test_insert_operations.py +++ b/documentdb_tests/compatibility/tests/core/query-and-write/commands/insert/test_insert_operations.py @@ -8,7 +8,7 @@ from bson import ObjectId from pymongo.errors import DuplicateKeyError -from framework.assertions import assert_count +from documentdb_tests.framework.assertions import assert_count @pytest.mark.insert diff --git a/conftest.py b/documentdb_tests/conftest.py similarity index 98% rename from conftest.py rename to documentdb_tests/conftest.py index a978a8e..131b582 100644 --- a/conftest.py +++ b/documentdb_tests/conftest.py @@ -8,7 +8,7 @@ """ import pytest -from framework import fixtures +from documentdb_tests.framework import fixtures def pytest_addoption(parser): diff --git a/framework/__init__.py b/documentdb_tests/framework/__init__.py similarity index 100% rename from framework/__init__.py rename to documentdb_tests/framework/__init__.py diff --git a/framework/assertions.py b/documentdb_tests/framework/assertions.py similarity index 100% rename from framework/assertions.py rename to documentdb_tests/framework/assertions.py diff --git a/framework/fixtures.py b/documentdb_tests/framework/fixtures.py similarity index 100% rename from framework/fixtures.py rename to documentdb_tests/framework/fixtures.py diff --git a/pytest.ini b/documentdb_tests/pytest.ini similarity index 97% rename from pytest.ini rename to documentdb_tests/pytest.ini index 02af8cd..24af4e2 100644 --- a/pytest.ini +++ b/documentdb_tests/pytest.ini @@ -1,6 +1,6 @@ [pytest] # Test discovery -testpaths = tests +testpaths = compatibility/tests python_files = test_*.py python_classes = Test* python_functions = test_* diff --git a/setup.py b/setup.py index dc24d5e..5d3f453 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ def parse_requirements(filename): install_requires=parse_requirements("requirements.txt"), entry_points={ "console_scripts": [ - "docdb-analyze=result_analyzer.cli:main", + "docdb-analyze=documentdb_tests.compatibility.result_analyzer.cli:main", ], }, ) diff --git a/tests/aggregate/__init__.py b/tests/aggregate/__init__.py deleted file mode 100644 index 1103a4a..0000000 --- a/tests/aggregate/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Aggregation pipeline tests.""" diff --git a/tests/collection/__init__.py b/tests/collection/__init__.py deleted file mode 100644 index b73cf50..0000000 --- a/tests/collection/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Collection management tests.""" diff --git a/tests/find/__init__.py b/tests/find/__init__.py deleted file mode 100644 index 0bdc7e7..0000000 --- a/tests/find/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Find operation tests.""" diff --git a/tests/insert/__init__.py b/tests/insert/__init__.py deleted file mode 100644 index 47ae134..0000000 --- a/tests/insert/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Insert operation tests."""