Paweł Wieczorek avatar Paweł Wieczorek committed dd373c0 Draft

added unit tests for sip types converters (not finished)

Comments (0)

Files changed (4)

 open Batteries
 open Sip_utils
 
-(***************************************************************************************************)
-(* DATA TYPE *)
+(*********************************************************************************************************************
+ *)
 
 type sip_request_method
     = REGISTER
     | UPDATE
     | UnknownRequestMethod of string
 
+let sip_request_method_of_string = function
+    | "REGISTER" -> REGISTER
+    | "INVITE" -> INVITE
+    | "CANCEL" -> CANCEL
+    | "ACK" -> ACK
+    | "PRACK" -> PRACK
+    | "BYE" -> BYE
+    | "OPTIONS" -> OPTIONS
+    | "SUBSCRIBE" -> SUBSCRIBE
+    | "NOTIFY" -> NOTIFY
+    | "PUBLISH" -> PUBLISH
+    | "INFO" -> INFO
+    | "REFER" -> REFER
+    | "MESSAGE" -> MESSAGE
+    | "UPDATE" -> UPDATE
+    | s -> UnknownRequestMethod s
+
+let string_of_sip_request_method = function
+    | REGISTER -> "REGISTER"
+    | INVITE -> "INVITE"
+    | CANCEL -> "CANCEL"
+    | ACK -> "ACK"
+    | PRACK -> "PRACK"
+    | BYE -> "BYE"
+    | OPTIONS -> "OPTIONS"
+    | SUBSCRIBE -> "SUBSCRIBE"
+    | NOTIFY -> "NOTIFY"
+    | PUBLISH -> "PUBLISH"
+    | INFO -> "INFO"
+    | REFER -> "REFER"
+    | MESSAGE -> "MESSAGE"
+    | UPDATE -> "UPDATE"
+    | UnknownRequestMethod s -> s
+
+(*********************************************************************************************************************
+ *)
 
 type sip_response_code
     = RESP_100_TRYING
 
     | OtherResponse of int
 
+let int_of_response_code = function
+    | RESP_100_TRYING -> 100
+    | RESP_180_RINGING -> 180
+    | RESP_181_CALL_IS_BEING_FORWARDED -> 181
+    | RESP_182_QUEUED -> 182
+    | RESP_183_SESSION_IN_PROGRESS -> 183
 
-type sip_login =
-    SipLogin of string
+    | RESP_200_OK -> 200
+    | RESP_202_ACCEPTED -> 202
+    | RESP_204_NO_NOTIFICATION -> 204
 
-type sip_host = 
-    SipHost of string
+    | RESP_300_MULTIPLE_CHOICES -> 300
+    | RESP_301_MOVED_PERMANENTLY -> 301
+    | RESP_302_MOVED_TEMPORILY -> 302
+    | RESP_305_USE_PROXY -> 305
+    | RESP_380_ALTERNATIVE_SERVICE -> 380
+
+    | RESP_400_BAD_REQUEST -> 400
+    | RESP_401_UNAUTHORIZED -> 401
+    | RESP_402_PAYMENT_REQUIRED -> 402
+    | RESP_403_FORBIDDEN -> 403
+    | RESP_404_NOT_FOUND -> 404
+    | RESP_405_METHOD_NOT_ALLOWED -> 405
+
+    | RESP_500_SERVER_INTERNAL_ERROR -> 500
+    | RESP_501_NOT_IMPLEMENTED -> 501
+    | RESP_502_BAD_GATEWAY -> 502
+    | RESP_503_SERVICE_UNAVAILABLE -> 503
+
+    | RESP_600_BUSY_EVERYWHERE -> 600
+
+    | OtherResponse i -> i
+
+let sip_response_code_of_string = function
+    | i -> OtherResponse i
+
+(*********************************************************************************************************************
+ * TODO: Maybe Should I use some external library for parsing URI? Eh... crazy text format ;]
+ *)
+
+type uri_scheme
+    = URI_SCHEME_SIP
+    | URI_SCHEME_SIPS
+    | URI_SCHEME_TEL
+    | URI_SCHEME_Unknown of string
+
+let string_of_uri_scheme = function
+    | URI_SCHEME_SIP -> "sip"
+    | URI_SCHEME_SIPS -> "sips"
+    | URI_SCHEME_TEL -> "tel"
+    | URI_SCHEME_Unknown s -> s
+
+let uri_scheme_of_string = function
+    | "sip"  -> URI_SCHEME_SIP
+    | "sips" -> URI_SCHEME_SIPS
+    | scheme -> URI_SCHEME_Unknown scheme
+
+(*********************************************************************************************************************
+ *)
 
 type sip_uri =
     SipUri of string
 
