@@ -946,3 +946,108 @@ describe('LATEX ROUND-TRIP COMPOUND UNITS', () => {
946946 expect ( parsed . latex ) . toBe ( original ) ;
947947 } ) ;
948948} ) ;
949+
950+ describe ( 'UNIT CANCELLATION' , ( ) => {
951+ test ( 'Same unit division gives scalar' , ( ) => {
952+ const expr = engine
953+ . box ( [ 'Divide' , [ 'Quantity' , 10 , 'm' ] , [ 'Quantity' , 2 , 'm' ] ] )
954+ . evaluate ( ) ;
955+ expect ( expr . re ) . toBe ( 5 ) ;
956+ expect ( expr . operator ) . not . toBe ( 'Quantity' ) ;
957+ } ) ;
958+
959+ test ( 'Compatible unit division gives scalar with scale' , ( ) => {
960+ const expr = engine
961+ . box ( [ 'Divide' , [ 'Quantity' , 1 , 'km' ] , [ 'Quantity' , 500 , 'm' ] ] )
962+ . evaluate ( ) ;
963+ expect ( expr . re ) . toBe ( 2 ) ;
964+ } ) ;
965+
966+ test ( 'Different dimension division gives compound unit' , ( ) => {
967+ const expr = engine
968+ . box ( [ 'Divide' , [ 'Quantity' , 100 , 'm' ] , [ 'Quantity' , 10 , 's' ] ] )
969+ . evaluate ( ) ;
970+ expect ( expr . operator ) . toBe ( 'Quantity' ) ;
971+ expect ( expr . op1 . re ) . toBe ( 10 ) ;
972+ } ) ;
973+ } ) ;
974+
975+ describe ( 'AUTO-SIMPLIFY COMPOUND UNITS' , ( ) => {
976+ test ( 'N * m simplifies to J' , ( ) => {
977+ const expr = engine
978+ . box ( [ 'Multiply' , [ 'Quantity' , 5 , 'N' ] , [ 'Quantity' , 2 , 'm' ] ] )
979+ . evaluate ( ) ;
980+ expect ( expr . operator ) . toBe ( 'Quantity' ) ;
981+ expect ( expr . op1 . re ) . toBe ( 10 ) ;
982+ expect ( expr . op2 . symbol ) . toBe ( 'J' ) ;
983+ } ) ;
984+
985+ test ( 'J / m simplifies to N' , ( ) => {
986+ const expr = engine
987+ . box ( [ 'Divide' , [ 'Quantity' , 100 , 'J' ] , [ 'Quantity' , 10 , 'm' ] ] )
988+ . evaluate ( ) ;
989+ expect ( expr . operator ) . toBe ( 'Quantity' ) ;
990+ expect ( expr . op1 . re ) . toBe ( 10 ) ;
991+ expect ( expr . op2 . symbol ) . toBe ( 'N' ) ;
992+ } ) ;
993+
994+ test ( 'J / s simplifies to W' , ( ) => {
995+ const expr = engine
996+ . box ( [ 'Divide' , [ 'Quantity' , 60 , 'J' ] , [ 'Quantity' , 2 , 's' ] ] )
997+ . evaluate ( ) ;
998+ expect ( expr . operator ) . toBe ( 'Quantity' ) ;
999+ expect ( expr . op1 . re ) . toBe ( 30 ) ;
1000+ expect ( expr . op2 . symbol ) . toBe ( 'W' ) ;
1001+ } ) ;
1002+ } ) ;
1003+
1004+ describe ( 'QUANTITY COMPARISON' , ( ) => {
1005+ test ( 'Less: 500m < 1km' , ( ) => {
1006+ const expr = engine
1007+ . box ( [ 'Less' , [ 'Quantity' , 500 , 'm' ] , [ 'Quantity' , 1 , 'km' ] ] )
1008+ . evaluate ( ) ;
1009+ expect ( expr . symbol ) . toBe ( 'True' ) ;
1010+ } ) ;
1011+
1012+ test ( 'Less: 1km < 500m is False' , ( ) => {
1013+ const expr = engine
1014+ . box ( [ 'Less' , [ 'Quantity' , 1 , 'km' ] , [ 'Quantity' , 500 , 'm' ] ] )
1015+ . evaluate ( ) ;
1016+ expect ( expr . symbol ) . toBe ( 'False' ) ;
1017+ } ) ;
1018+
1019+ test ( 'Greater: 1km > 500m' , ( ) => {
1020+ const expr = engine
1021+ . box ( [ 'Greater' , [ 'Quantity' , 1 , 'km' ] , [ 'Quantity' , 500 , 'm' ] ] )
1022+ . evaluate ( ) ;
1023+ expect ( expr . symbol ) . toBe ( 'True' ) ;
1024+ } ) ;
1025+
1026+ test ( 'Equal: 100cm == 1m' , ( ) => {
1027+ const expr = engine
1028+ . box ( [ 'Equal' , [ 'Quantity' , 100 , 'cm' ] , [ 'Quantity' , 1 , 'm' ] ] )
1029+ . evaluate ( ) ;
1030+ expect ( expr . symbol ) . toBe ( 'True' ) ;
1031+ } ) ;
1032+
1033+ test ( 'Equal: 1km == 1000m' , ( ) => {
1034+ const expr = engine
1035+ . box ( [ 'Equal' , [ 'Quantity' , 1 , 'km' ] , [ 'Quantity' , 1000 , 'm' ] ] )
1036+ . evaluate ( ) ;
1037+ expect ( expr . symbol ) . toBe ( 'True' ) ;
1038+ } ) ;
1039+
1040+ test ( 'LessEqual: 1km <= 1000m' , ( ) => {
1041+ const expr = engine
1042+ . box ( [ 'LessEqual' , [ 'Quantity' , 1 , 'km' ] , [ 'Quantity' , 1000 , 'm' ] ] )
1043+ . evaluate ( ) ;
1044+ expect ( expr . symbol ) . toBe ( 'True' ) ;
1045+ } ) ;
1046+
1047+ test ( 'Incompatible units stay unevaluated' , ( ) => {
1048+ const expr = engine
1049+ . box ( [ 'Less' , [ 'Quantity' , 5 , 'm' ] , [ 'Quantity' , 3 , 's' ] ] )
1050+ . evaluate ( ) ;
1051+ expect ( expr . operator ) . toBe ( 'Less' ) ;
1052+ } ) ;
1053+ } ) ;
0 commit comments