@@ -2,8 +2,9 @@ import { Transform, Writable } from "node:stream";
22import njfetch from "node-fetch" ;
33import { describe , expect , it } from "vitest" ;
44
5- import type { SDFRecord } from ".." ;
5+ import { filterRecord , type FilterRule } from "../src/filter " ;
66import { NodeSDFTransformer } from "../src/node-stream" ;
7+ import type { SDFRecord } from "../src/parser" ;
78import { createSDFTransformer as createWebSDFTransformer , parser } from ".." ;
89
910const webStreamParser = async ( stream : ReadableStream < string > ) => {
@@ -112,3 +113,154 @@ describe("NodeJS stream", async () => {
112113 expect ( streamedRecords ) . toEqual ( records ) ;
113114 } ) ;
114115} ) ;
116+
117+ describe ( "Filter with treatAs number" , ( ) => {
118+ const record : SDFRecord = {
119+ molFile : "" ,
120+ properties : {
121+ property1 : "" ,
122+ property2 : "abc" ,
123+ property3 : "123" ,
124+ property4 : "-123" ,
125+ } ,
126+ } ;
127+
128+ it ( "Filter drops empty string if treated as a number" , ( ) => {
129+ const filterRules : FilterRule [ ] = [
130+ {
131+ property : "property1" ,
132+ treatAs : "number" ,
133+ min : 0 ,
134+ max : Infinity ,
135+ } ,
136+ ] ;
137+ const filter = ( record : SDFRecord ) => filterRecord ( record , filterRules ) ;
138+
139+ expect ( filter ( record ) ) . toBe ( false ) ;
140+ } ) ;
141+
142+ it ( "Filter drops non-numbers if treated as a number" , ( ) => {
143+ const filterRules : FilterRule [ ] = [
144+ {
145+ property : "property2" ,
146+ treatAs : "number" ,
147+ min : 0 ,
148+ max : Infinity ,
149+ } ,
150+ ] ;
151+ const filter = ( record : SDFRecord ) => filterRecord ( record , filterRules ) ;
152+
153+ expect ( filter ( record ) ) . toBe ( false ) ;
154+ } ) ;
155+
156+ it ( "Filter keeps numbers when using infinite bounds" , ( ) => {
157+ const filterRules : FilterRule [ ] = [
158+ {
159+ property : "property3" ,
160+ treatAs : "number" ,
161+ min : - Infinity ,
162+ max : Infinity ,
163+ } ,
164+ ] ;
165+ const filter = ( record : SDFRecord ) => filterRecord ( record , filterRules ) ;
166+
167+ expect ( filter ( record ) ) . toBe ( true ) ;
168+ } ) ;
169+
170+ it ( "Filter keeps numbers when using semi-infinite bounds" , ( ) => {
171+ const filterRules : FilterRule [ ] = [
172+ {
173+ property : "property3" ,
174+ treatAs : "number" ,
175+ min : 0 ,
176+ max : Infinity ,
177+ } ,
178+ ] ;
179+ const filter = ( record : SDFRecord ) => filterRecord ( record , filterRules ) ;
180+
181+ expect ( filter ( record ) ) . toBe ( true ) ;
182+ } ) ;
183+
184+ it ( "Filter drops negative numbers when out of bounds" , ( ) => {
185+ const filterRules : FilterRule [ ] = [
186+ {
187+ property : "property4" ,
188+ treatAs : "number" ,
189+ min : 0 ,
190+ max : Infinity ,
191+ } ,
192+ ] ;
193+ const filter = ( record : SDFRecord ) => filterRecord ( record , filterRules ) ;
194+
195+ expect ( filter ( record ) ) . toBe ( false ) ;
196+ } ) ;
197+ } ) ;
198+
199+ const getAStream = async ( ) => {
200+ const response = await njfetch (
201+ "https://github.com/InformaticsMatters/sdf-parser/raw/master/tests/data/poses.sdf" ,
202+ ) ;
203+ const stream = response . body ;
204+
205+ if ( ! stream ) throw new Error ( "No stream" ) ;
206+
207+ return stream ;
208+ } ;
209+
210+ describe ( "NodeJS stream with filter" , async ( ) => {
211+ it ( "Filter drops all records" , async ( ) => {
212+ const stream = await getAStream ( ) ;
213+ const filterRules : FilterRule [ ] = [
214+ {
215+ property : "TransFSScore" ,
216+ treatAs : "number" ,
217+ min : - Infinity ,
218+ max : 0 ,
219+ } ,
220+ ] ;
221+ const filter = ( record : SDFRecord ) => filterRecord ( record , filterRules ) ;
222+
223+ const streamedRecords = await consumeStream (
224+ stream . pipe ( decoderTransform ( ) ) . pipe ( new NodeSDFTransformer ( filter ) ) ,
225+ ) ;
226+ expect ( streamedRecords ) . toHaveLength ( 0 ) ;
227+ } ) ;
228+
229+ it ( "Filter keeps all records" , async ( ) => {
230+ const stream = await getAStream ( ) ;
231+
232+ const filterRules : FilterRule [ ] = [
233+ {
234+ property : "FeatureStein" ,
235+ treatAs : "number" ,
236+ min : - Infinity ,
237+ max : Infinity ,
238+ } ,
239+ ] ;
240+ const filter = ( record : SDFRecord ) => filterRecord ( record , filterRules ) ;
241+
242+ const streamedRecords = await consumeStream (
243+ stream . pipe ( decoderTransform ( ) ) . pipe ( new NodeSDFTransformer ( filter ) ) ,
244+ ) ;
245+ expect ( streamedRecords ) . toHaveLength ( 268 ) ;
246+ } ) ;
247+
248+ it ( "Filter keeps the right number of records" , async ( ) => {
249+ const stream = await getAStream ( ) ;
250+
251+ const filterRules : FilterRule [ ] = [
252+ {
253+ property : "TransFSScore" ,
254+ treatAs : "number" ,
255+ min : 0.2 ,
256+ max : 0.3 ,
257+ } ,
258+ ] ;
259+ const filter = ( record : SDFRecord ) => filterRecord ( record , filterRules ) ;
260+
261+ const streamedRecords = await consumeStream (
262+ stream . pipe ( decoderTransform ( ) ) . pipe ( new NodeSDFTransformer ( filter ) ) ,
263+ ) ;
264+ expect ( streamedRecords ) . toHaveLength ( 53 ) ;
265+ } ) ;
266+ } ) ;
0 commit comments