+let string_of_sip_uri = function
+    | SipUri s -> s
+
+let sip_uri_of_string = function
+    | s -> SipUri s
+
+(*********************************************************************************************************************
+ *)
 type sip_address =
     SipAddress of string
 
+let sip_address_of_string = function
+    | s -> SipAddress s
+
+let string_of_sip_address = function
+    | SipAddress s -> s
+
+(*********************************************************************************************************************
+ *)
+
 type sip_call_id =
     SipCallId of string
 
+let sip_call_id_of_string = function
+    | s -> SipCallId s
+
+let string_of_sip_call_id = function
+    | SipCallId s -> s
+
+(*********************************************************************************************************************
+ *)
+
 type sip_cseq =
-    SipCseq of string
+    SipCseq of int32 * sip_request_method
+
+let string_of_sip_cseq = function
+    | SipCseq (seq, reqmethod) -> Int32.to_string seq ^ " " ^ string_of_sip_request_method reqmethod
+
+let sip_cseq_of_string s = 
+    try
+        let (word, index) = Sip_utils.find_word 0 s in
+        let rest          = String.slice ~first:index s in
+        SipCseq (Int32.of_string word, sip_request_method_of_string rest)
+    with _ ->
+        failwith "sip_cseq_of_string"
+
+(*********************************************************************************************************************
+ *)
 
 type sip_version =
     | SIP_1_0
     | SIP_2_0
     | UnknownSipVersion of string
 
+let sip_version_of_string = function
+    | "SIP/1.0" ->
+        SIP_1_0
+
+    | "SIP/2.0" ->
+        SIP_2_0
+
+    | sipver when String.starts_with sipver "SIP/" ->
+        UnknownSipVersion (String.slice ~first:4 sipver)
+
+    | _ -> raise (Failure "sip_version_of_string")
+
+let string_of_sip_version = function
+    | SIP_1_0 -> "SIP/1.0"
+    | SIP_2_0 -> "SIP/2.0"
+    | UnknownSipVersion s -> "SIP/"^ s
+
+(*********************************************************************************************************************
+ *)
 
 type sip_via =
     | SipVia of string
 
+let sip_via_of_string = function
+    | s -> SipVia s
+
+let string_of_sip_via = function
+    | SipVia s -> s
+
+(*********************************************************************************************************************
+ *)
+
 class type sip_message =
     object
 
 
     end
 
-(*********************************************************************************************************************
- * Coercions
- *)
-
-let sip_request_method_of_string = function
-    | "REGISTER" -> REGISTER
-    | "INVITE" -> INVITE
-    | "CANCEL" -> CANCEL
-    | "ACK" -> ACK
-    | "PRACK" -> PRACK
-    | "BYE" -> BYE
-    | "OPTIONS" -> OPTIONS
-    | "SUBSCRIBE" -> SUBSCRIBE
-    | "NOTIFY" -> NOTIFY
-    | "PUBLISH" -> PUBLISH
-    | "INFO" -> INFO
-    | "REFER" -> REFER
-    | "MESSAGE" -> MESSAGE
-    | "UPDATE" -> UPDATE
-    | s -> UnknownRequestMethod s
-
-let string_of_sip_request_method = function
-    | REGISTER -> "REGISTER"
-    | INVITE -> "INVITE"
-    | CANCEL -> "CANCEL"
-    | ACK -> "ACK"
-    | PRACK -> "PRACK"
-    | BYE -> "BYE"
-    | OPTIONS -> "OPTIONS"
-    | SUBSCRIBE -> "SUBSCRIBE"
-    | NOTIFY -> "NOTIFY"
-    | PUBLISH -> "PUBLISH"
-    | INFO -> "INFO"
-    | REFER -> "REFER"
-    | MESSAGE -> "MESSAGE"
-    | UPDATE -> "UPDATE"
-    | UnknownRequestMethod s -> s
-
-let int_of_response_code = function
-    | RESP_100_TRYING -> 100
-    | RESP_180_RINGING -> 180
-    | RESP_181_CALL_IS_BEING_FORWARDED -> 181
-    | RESP_182_QUEUED -> 182
-    | RESP_183_SESSION_IN_PROGRESS -> 183
-
-    | RESP_200_OK -> 200
-    | RESP_202_ACCEPTED -> 202
-    | RESP_204_NO_NOTIFICATION -> 204
-
-    | RESP_300_MULTIPLE_CHOICES -> 300
-    | RESP_301_MOVED_PERMANENTLY -> 301
-    | RESP_302_MOVED_TEMPORILY -> 302
-    | RESP_305_USE_PROXY -> 305
-    | RESP_380_ALTERNATIVE_SERVICE -> 380
-
-    | RESP_400_BAD_REQUEST -> 400
-    | RESP_401_UNAUTHORIZED -> 401
-    | RESP_402_PAYMENT_REQUIRED -> 402
-    | RESP_403_FORBIDDEN -> 403
-    | RESP_404_NOT_FOUND -> 404
-    | RESP_405_METHOD_NOT_ALLOWED -> 405
-
-    | RESP_500_SERVER_INTERNAL_ERROR -> 500
-    | RESP_501_NOT_IMPLEMENTED -> 501
-    | RESP_502_BAD_GATEWAY -> 502
-    | RESP_503_SERVICE_UNAVAILABLE -> 503
-
-    | RESP_600_BUSY_EVERYWHERE -> 600
-
-    | OtherResponse i -> i
-
-let sip_response_code_of_string = function
-    | i -> OtherResponse i
-
-
-let sip_version_of_string = function
-    | "SIP/1.0" ->
-        SIP_1_0
-
-    | "SIP/2.0" ->
-        SIP_2_0
-
-    | sipver when String.starts_with sipver "SIP/" ->
-        UnknownSipVersion (String.slice ~first:4 sipver)
-
-    | _ -> raise (Failure "sip_version_of_string")
-
-let string_of_sip_version = function
-    | SIP_1_0 -> "SIP/1.0"
-    | SIP_2_0 -> "SIP/2.0"
-    | UnknownSipVersion s -> "SIP/"^ s
-
-let string_of_sip_uri = function
-    | SipUri s -> s
-
-let sip_uri_of_string = function
-    | s -> SipUri s
-
-let string_of_sip_cseq = function
-    | SipCseq s -> s
-
-let sip_cseq_of_string = function
-    | s -> SipCseq s
-
-let sip_call_id_of_string = function
-    | s -> SipCallId s
-
-let string_of_sip_call_id = function
-    | SipCallId s -> s
-
-let sip_via_of_string = function
-    | s -> SipVia s
-
-let string_of_sip_via = function
-    | SipVia s -> s
-
-let sip_address_of_string = function
-    | s -> SipAddress s
-
-let string_of_sip_address = function
-    | SipAddress s -> s
-
 
 
 let test_suite = "SIP" >:::
-    [ Test_parser.test_suite
+    [ Test_sip_types.test_suite
+    ; Test_parser.test_suite
     ]
 ;;
 

tests/Test_parser.ml

  * Test suite
  *)
 
-let test_suite = "Parser" >:::
-      List.map valid_message_parse_test   Valid_messages.messages
-    @ List.map invalid_message_parse_test Invalid_messages.messages
+let test_suite = "Parser" >::: List.concat
+    [ List.map valid_message_parse_test   Valid_messages.messages
+    ; List.map invalid_message_parse_test Invalid_messages.messages
+    ]
 ;;
 

tests/Test_sip_types.ml

+(*********************************************************************************************************************
+ * Copyrights (C) 2012 by Pawel Wieczorek <wieczyk at gmail>
+ *  http://bitbucket.org/wieczyk/ocaml-sip
+ *)
+
+open Testdata_messages
+open Batteries
+open OUnit
+open Sip_types
+open Testdata_messages.Util
+
+(*********************************************************************************************************************
+ * Helpers
+ *)
+
+let assert_str_equal msg a b =
+    assert_equal ~msg:msg ~printer:String.quote a b
+
+
+let prepare_valid_case  title input output = (title, input, output)
+let prepare_valid_case' title output = (String.quote title, title, output)
+let prepare_invalid_case title failmsg input = (title, failmsg, input)
+let prepare_invalid_case' title failmsg = (String.quote title, failmsg, title)
+
+module type Test_for_type_converters = sig
+
+    type t
+
+    val converters : (string -> t) * (t -> string)
+
+    val valid_data : (string * string * t) list
+
+    val invalid_data : (string * string * string) list
+
+end
+
+(*********************************************************************************************************************
+ * SIP version
+ *)
+
+module Test_sip_version : Test_for_type_converters = struct
+
+    type t = sip_version
+
+    let converters =
+        (sip_version_of_string, string_of_sip_version)
+
+    let valid_data =
+        [ prepare_valid_case'
+            "SIP/1.0"
+            SIP_1_0
+
+        ; prepare_valid_case' 
+            "SIP/1.1"
+            (UnknownSipVersion "1.1")
+
+        ; prepare_valid_case' 
+            "SIP/2.0"
+            SIP_2_0
+
+        ; prepare_valid_case'
+            "SIP/2.1"
+            (UnknownSipVersion "2.1")
+
+        ; prepare_valid_case'
+            "SIP/3.0"
+            (UnknownSipVersion "3.0")
+        ]
+
+    let invalid_data =
+        let prepare title = prepare_invalid_case' title "sip_version_of_string" in
+        [ prepare "HTTP/1.0"
+        ; prepare "HTTP/1.1"
+        ; prepare "HTTP/2.0"
+        ; prepare "SIPS/2.0"
+        ; prepare "SIPS"
+        ; prepare "SIPS/"
+        ; prepare "SIP/"
+        ; prepare "ELO320"
+        ; prepare "fdsfds fsd fsdf sdf s"
+        ]
+
+end
+
+(*********************************************************************************************************************
+ *)
+
+module Test_sip_request_method : Test_for_type_converters = struct
+
+    type t = sip_request_method
+
+    let converters =
+        (sip_request_method_of_string, string_of_sip_request_method)
+
+    let valid_data =
+        [ prepare_valid_case'
+            "INVITE"
+            INVITE
+
+        ; prepare_valid_case'
+            "ACK"
+            ACK
+
+        ; prepare_valid_case'
+            "PRACK"
+            PRACK
+
+        ; prepare_valid_case'
+            "MESSAGE"
+            MESSAGE
+
+        ; prepare_valid_case'
+            "REGISTER"
+            REGISTER
+
+        ; prepare_valid_case'
+            "CANCEL"
+            CANCEL
+
+        ; prepare_valid_case'
+            "OPTIONS"
+            OPTIONS
+
+        ; prepare_valid_case'
+            "OPTION"
+            (UnknownRequestMethod "OPTION")
+        ]
+
+    let invalid_data =
+        let prepare title = prepare_invalid_case' title "sip_request_method_of_string" in
+        [ prepare "INVITE a"
+        ; prepare "a b c"
+        ; prepare " INVITE"
+        ; prepare " a b c"
+        ; prepare "INVITE "
+        ]
+
+end
+
+(*********************************************************************************************************************
+ *)
+
+(*********************************************************************************************************************
+ *)
+
+
+(*********************************************************************************************************************
+ * Test generators
+ *)
+
+let valid_conversion_test (input_conv, output_conv) (title, input, output) = 
+    "valid conversion -- " ^ title >::
+    begin fun () ->
+        let input_converted  = input_conv input in
+        let output_converted = output_conv output in
+        assert_equal
+            ~msg:"checking conversion from string"
+            output input_converted;
+        assert_equal
+            ~msg:"checking conversion to string"
+            ~printer:String.quote
+            input  output_converted
+    end
+
+let invalid_conversion_test (input_conv, _)  (title, failmsg, input) =
+    "invalid conversion -- " ^ title >::
+     begin fun () ->
+        let exn = Failure failmsg in
+        assert_raises 
+            exn (fun () -> input_conv input)
+     end
+
+let generate_valid_conversion_tests converters tests =
+    List.map (valid_conversion_test converters) tests
+
+let generate_invalid_conversion_tests converters tests =
+    List.map (invalid_conversion_test converters) tests
+
+let generate_tests_from_module m = 
+    let module M = (val m : Test_for_type_converters) in
+    List.concat
+        [ generate_valid_conversion_tests M.converters M.valid_data
+        ; generate_invalid_conversion_tests M.converters M.invalid_data
+        ]
+
+(*********************************************************************************************************************
+ * Test suite
+ *)
+
+let test_suite = "Types" >::: List.concat
+    [ generate_tests_from_module (module Test_sip_version        : Test_for_type_converters )
+    ; generate_tests_from_module (module Test_sip_request_method : Test_for_type_converters )
+    ]
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.